diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f9b303465f19b5fbf5ec669cd083c9cc38ecda9a
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:flutter_lints/flutter.yaml
diff --git a/android/gradle.properties b/android/gradle.properties
index c2a871af8ab063d06f9d9304e63850ba93031951..357cef39a7f1619a4f0ba1c191a85a0dd10b7266 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=0.0.24
-app.versionCode=24
+app.versionName=0.0.25
+app.versionCode=25
diff --git a/fastlane/metadata/android/en-US/changelogs/25.txt b/fastlane/metadata/android/en-US/changelogs/25.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ab11150150fc75a46c9acc317890208e5a120b9
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/25.txt
@@ -0,0 +1 @@
+Add automatic flutter linter. Apply code lints. Update dependencies.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/25.txt b/fastlane/metadata/android/fr-FR/changelogs/25.txt
new file mode 100644
index 0000000000000000000000000000000000000000..609f5cf6e95a8df0799865df2e1ebde8fa981e5a
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/25.txt
@@ -0,0 +1 @@
+Ajout d'un correcteur automatique de code. Application des corrections. Mise à jour des dépendances.
diff --git a/lib/config/default_game_settings.dart b/lib/config/default_game_settings.dart
index d8d7c9513a6bdc3ccf32c4df188466176b5731c7..3c7798badd6ca51da472fc2148ae47dbbd56de87 100644
--- a/lib/config/default_game_settings.dart
+++ b/lib/config/default_game_settings.dart
@@ -38,7 +38,7 @@ class DefaultGameSettings {
         return DefaultGameSettings.allowedColorsCountValues;
     }
 
-    print('Did not find any available value for game parameter \"' + parameterCode + '\".');
+    print('Did not find any available value for game parameter "$parameterCode".');
     return [];
   }
 
diff --git a/lib/config/default_global_settings.dart b/lib/config/default_global_settings.dart
index 773491a601114e5d5c4a21873d4ae893d7a1c41e..e006915bb4e9df4edbd70c1847bcf40e3cff0d81 100644
--- a/lib/config/default_global_settings.dart
+++ b/lib/config/default_global_settings.dart
@@ -60,7 +60,7 @@ class DefaultGlobalSettings {
         return DefaultGlobalSettings.allowedGraphicThemeValues;
     }
 
-    print('Did not find any available value for global parameter \"' + parameterCode + '\".');
+    print('Did not find any available value for global parameter "$parameterCode".');
     return [];
   }
 }
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
index 2247d394a99054da1992eb0ea8933870a17c5ba3..c7d17e2e84baa2cf0c78999441386f514da8f842 100644
--- a/lib/cubit/game_cubit.dart
+++ b/lib/cubit/game_cubit.dart
@@ -50,31 +50,31 @@ class GameCubit extends HydratedCubit<GameState> {
   }
 
   void increaseMovesCount() {
-    this.state.currentGame.increaseMovesCount();
+    state.currentGame.increaseMovesCount();
     refresh();
   }
 
   void increaseScore(int increment) {
-    this.state.currentGame.increaseScore(increment);
+    state.currentGame.increaseScore(increment);
     refresh();
   }
 
   void updateAvailableBlocksCount() {
-    this.state.currentGame.updateAvailableBlocksCount();
+    state.currentGame.updateAvailableBlocksCount();
     refresh();
   }
 
   void updateGameIsFinished(bool gameIsFinished) {
-    this.state.currentGame.updateGameIsFinished(gameIsFinished);
+    state.currentGame.updateGameIsFinished(gameIsFinished);
     refresh();
   }
 
   void shuffleColors(final int colorsTheme) {
-    this.state.currentGame.shuffleColorsAgain(colorsTheme);
+    state.currentGame.shuffleColorsAgain(colorsTheme);
   }
 
   moveCellsDown() {
-    final Game currentGame = this.state.currentGame;
+    final Game currentGame = state.currentGame;
 
     final int boardSizeHorizontal = currentGame.gameSettings.boardSize;
     final int boardSizeVertical = currentGame.gameSettings.boardSize;
@@ -85,11 +85,11 @@ class GameCubit extends HydratedCubit<GameState> {
         if (currentGame.getCellValue(CellLocation.go(row, col)) == null) {
           // move cells down
           for (int r = row; r > 0; r--) {
-            this.updateCellValue(CellLocation.go(r, col),
+            updateCellValue(CellLocation.go(r, col),
                 currentGame.getCellValue(CellLocation.go(r - 1, col)));
           }
           // fill top empty cell
-          this.updateCellValue(
+          updateCellValue(
               CellLocation.go(0, col), currentGame.getFillValue(CellLocation.go(row, col)));
         }
       }
@@ -100,9 +100,9 @@ class GameCubit extends HydratedCubit<GameState> {
     // Sort cells from top to bottom
     block.sort((cell1, cell2) => cell1.row.compareTo(cell2.row));
     // Delete all cells
-    block.forEach((CellLocation blockItemToDelete) {
-      this.updateCellValue(blockItemToDelete, null);
-    });
+    for (CellLocation blockItemToDelete in block) {
+      updateCellValue(blockItemToDelete, null);
+    }
   }
 
   int getScoreFromBlock(int blockSize) {
@@ -110,16 +110,16 @@ class GameCubit extends HydratedCubit<GameState> {
   }
 
   List<CellLocation> tapOnCell(CellLocation tappedCellLocation) {
-    final Game currentGame = this.state.currentGame;
+    final Game currentGame = state.currentGame;
 
     final int? cellValue = currentGame.getCellValue(tappedCellLocation);
 
     if (cellValue != null) {
       List<CellLocation> blockCells = currentGame.getSiblingCells(tappedCellLocation, []);
       if (blockCells.length >= DefaultGameSettings.blockMinimumCellsCount) {
-        this.deleteBlock(blockCells);
-        this.increaseMovesCount();
-        this.increaseScore(getScoreFromBlock(blockCells.length));
+        deleteBlock(blockCells);
+        increaseMovesCount();
+        increaseScore(getScoreFromBlock(blockCells.length));
         return blockCells;
       }
     }
@@ -128,13 +128,13 @@ class GameCubit extends HydratedCubit<GameState> {
   }
 
   void postAnimate() {
-    this.moveCellsDown();
-    this.updateAvailableBlocksCount();
+    moveCellsDown();
+    updateAvailableBlocksCount();
     refresh();
 
-    if (!this.state.currentGame.hasAtLeastOneAvailableBlock()) {
+    if (!state.currentGame.hasAtLeastOneAvailableBlock()) {
       print('no more block found. finish game.');
-      this.updateGameIsFinished(true);
+      updateGameIsFinished(true);
     }
   }
 
@@ -150,7 +150,7 @@ class GameCubit extends HydratedCubit<GameState> {
     newGame.dump();
 
     updateState(newGame);
-    this.postAnimate();
+    postAnimate();
   }
 
   @override
diff --git a/lib/cubit/settings_game_cubit.dart b/lib/cubit/settings_game_cubit.dart
index d637cec6a3e16f049ccea497a1ed22653563491e..d37412e9269a3172961814018ea7752dc719ac18 100644
--- a/lib/cubit/settings_game_cubit.dart
+++ b/lib/cubit/settings_game_cubit.dart
@@ -35,7 +35,7 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
 
   void setParameterValue(String code, int value) {
     print('GameSettingsCubit.setParameterValue');
-    print('code: ' + code + '  / value: ' + value.toString());
+    print('code: $code  / value: $value');
 
     int boardSize = code == 'boardSize' ? value : getParameterValue('boardSize');
     int colorsCount = code == 'colorsCount' ? value : getParameterValue('colorsCount');
diff --git a/lib/cubit/settings_global_cubit.dart b/lib/cubit/settings_global_cubit.dart
index 94a99a3ca65d2d912eacdfe6eaaa1a3ff67c4586..279406f49863f1f443e953440c5958f8ed0f05a0 100644
--- a/lib/cubit/settings_global_cubit.dart
+++ b/lib/cubit/settings_global_cubit.dart
@@ -35,7 +35,7 @@ class GlobalSettingsCubit extends HydratedCubit<GlobalSettingsState> {
 
   void setParameterValue(String code, int value) {
     print('GlobalSettingsCubit.setParameterValue');
-    print('code: ' + code + '  / value: ' + value.toString());
+    print('code: $code  / value: $value');
 
     int colorsTheme = code == 'colorsTheme' ? value : getParameterValue('colorsTheme');
     int graphicTheme = code == 'graphicTheme' ? value : getParameterValue('graphicTheme');
diff --git a/lib/models/cell_location.dart b/lib/models/cell_location.dart
index be4c1063325d10d5bce45deb13ec60a1bedbc224..ae387e3fc0f0869484b5138f410845bb26752b20 100644
--- a/lib/models/cell_location.dart
+++ b/lib/models/cell_location.dart
@@ -8,10 +8,11 @@ class CellLocation {
   });
 
   factory CellLocation.go(int row, int col) {
-    return new CellLocation(col: col, row: row);
+    return CellLocation(col: col, row: row);
   }
 
+  @override
   String toString() {
-    return 'CellLocation(col: ' + col.toString() + ', row: ' + row.toString() + ')';
+    return 'CellLocation(col: $col, row: $row)';
   }
 }
diff --git a/lib/models/game.dart b/lib/models/game.dart
index 01ca0afacedae4090edee8db34e82510686eb20d..8f41596e60d6ca4b5575c415bb963fe28dde6dbc 100644
--- a/lib/models/game.dart
+++ b/lib/models/game.dart
@@ -58,61 +58,61 @@ class Game {
 
   static List<int> shuffleColors(final int colorsTheme) {
     List<int> values =
-        new List<int>.generate(ColorTheme.getColorsCount(colorsTheme), (i) => i + 1);
+        List<int>.generate(ColorTheme.getColorsCount(colorsTheme), (i) => i + 1);
     values.shuffle();
 
     return values;
   }
 
   void shuffleColorsAgain(final int colorsTheme) {
-    this.shuffledColors = shuffleColors(colorsTheme);
+    shuffledColors = shuffleColors(colorsTheme);
   }
 
   GameCell getCell(CellLocation cellLocation) {
-    return this.board.cells[cellLocation.row][cellLocation.col];
+    return board.cells[cellLocation.row][cellLocation.col];
   }
 
   int? getCellValue(CellLocation cellLocation) {
-    return this.getCell(cellLocation).value;
+    return getCell(cellLocation).value;
   }
 
   int? getCellValueShuffled(CellLocation cellLocation) {
-    final int? value = this.getCell(cellLocation).value;
-    return value != null ? this.shuffledColors[value - 1] : null;
+    final int? value = getCell(cellLocation).value;
+    return value != null ? shuffledColors[value - 1] : null;
   }
 
   void updateCellValue(CellLocation locationToUpdate, int? value) {
-    this.board.cells[locationToUpdate.row][locationToUpdate.col].value = value;
+    board.cells[locationToUpdate.row][locationToUpdate.col].value = value;
   }
 
   void increaseMovesCount() {
-    this.movesCount += 1;
+    movesCount += 1;
   }
 
   void increaseScore(int? count) {
-    this.score += (count ?? 0);
+    score += (count ?? 0);
   }
 
   void updateAvailableBlocksCount() {
-    this.availableBlocksCount = this.getAvailableBlocks(this).length;
+    availableBlocksCount = getAvailableBlocks(this).length;
   }
 
   void updateGameIsRunning(bool gameIsRunning) {
-    this.isRunning = gameIsRunning;
+    isRunning = gameIsRunning;
   }
 
   void updateGameIsFinished(bool gameIsFinished) {
-    this.isFinished = gameIsFinished;
+    isFinished = gameIsFinished;
   }
 
   List<CellLocation> getSiblingCells(
     final CellLocation referenceCellLocation,
     List<CellLocation> siblingCells,
   ) {
-    final int boardSizeHorizontal = this.gameSettings.boardSize;
-    final int boardSizeVertical = this.gameSettings.boardSize;
+    final int boardSizeHorizontal = gameSettings.boardSize;
+    final int boardSizeVertical = gameSettings.boardSize;
 
-    final int? referenceValue = this.getCellValue(referenceCellLocation);
+    final int? referenceValue = getCellValue(referenceCellLocation);
 
     for (int deltaRow = -1; deltaRow <= 1; deltaRow++) {
       for (int deltaCol = -1; deltaCol <= 1; deltaCol++) {
@@ -124,7 +124,7 @@ class Game {
               (candidateCol >= 0 && candidateCol < boardSizeHorizontal)) {
             final candidateLocation = CellLocation.go(candidateRow, candidateCol);
 
-            if (this.getCellValue(candidateLocation) == referenceValue) {
+            if (getCellValue(candidateLocation) == referenceValue) {
               bool alreadyFound = false;
               for (int index = 0; index < siblingCells.length; index++) {
                 if ((siblingCells[index].row == candidateRow) &&
@@ -158,13 +158,13 @@ class Game {
           // if current cell not already in a found block
           bool alreadyFound = false;
 
-          blocks.forEach((List<CellLocation> foundBlock) {
-            foundBlock.forEach((CellLocation foundBlockCell) {
+          for (List<CellLocation> foundBlock in blocks) {
+            for (CellLocation foundBlockCell in foundBlock) {
               if ((foundBlockCell.row == row) && (foundBlockCell.col == col)) {
                 alreadyFound = true;
               }
-            });
-          });
+            }
+          }
           if (!alreadyFound) {
             final List<CellLocation> block = game.getSiblingCells(cellLocation, []);
             if (block.length >= 3) {
@@ -179,14 +179,14 @@ class Game {
   }
 
   bool hasAtLeastOneAvailableBlock() {
-    final int boardSizeHorizontal = this.gameSettings.boardSize;
-    final int boardSizeVertical = this.gameSettings.boardSize;
+    final int boardSizeHorizontal = gameSettings.boardSize;
+    final int boardSizeVertical = gameSettings.boardSize;
 
     for (int row = 0; row < boardSizeVertical; row++) {
       for (int col = 0; col < boardSizeHorizontal; col++) {
         final CellLocation cellLocation = CellLocation.go(row, col);
-        if (this.getCellValue(cellLocation) != null) {
-          final List<CellLocation> block = this.getSiblingCells(cellLocation, []);
+        if (getCellValue(cellLocation) != null) {
+          final List<CellLocation> block = getSiblingCells(cellLocation, []);
           if (block.length >= 3) {
             // found one block => ok, not locked
             return true;
@@ -201,9 +201,9 @@ class Game {
 
   bool isInBoard(CellLocation cell) {
     if (cell.row > 0 &&
-        cell.row < this.gameSettings.boardSize &&
+        cell.row < gameSettings.boardSize &&
         cell.col > 0 &&
-        cell.col < this.gameSettings.boardSize) {
+        cell.col < gameSettings.boardSize) {
       return true;
     }
     return false;
@@ -217,16 +217,16 @@ class Game {
     final List<int> values = [];
 
     // All eligible values (twice)
-    final int maxValue = this.gameSettings.colorsCount;
+    final int maxValue = gameSettings.colorsCount;
     for (int i = 1; i <= maxValue; i++) {
       values.add(i);
       values.add(i);
     }
 
     // Add values of current col (twice)
-    for (int r = 0; r <= this.gameSettings.boardSize; r++) {
-      if (this.isInBoard(CellLocation.go(r, col))) {
-        final int? value = this.getCellValue(CellLocation.go(r, col));
+    for (int r = 0; r <= gameSettings.boardSize; r++) {
+      if (isInBoard(CellLocation.go(r, col))) {
+        final int? value = getCellValue(CellLocation.go(r, col));
         if (value != null) {
           values.add(value);
           values.add(value);
@@ -237,12 +237,12 @@ class Game {
     // Add values of sibling cols (twice for top rows)
     for (int deltaCol = -1; deltaCol <= 1; deltaCol++) {
       final int c = col + deltaCol;
-      for (int r = 0; r < this.gameSettings.boardSize; r++) {
-        if (this.isInBoard(CellLocation.go(r, c))) {
-          final int? value = this.getCellValue(CellLocation.go(r, c));
+      for (int r = 0; r < gameSettings.boardSize; r++) {
+        if (isInBoard(CellLocation.go(r, c))) {
+          final int? value = getCellValue(CellLocation.go(r, c));
           if (value != null) {
             values.add(value);
-            if (row < this.gameSettings.boardSize / 3) {
+            if (row < gameSettings.boardSize / 3) {
               values.add(value);
             }
           }
@@ -255,8 +255,8 @@ class Game {
       final int c = col + deltaCol;
       for (int deltaRow = -2; deltaRow <= 2; deltaRow++) {
         final int r = row + deltaRow;
-        if (this.isInBoard(CellLocation.go(r, c))) {
-          final int? value = this.getCellValue(CellLocation.go(r, c));
+        if (isInBoard(CellLocation.go(r, c))) {
+          final int? value = getCellValue(CellLocation.go(r, c));
           if (value != null) {
             values.add(value);
           }
@@ -272,36 +272,37 @@ class Game {
     print('');
     print('## Current game dump:');
     print('');
-    this.gameSettings.dump();
-    this.globalSettings.dump();
+    gameSettings.dump();
+    globalSettings.dump();
     print('');
-    this.board.dump();
+    board.dump();
     print('');
     print('Game: ');
-    print('  isRunning: ' + isRunning.toString());
-    print('  isFinished: ' + isFinished.toString());
-    print('  movesCount: ' + movesCount.toString());
-    print('  score: ' + score.toString());
-    print('  availableBlocksCount: ' + availableBlocksCount.toString());
-    print('  shuffledColors: ' + shuffledColors.toString());
+    print('  isRunning: $isRunning');
+    print('  isFinished: $isFinished');
+    print('  movesCount: $movesCount');
+    print('  score: $score');
+    print('  availableBlocksCount: $availableBlocksCount');
+    print('  shuffledColors: $shuffledColors');
     print('');
   }
 
+  @override
   String toString() {
-    return 'Game(' + this.toJson().toString() + ')';
+    return 'Game(${toJson()})';
   }
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
-      'board': this.board.toJson(),
-      'gameSettings': this.gameSettings.toJson(),
-      'globalSettings': this.globalSettings.toJson(),
-      'shuffledColors': this.shuffledColors,
-      'isRunning': this.isRunning,
-      'isFinished': this.isFinished,
-      'availableBlocksCount': this.availableBlocksCount,
-      'movesCount': this.movesCount,
-      'score': this.score,
+      'board': board.toJson(),
+      'gameSettings': gameSettings.toJson(),
+      'globalSettings': globalSettings.toJson(),
+      'shuffledColors': shuffledColors,
+      'isRunning': isRunning,
+      'isFinished': isFinished,
+      'availableBlocksCount': availableBlocksCount,
+      'movesCount': movesCount,
+      'score': score,
     };
   }
 }
diff --git a/lib/models/game_board.dart b/lib/models/game_board.dart
index a9bf7cb9e9cceb3dd737618c17ea9a84d738abc6..ee0ffff9d49adaf99dbdc886f6d1a9a962ad51d9 100644
--- a/lib/models/game_board.dart
+++ b/lib/models/game_board.dart
@@ -19,7 +19,7 @@ class GameBoard {
     final int boardSizeVertical = gameSettings.boardSize;
     final int maxValue = gameSettings.colorsCount;
 
-    final rand = new Random();
+    final rand = Random();
 
     List<List<GameCell>> cells = [];
     for (int rowIndex = 0; rowIndex < boardSizeVertical; rowIndex++) {
@@ -38,9 +38,9 @@ class GameBoard {
 
   void dump() {
     String horizontalRule = '----';
-    cells[0].forEach((element) {
+    for (int i = 0; i < cells[0].length; i++) {
       horizontalRule += '-';
-    });
+    }
 
     print('Board:');
     print(horizontalRule);
@@ -58,13 +58,14 @@ class GameBoard {
     print(horizontalRule);
   }
 
+  @override
   String toString() {
-    return 'Board(' + this.toJson().toString() + ')';
+    return 'Board(${toJson()})';
   }
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
-      'cells': this.cells.toString(),
+      'cells': cells.toString(),
     };
   }
 }
diff --git a/lib/models/game_cell.dart b/lib/models/game_cell.dart
index 25667ccf76bfbd4ef65f8651c120a7dbaab641b8..4cba17ba8adef606942ce8932dcbf429886edd5d 100644
--- a/lib/models/game_cell.dart
+++ b/lib/models/game_cell.dart
@@ -5,13 +5,14 @@ class GameCell {
     this.value,
   );
 
+  @override
   String toString() {
-    return 'Cell(' + this.toJson().toString() + ')';
+    return 'Cell(${toJson()})';
   }
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
-      'value': this.value,
+      'value': value,
     };
   }
 }
diff --git a/lib/models/settings_game.dart b/lib/models/settings_game.dart
index 6e2cb12098401e1187ff7d5afc89928d9cf8a4be..46182a518ce418dd0a52e18df6dfd127010c7f97 100644
--- a/lib/models/settings_game.dart
+++ b/lib/models/settings_game.dart
@@ -34,18 +34,19 @@ class GameSettings {
 
   void dump() {
     print('Settings: ');
-    print('  boardSize: ' + boardSize.toString());
-    print('  colorsCount: ' + colorsCount.toString());
+    print('  boardSize: $boardSize');
+    print('  colorsCount: $colorsCount');
   }
 
+  @override
   String toString() {
-    return 'GameSettings(' + this.toJson().toString() + ')';
+    return 'GameSettings(${toJson()})';
   }
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
-      'boardSize': this.boardSize,
-      'colorsCount': this.colorsCount,
+      'boardSize': boardSize,
+      'colorsCount': colorsCount,
     };
   }
 }
diff --git a/lib/models/settings_global.dart b/lib/models/settings_global.dart
index eac1cf32fe955e0b91309c388d715f28a80b4a9a..8dd498992571e1dcaf9a66bc86e950908f7992a3 100644
--- a/lib/models/settings_global.dart
+++ b/lib/models/settings_global.dart
@@ -34,18 +34,19 @@ class GlobalSettings {
 
   void dump() {
     print('Settings: ');
-    print('  colorsTheme: ' + colorsTheme.toString());
-    print('  graphicTheme: ' + graphicTheme.toString());
+    print('  colorsTheme: $colorsTheme');
+    print('  graphicTheme: $graphicTheme');
   }
 
+  @override
   String toString() {
-    return 'GlobalSettings(' + this.toJson().toString() + ')';
+    return 'GlobalSettings(${toJson()})';
   }
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
-      'colorsTheme': this.colorsTheme,
-      'graphicTheme': this.graphicTheme,
+      'colorsTheme': colorsTheme,
+      'graphicTheme': graphicTheme,
     };
   }
 }
diff --git a/lib/ui/painters/game_board_painter.dart b/lib/ui/painters/game_board_painter.dart
index 428dbe8d9b06ee14027a5e4abcfabb0271798e00..57dd7415ba17805cfeb45072c88fe1ef952f7f23 100644
--- a/lib/ui/painters/game_board_painter.dart
+++ b/lib/ui/painters/game_board_painter.dart
@@ -29,14 +29,14 @@ class GameBoardPainter extends CustomPainter {
 
     switch (graphicTheme) {
       case DefaultGlobalSettings.graphicThemeSolidBackground:
-        this.drawBoard(
+        drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           game: game,
         );
         break;
       case DefaultGlobalSettings.graphicThemeGradientAndBorder:
-        this.drawBoard(
+        drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           game: game,
@@ -46,7 +46,7 @@ class GameBoardPainter extends CustomPainter {
         );
         break;
       case DefaultGlobalSettings.graphicThemeEmojis:
-        this.drawBoard(
+        drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           game: game,
@@ -54,7 +54,7 @@ class GameBoardPainter extends CustomPainter {
         );
         break;
       case DefaultGlobalSettings.graphicThemePatterns:
-        this.drawBoard(
+        drawBoard(
           canvas: canvas,
           canvasSize: canvasSize,
           game: game,
@@ -71,7 +71,7 @@ class GameBoardPainter extends CustomPainter {
     boardPaintBorder.strokeWidth = boardBorderWidth;
     boardPaintBorder.strokeCap = StrokeCap.round;
 
-    final Offset boardTopLeft = Offset(0, 0);
+    const Offset boardTopLeft = Offset(0, 0);
     final Offset boardTopRight = Offset(canvasSize, 0);
     final Offset boardBottomLeft = Offset(0, canvasSize);
     final Offset boardBottomRight = Offset(canvasSize, canvasSize);
@@ -111,10 +111,10 @@ class GameBoardPainter extends CustomPainter {
         final CellLocation cellLocation = CellLocation.go(row, col);
         final int? cellValue = game.getCellValueShuffled(cellLocation);
         if (cellValue != null) {
-          final Animation<double>? translation = this.animations[row][col];
+          final Animation<double>? translation = animations[row][col];
           final double y = yOrigin + (translation?.value ?? 0) * size;
 
-          this.drawCell(
+          drawCell(
             canvas: canvas,
             x: x,
             y: y,
diff --git a/lib/ui/painters/parameter_painter.dart b/lib/ui/painters/parameter_painter.dart
index 775e306d55006714379f4459f5bfbdebe148706c..c7a6e13a0cf241beb3289859c2d2b2b5c50b68ce 100644
--- a/lib/ui/painters/parameter_painter.dart
+++ b/lib/ui/painters/parameter_painter.dart
@@ -36,10 +36,10 @@ class ParameterPainter extends CustomPainter {
     // "enabled/disabled" border
     final paint = Paint();
     paint.style = PaintingStyle.stroke;
-    paint.color = this.isSelected ? borderColorEnabled : borderColorDisabled;
+    paint.color = isSelected ? borderColorEnabled : borderColorDisabled;
     paint.strokeJoin = StrokeJoin.round;
     paint.strokeWidth = 20 / 100 * canvasSize;
-    canvas.drawRect(Rect.fromPoints(Offset(0, 0), Offset(canvasSize, canvasSize)), paint);
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(canvasSize, canvasSize)), paint);
 
     // content
     switch (code) {
@@ -56,7 +56,7 @@ class ParameterPainter extends CustomPainter {
         paintGraphicThemeParameterItem(value, canvas, canvasSize);
         break;
       default:
-        print('Unknown parameter: ' + code + '/' + value.toString());
+        print('Unknown parameter: $code/$value');
         paintUnknownParameterItem(value, canvas, canvasSize);
     }
   }
@@ -78,10 +78,10 @@ class ParameterPainter extends CustomPainter {
 
     paint.color = Colors.grey;
     paint.style = PaintingStyle.fill;
-    canvas.drawRect(Rect.fromPoints(Offset(0, 0), Offset(size, size)), paint);
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
 
     final textSpan = TextSpan(
-      text: '?' + '\n' + value.toString(),
+      text: '?\n$value',
       style: const TextStyle(
         color: Colors.black,
         fontSize: 18,
@@ -128,7 +128,7 @@ class ParameterPainter extends CustomPainter {
         gridWidth = 5;
         break;
       default:
-        print('Wrong value for boardSize parameter value: ' + value.toString());
+        print('Wrong value for boardSize parameter value: $value');
     }
 
     final paint = Paint();
@@ -138,7 +138,7 @@ class ParameterPainter extends CustomPainter {
     // Colored background
     paint.color = backgroundColor;
     paint.style = PaintingStyle.fill;
-    canvas.drawRect(Rect.fromPoints(Offset(0, 0), Offset(size, size)), paint);
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
 
     // Mini grid
     final borderColor = Colors.grey.shade800;
@@ -186,7 +186,7 @@ class ParameterPainter extends CustomPainter {
         backgroundColor = Colors.purple;
         break;
       default:
-        print('Wrong value for colorsCount parameter value: ' + value.toString());
+        print('Wrong value for colorsCount parameter value: $value');
     }
 
     final paint = Paint();
@@ -196,7 +196,7 @@ class ParameterPainter extends CustomPainter {
     // Colored background
     paint.color = backgroundColor;
     paint.style = PaintingStyle.fill;
-    canvas.drawRect(Rect.fromPoints(Offset(0, 0), Offset(size, size)), paint);
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
 
     // Colors preview
     const List<Offset> positions = [
@@ -272,7 +272,7 @@ class ParameterPainter extends CustomPainter {
     // Colored background
     paint.color = backgroundColor;
     paint.style = PaintingStyle.fill;
-    canvas.drawRect(Rect.fromPoints(Offset(0, 0), Offset(size, size)), paint);
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
 
     // Mini grid
     final borderColor = Colors.grey.shade800;
@@ -312,7 +312,7 @@ class ParameterPainter extends CustomPainter {
     // Colored background
     paint.color = backgroundColor;
     paint.style = PaintingStyle.fill;
-    canvas.drawRect(Rect.fromPoints(Offset(0, 0), Offset(size, size)), paint);
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
 
     // cells preview
     const List<Offset> positions = [
@@ -347,7 +347,7 @@ class ParameterPainter extends CustomPainter {
         contentStrings = DefaultGlobalSettings.graphicThemeContentPatternStrings;
         break;
       default:
-        print('Wrong value for colorsCount parameter value: ' + value.toString());
+        print('Wrong value for colorsCount parameter value: $value');
     }
 
     for (int itemValue = 0; itemValue < positions.length; itemValue++) {
@@ -385,7 +385,7 @@ class ParameterPainter extends CustomPainter {
       }
 
       // centered text value
-      if (contentStrings.length != 0) {
+      if (contentStrings.isNotEmpty) {
         final textSpan = TextSpan(
           text: contentStrings[itemValue],
           style: TextStyle(
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index 6b24bb4c334f0dbb526ffb75ee19dfc788d81420..8ce8ca5bdf83f8a9a898dd5b1470ea09ca8daf5f 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -9,9 +9,9 @@ class SkeletonScreen extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Scaffold(
-      appBar: GlobalAppBar(),
+      appBar: const GlobalAppBar(),
       extendBodyBehindAppBar: false,
-      body: ScreenGame(),
+      body: const ScreenGame(),
       backgroundColor: Theme.of(context).colorScheme.background,
     );
   }
diff --git a/lib/ui/widgets/game_board.dart b/lib/ui/widgets/game_board.dart
index 402b200d14d77d99666d86efab046f9c97c461e9..beba562c5da23c3dfae9000b1101265b185f5058 100644
--- a/lib/ui/widgets/game_board.dart
+++ b/lib/ui/widgets/game_board.dart
@@ -19,7 +19,7 @@ class _GameBoard extends State<GameBoard> with TickerProviderStateMixin {
   List<List<Animation<double>?>> animations = [];
 
   void resetAnimations(int boardSize) {
-    this.animations = List.generate(
+    animations = List.generate(
       boardSize,
       (i) => List.generate(
         boardSize,
@@ -72,21 +72,21 @@ class _GameBoard extends State<GameBoard> with TickerProviderStateMixin {
         (i) => 0,
       ),
     );
-    cellsToRemove.forEach((cellToRemove) {
+    for (CellLocation cellToRemove in cellsToRemove) {
       for (int i = 0; i < cellToRemove.row; i++) {
         stepsDownCounts[(cellToRemove.row - i) - 1][cellToRemove.col] += 1;
       }
-    });
+    }
 
     // Build animation for each cell to move
     bool needAnimation = false;
-    cellsToRemove.forEach((cellToRemove) {
+    for (CellLocation cellToRemove in cellsToRemove) {
       for (int i = 0; i < cellToRemove.row; i++) {
         final int stepsCount = stepsDownCounts[(cellToRemove.row - i) - 1][cellToRemove.col];
-        this.animations[(cellToRemove.row - i) - 1][cellToRemove.col] = animation(stepsCount);
+        animations[(cellToRemove.row - i) - 1][cellToRemove.col] = animation(stepsCount);
         needAnimation = true;
       }
-    });
+    }
 
     controller.forward().orCancel;
 
@@ -104,20 +104,20 @@ class _GameBoard extends State<GameBoard> with TickerProviderStateMixin {
         builder: (BuildContext context, GameState gameState) {
           final Game currentGame = gameState.currentGame;
 
-          if (this.animations.length == 0) {
+          if (animations.isEmpty) {
             resetAnimations(currentGame.gameSettings.boardSize);
           }
 
           return GestureDetector(
             onTapUp: (details) {
               bool animationInProgress = false;
-              animations.forEach((row) {
-                row.forEach((cell) {
+              for (List<Animation<double>?> row in animations) {
+                for (Animation<double>? cell in row) {
                   if (cell != null) {
                     animationInProgress = true;
                   }
-                });
-              });
+                }
+              }
 
               if (!animationInProgress) {
                 final double xTap = details.localPosition.dx;
@@ -134,7 +134,7 @@ class _GameBoard extends State<GameBoard> with TickerProviderStateMixin {
               willChange: false,
               painter: GameBoardPainter(
                 game: currentGame,
-                animations: this.animations,
+                animations: animations,
               ),
               isComplex: true,
             ),
diff --git a/lib/ui/widgets/game_bottom_buttons.dart b/lib/ui/widgets/game_bottom_buttons.dart
index 684279ec3a2f7cd3e33002ab86397109049021d6..4faea09427554cfd20d477eb2569e6805bfca580 100644
--- a/lib/ui/widgets/game_bottom_buttons.dart
+++ b/lib/ui/widgets/game_bottom_buttons.dart
@@ -15,39 +15,37 @@ class GameBottomButtonsWidget extends StatelessWidget {
         image: AssetImage(decorationImageAssetName),
         fit: BoxFit.fill,
       ),
-      onPressed: () => null,
+      onPressed: () {},
     );
 
-    return Container(
-      child: Table(
-        defaultColumnWidth: IntrinsicColumnWidth(),
-        children: [
-          TableRow(
-            children: [
-              Column(
-                children: [decorationWidget],
-              ),
-              Column(
-                children: [
-                  TextButton(
-                    child: Image(
-                      image: AssetImage('assets/icons/button_back.png'),
-                      fit: BoxFit.fill,
-                    ),
-                    onPressed: () {
-                      final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-                      gameCubit.quitGame();
-                    },
-                  )
-                ],
-              ),
-              Column(
-                children: [decorationWidget],
-              ),
-            ],
-          ),
-        ],
-      ),
+    return Table(
+      defaultColumnWidth: const IntrinsicColumnWidth(),
+      children: [
+        TableRow(
+          children: [
+            Column(
+              children: [decorationWidget],
+            ),
+            Column(
+              children: [
+                TextButton(
+                  child: const Image(
+                    image: AssetImage('assets/icons/button_back.png'),
+                    fit: BoxFit.fill,
+                  ),
+                  onPressed: () {
+                    final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+                    gameCubit.quitGame();
+                  },
+                )
+              ],
+            ),
+            Column(
+              children: [decorationWidget],
+            ),
+          ],
+        ),
+      ],
     );
   }
 }
diff --git a/lib/ui/widgets/game_top_indicator.dart b/lib/ui/widgets/game_top_indicator.dart
index 25d93d4aa2238b1ba355c320a270f22fa9719816..bdbbc85fe1ab585d38d6c12988497b50d07c75df 100644
--- a/lib/ui/widgets/game_top_indicator.dart
+++ b/lib/ui/widgets/game_top_indicator.dart
@@ -57,7 +57,7 @@ class GameTopIndicatorWidget extends StatelessWidget {
                       ),
                     ),
                     TextButton(
-                      child: Icon(UniconsSolid.refresh),
+                      child: const Icon(UniconsSolid.refresh),
                       onPressed: () {
                         final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
                         gameCubit.shuffleColors(currentGame.globalSettings.colorsTheme);
diff --git a/lib/ui/widgets/global_app_bar.dart b/lib/ui/widgets/global_app_bar.dart
index afcf1c9304ebc53b9758b5f91698f93fbdc8a517..58905ec2df00fce1dc7259b8ca14a07adaf3aa39 100644
--- a/lib/ui/widgets/global_app_bar.dart
+++ b/lib/ui/widgets/global_app_bar.dart
@@ -18,13 +18,11 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
 
         if (currentGame.isRunning) {
           menuActions.add(TextButton(
-            child: Container(
-              child: Image(
-                image: AssetImage('assets/icons/button_back.png'),
-                fit: BoxFit.fill,
-              ),
+            child: const Image(
+              image: AssetImage('assets/icons/button_back.png'),
+              fit: BoxFit.fill,
             ),
-            onPressed: () => null,
+            onPressed: () {},
             onLongPress: () {
               final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
               gameCubit.quitGame();
diff --git a/lib/ui/widgets/parameters.dart b/lib/ui/widgets/parameters.dart
index e334834dc678edaaa38048ea5892b90390cc5ff1..21cc610eaa8c84ba51ea0c8a5ebc23a9e3125aa1 100644
--- a/lib/ui/widgets/parameters.dart
+++ b/lib/ui/widgets/parameters.dart
@@ -23,7 +23,7 @@ class Parameters extends StatelessWidget {
         ? DefaultGlobalSettings.getAvailableValues(code)
         : DefaultGameSettings.getAvailableValues(code);
 
-    availableValues.forEach((value) {
+    for (int value in availableValues) {
       final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
         builder: (BuildContext context, GameSettingsState gameSettingsState) {
           return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
@@ -44,8 +44,8 @@ class Parameters extends StatelessWidget {
 
               return TextButton(
                 child: Container(
-                  margin: EdgeInsets.all(0),
-                  padding: EdgeInsets.all(0),
+                  margin: const EdgeInsets.all(0),
+                  padding: const EdgeInsets.all(0),
                   child: CustomPaint(
                     size: Size(itemWidth, itemWidth),
                     willChange: false,
@@ -69,7 +69,7 @@ class Parameters extends StatelessWidget {
       );
 
       parameterButtons.add(parameterButton);
-    });
+    }
 
     return parameterButtons;
   }
@@ -79,7 +79,7 @@ class Parameters extends StatelessWidget {
     final List<Widget> lines = [];
 
     // Game settings
-    DefaultGameSettings.availableParameters.forEach((code) {
+    for (String code in DefaultGameSettings.availableParameters) {
       lines.add(Row(
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         children: buildParametersLine(
@@ -89,14 +89,14 @@ class Parameters extends StatelessWidget {
       ));
 
       lines.add(SizedBox(height: separatorHeight));
-    });
+    }
 
     lines.add(SizedBox(height: separatorHeight));
     lines.add(buildStartNewGameButton());
     lines.add(SizedBox(height: separatorHeight));
 
     // Global settings
-    DefaultGlobalSettings.availableParameters.forEach((code) {
+    for (String code in DefaultGlobalSettings.availableParameters) {
       lines.add(Row(
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         children: buildParametersLine(
@@ -106,7 +106,7 @@ class Parameters extends StatelessWidget {
       ));
 
       lines.add(SizedBox(height: separatorHeight));
-    });
+    }
 
     return Column(
       children: lines,
@@ -115,7 +115,7 @@ class Parameters extends StatelessWidget {
 
   static Image buildImageWidget(String imageAssetCode) {
     return Image(
-      image: AssetImage('assets/icons/' + imageAssetCode + '.png'),
+      image: AssetImage('assets/icons/$imageAssetCode.png'),
       fit: BoxFit.fill,
     );
   }
@@ -131,7 +131,7 @@ class Parameters extends StatelessWidget {
       children: [
         TextButton(
           child: buildImageContainerWidget('placeholder'),
-          onPressed: () => null,
+          onPressed: () {},
         ),
       ],
     );
@@ -148,10 +148,10 @@ class Parameters extends StatelessWidget {
             final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
 
             return Container(
-              margin: EdgeInsets.all(blockMargin),
-              padding: EdgeInsets.all(blockPadding),
+              margin: const EdgeInsets.all(blockMargin),
+              padding: const EdgeInsets.all(blockPadding),
               child: Table(
-                defaultColumnWidth: IntrinsicColumnWidth(),
+                defaultColumnWidth: const IntrinsicColumnWidth(),
                 children: [
                   TableRow(
                     children: [
diff --git a/pubspec.lock b/pubspec.lock
index f0a711fa116acf1950fd1e05861e1a227e16cc00..dd410ae2821bec1a358fd157ff0ba312feeb40ff 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -13,10 +13,10 @@ packages:
     dependency: transitive
     description:
       name: bloc
-      sha256: "3820f15f502372d979121de1f6b97bfcf1630ebff8fe1d52fb2b0bfa49be5b49"
+      sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e
       url: "https://pub.dev"
     source: hosted
-    version: "8.1.2"
+    version: "8.1.3"
   characters:
     dependency: transitive
     description:
@@ -53,10 +53,10 @@ packages:
     dependency: "direct main"
     description:
       name: easy_localization
-      sha256: de63e3b422adfc97f256cbb3f8cf12739b6a4993d390f3cadb3f51837afaefe5
+      sha256: "9c86754b22aaa3e74e471635b25b33729f958dd6fb83df0ad6612948a7b231af"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.3"
+    version: "3.0.4"
   easy_logger:
     dependency: transitive
     description:
@@ -77,10 +77,10 @@ packages:
     dependency: transitive
     description:
       name: ffi
-      sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
+      sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.0"
+    version: "2.1.2"
   file:
     dependency: transitive
     description:
@@ -98,10 +98,18 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_bloc
-      sha256: e74efb89ee6945bcbce74a5b3a5a3376b088e5f21f55c263fc38cbdc6237faae
+      sha256: "87325da1ac757fcc4813e6b34ed5dd61169973871fdf181d6c2109dd6935ece1"
       url: "https://pub.dev"
     source: hosted
-    version: "8.1.3"
+    version: "8.1.4"
+  flutter_lints:
+    dependency: "direct dev"
+    description:
+      name: flutter_lints
+      sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.1"
   flutter_localizations:
     dependency: transitive
     description: flutter
@@ -113,7 +121,7 @@ packages:
     source: sdk
     version: "0.0.0"
   hive:
-    dependency: transitive
+    dependency: "direct main"
     description:
       name: hive
       sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
@@ -124,10 +132,10 @@ packages:
     dependency: "direct main"
     description:
       name: hydrated_bloc
-      sha256: c925e49704c052a8f249226ae7603f86bfa776b910816390763b956c71d2cbaf
+      sha256: "00a2099680162e74b5a836b8a7f446e478520a9cae9f6032e028ad8129f4432d"
       url: "https://pub.dev"
     source: hosted
-    version: "9.1.3"
+    version: "9.1.4"
   intl:
     dependency: transitive
     description:
@@ -136,22 +144,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.18.1"
+  lints:
+    dependency: transitive
+    description:
+      name: lints
+      sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.0"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
       url: "https://pub.dev"
     source: hosted
-    version: "0.5.0"
+    version: "0.8.0"
   meta:
     dependency: transitive
     description:
       name: meta
-      sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
+      sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
       url: "https://pub.dev"
     source: hosted
-    version: "1.10.0"
+    version: "1.11.0"
   nested:
     dependency: transitive
     description:
@@ -164,10 +180,10 @@ packages:
     dependency: transitive
     description:
       name: path
-      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+      sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.3"
+    version: "1.9.0"
   path_provider:
     dependency: "direct main"
     description:
@@ -337,10 +353,10 @@ packages:
     dependency: transitive
     description:
       name: web
-      sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
+      sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
       url: "https://pub.dev"
     source: hosted
-    version: "0.3.0"
+    version: "0.4.2"
   win32:
     dependency: transitive
     description:
@@ -358,5 +374,5 @@ packages:
     source: hosted
     version: "1.0.4"
 sdks:
-  dart: ">=3.2.0 <4.0.0"
+  dart: ">=3.3.0-279.1.beta <4.0.0"
   flutter: ">=3.16.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 9ab963d2a85b14c0fce29f89b600507d993c9b01..2cb220eeb8d3d6e8f58f2ab0e3d9394cefb8db79 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Jeweled Game
 
 publish_to: 'none'
 
-version: 0.0.24+24
+version: 0.0.25+25
 
 environment:
   sdk: '^3.0.0'
@@ -14,10 +14,14 @@ dependencies:
   easy_localization: ^3.0.1
   equatable: ^2.0.5
   flutter_bloc: ^8.1.1
+  hive: ^2.2.3
   hydrated_bloc: ^9.0.0
   path_provider: ^2.0.11
   unicons: ^2.1.1
 
+dev_dependencies:
+  flutter_lints: ^3.0.1
+
 flutter:
   uses-material-design: false
   assets: