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/app/build.gradle b/android/app/build.gradle
index ad6a6f31e64926d71ad8741a524f4a9a7946a3d1..fe8bedd11648e2bac231b68b065ca0a7d764eecd 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -44,7 +44,7 @@ android {
 
     defaultConfig {
         applicationId "org.benoitharrault.tetrisdual"
-        minSdkVersion 16
+        minSdkVersion flutter.minSdkVersion
         targetSdkVersion 30
         versionCode appVersionCode.toInteger()
         versionName appVersionName
diff --git a/android/gradle.properties b/android/gradle.properties
index 65eed6426393974efb5a056ec44936d42b5ef2a1..4bb5439f682100f8ef4ba80a557fe4f2f0ab14c2 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.8
-app.versionCode=8
+app.versionName=0.0.9
+app.versionCode=9
diff --git a/fastlane/metadata/android/en-US/changelogs/9.txt b/fastlane/metadata/android/en-US/changelogs/9.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ab11150150fc75a46c9acc317890208e5a120b9
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/9.txt
@@ -0,0 +1 @@
+Add automatic flutter linter. Apply code lints. Update dependencies.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/9.txt b/fastlane/metadata/android/fr-FR/changelogs/9.txt
new file mode 100644
index 0000000000000000000000000000000000000000..315dd65b6fea52abf09c73bd8b62e0a6e41082b7
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/9.txt
@@ -0,0 +1 @@
+Ajout d'un correcteur automatique de code. Application des correction. Mise à jour des dépendances.
diff --git a/lib/entity/counter.dart b/lib/entity/counter.dart
index f9ae8597d1f871e82b78346071505fc703891a38..31fedae0d2c1f1bf3858fc36569b109c3caacbc0 100644
--- a/lib/entity/counter.dart
+++ b/lib/entity/counter.dart
@@ -1,6 +1,7 @@
 import 'dart:math';
 
 import 'package:flutter/material.dart';
+
 import 'package:tetrisdual/provider/data.dart';
 
 class Counter {
@@ -10,56 +11,79 @@ class Counter {
   int _holes = 0; // Count non fillable holes caused by this new tetrimino
 
   // Points definitions
-  int _base = 50;
-  int _pointsIfMatch = 50;
-  int _pointsPerLine = 60;
-  int _pointsPerHole = -10;
+  static const int _base = 50;
+  static const int _pointsIfMatch = 50;
+  static const int _pointsPerLine = 60;
+  static const int _pointsPerHole = -10;
 
-  Color categoryIconColor = Colors.green;
-  Color buttonIconColor = Colors.blue;
-  double iconSize = 30.0;
+  static const double iconSize = 30.0;
+  static const double fontSize = 50.0;
+  static const double spacerHeight = 7;
 
-  TableRow spacer() {
-    double height = 7;
-    return TableRow(children: [
-      SizedBox(height: height),
-      SizedBox(height: height),
-      SizedBox(height: height),
-      SizedBox(height: height)
-    ]);
-  }
+  // Counter categories icons
+  static const Color categoryIconColor = Colors.green;
+  static const Icon iconTouchingColor = Icon(
+    Icons.join_full,
+    color: categoryIconColor,
+    size: iconSize,
+  );
+  static const Icon iconRowsCount = Icon(
+    Icons.table_rows,
+    color: categoryIconColor,
+    size: iconSize,
+  );
+  static const Icon iconHolesCount = Icon(
+    Icons.check_box_outline_blank,
+    color: categoryIconColor,
+    size: iconSize,
+  );
+
+  // Action buttons icons
+  static const Color buttonIconColor = Colors.blue;
+  static const Icon iconRemove = Icon(
+    Icons.remove,
+    color: buttonIconColor,
+    size: iconSize,
+  );
+  static const Icon iconAdd = Icon(
+    Icons.add,
+    color: buttonIconColor,
+    size: iconSize,
+  );
 
   Widget buildCounterWidget(Data myProvider) {
-    return Container(
-      child: Table(
-        children: [
-          buildMatchWidget(myProvider),
-          spacer(),
-          buildLinesWidget(myProvider),
-          spacer(),
-          buildHolesWidget(myProvider),
-          spacer(),
-        ],
-      ),
+    return Table(
+      children: [
+        buildMatchWidget(myProvider),
+        buildSpacerRow(),
+        buildLinesWidget(myProvider),
+        buildSpacerRow(),
+        buildHolesWidget(myProvider),
+        buildSpacerRow(),
+      ],
     );
   }
 
+  TableRow buildSpacerRow() {
+    return const TableRow(children: [
+      SizedBox(height: spacerHeight),
+      SizedBox(height: spacerHeight),
+      SizedBox(height: spacerHeight),
+      SizedBox(height: spacerHeight)
+    ]);
+  }
+
   TableRow buildMatchWidget(Data myProvider) {
     return TableRow(
       children: [
-        Icon(
-          Icons.join_full,
-          color: categoryIconColor,
-          size: iconSize,
-        ),
+        iconTouchingColor,
         IconButton(
           padding: EdgeInsets.zero,
-          constraints: BoxConstraints(),
-          icon: Icon(
-            Icons.remove,
-            color: buttonIconColor,
-            size: iconSize,
+          constraints: const BoxConstraints(),
+          style: const ButtonStyle(
+            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
           ),
+          icon: iconRemove,
           onPressed: () {
             _match = false;
             myProvider.redraw();
@@ -74,12 +98,11 @@ class Counter {
         ),
         IconButton(
           padding: EdgeInsets.zero,
-          constraints: BoxConstraints(),
-          icon: Icon(
-            Icons.add,
-            color: buttonIconColor,
-            size: iconSize,
+          constraints: const BoxConstraints(),
+          style: const ButtonStyle(
+            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
           ),
+          icon: iconAdd,
           onPressed: () {
             _match = true;
             myProvider.redraw();
@@ -92,19 +115,14 @@ class Counter {
   TableRow buildLinesWidget(Data myProvider) {
     return TableRow(
       children: [
-        Icon(
-          Icons.table_rows,
-          color: categoryIconColor,
-          size: iconSize,
-        ),
+        iconRowsCount,
         IconButton(
           padding: EdgeInsets.zero,
-          constraints: BoxConstraints(),
-          icon: Icon(
-            Icons.remove,
-            color: buttonIconColor,
-            size: iconSize,
+          constraints: const BoxConstraints(),
+          style: const ButtonStyle(
+            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
           ),
+          icon: iconRemove,
           onPressed: () {
             _lines = max(_lines - 1, 0);
             myProvider.redraw();
@@ -113,20 +131,23 @@ class Counter {
         Center(
           child: Text(
             _lines.toString(),
-            style: TextStyle(
+            style: const TextStyle(
               fontFamily: 'Blocks',
-              fontSize: 50,
+              fontSize: fontSize,
+            ),
+            textHeightBehavior: const TextHeightBehavior(
+              applyHeightToFirstAscent: false,
+              applyHeightToLastDescent: false,
             ),
           ),
         ),
         IconButton(
           padding: EdgeInsets.zero,
-          constraints: BoxConstraints(),
-          icon: Icon(
-            Icons.add,
-            color: buttonIconColor,
-            size: iconSize,
+          constraints: const BoxConstraints(),
+          style: const ButtonStyle(
+            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
           ),
+          icon: iconAdd,
           onPressed: () {
             _lines = min(_lines + 1, 4);
             myProvider.redraw();
@@ -139,19 +160,14 @@ class Counter {
   TableRow buildHolesWidget(Data myProvider) {
     return TableRow(
       children: [
-        Icon(
-          Icons.check_box_outline_blank,
-          color: categoryIconColor,
-          size: iconSize,
-        ),
+        iconHolesCount,
         IconButton(
           padding: EdgeInsets.zero,
-          constraints: BoxConstraints(),
-          icon: Icon(
-            Icons.remove,
-            color: buttonIconColor,
-            size: iconSize,
+          constraints: const BoxConstraints(),
+          style: const ButtonStyle(
+            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
           ),
+          icon: iconRemove,
           onPressed: () {
             _holes = max(_holes - 1, 0);
             myProvider.redraw();
@@ -160,22 +176,25 @@ class Counter {
         Center(
           child: Text(
             _holes.toString(),
-            style: TextStyle(
+            style: const TextStyle(
               fontFamily: 'Blocks',
-              fontSize: 50,
+              fontSize: fontSize,
+            ),
+            textHeightBehavior: const TextHeightBehavior(
+              applyHeightToFirstAscent: false,
+              applyHeightToLastDescent: false,
             ),
           ),
         ),
         IconButton(
           padding: EdgeInsets.zero,
-          constraints: BoxConstraints(),
-          icon: Icon(
-            Icons.add,
-            color: buttonIconColor,
-            size: iconSize,
+          constraints: const BoxConstraints(),
+          style: const ButtonStyle(
+            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
           ),
+          icon: iconAdd,
           onPressed: () {
-            _holes = min(_holes + 1, 4);
+            _holes = min(_holes + 1, 9);
             myProvider.redraw();
           },
         ),
diff --git a/lib/entity/player.dart b/lib/entity/player.dart
index fe637add88582623829d352a7846c31ff5acb827..cef7f92cdc452487d61b7e6acbfda837020e75cf 100644
--- a/lib/entity/player.dart
+++ b/lib/entity/player.dart
@@ -1,6 +1,7 @@
 import 'dart:math';
 
 import 'package:flutter/material.dart';
+
 import 'package:tetrisdual/entity/counter.dart';
 import 'package:tetrisdual/layout/board_painter.dart';
 import 'package:tetrisdual/provider/data.dart';
@@ -11,106 +12,108 @@ class Player {
 
   int _score = 0;
   int _currentTetrimino = 0;
-  Counter _counter = new Counter();
+  final Counter _counter = Counter();
 
   Widget buildTetriminoWidget(Data myProvider, double width) {
-    return Container(
-      child: GestureDetector(
-        onTapUp: (details) {
-          if (playerId == myProvider.getCurrentPlayer().playerId) {
-            pickRandomTetrimino();
-            myProvider.redraw();
-          }
-        },
-        child: Container(
-          child: CustomPaint(
-            size: Size(width, width),
-            willChange: false,
-            painter: BoardPainter(_currentTetrimino),
-            isComplex: true,
-            key: Key(_currentTetrimino.toString()),
-          ),
-        ),
+    return GestureDetector(
+      onTapUp: (details) {
+        if (playerId == myProvider.getCurrentPlayer().playerId) {
+          pickRandomTetrimino();
+          myProvider.redraw();
+        }
+      },
+      child: CustomPaint(
+        size: Size(width, width),
+        willChange: false,
+        painter: BoardPainter(_currentTetrimino),
+        isComplex: true,
+        key: Key(_currentTetrimino.toString()),
       ),
     );
   }
 
   Widget buildManagerWidget(Data myProvider) {
-    List<Widget> items = [];
-
-    if (myProvider.currentPlayer == playerId) {
-      items.add(_counter.buildCounterWidget(myProvider));
-      items.add(buildSubmitWidget(myProvider));
-    }
-
     return Expanded(
       child: Container(
-        margin: EdgeInsets.all(5),
+        margin: const EdgeInsets.all(5),
         child: Column(
           mainAxisAlignment: MainAxisAlignment.start,
           crossAxisAlignment: CrossAxisAlignment.center,
-          children: items,
+          children: myProvider.currentPlayer == playerId
+              ? [
+                  _counter.buildCounterWidget(myProvider),
+                  buildSubmitWidget(myProvider),
+                ]
+              : [],
         ),
       ),
     );
   }
 
   Widget buildSubmitWidget(Data myProvider) {
-    double fontSize = 70;
+    const double gainFontSize = 70;
 
-    return Container(
-      decoration: BoxDecoration(
-        border: Border(
-          top: BorderSide(
-            color: Colors.black,
-            width: 2,
-          ),
+    const gainTestStyle = TextStyle(
+      fontFamily: 'Blocks',
+      fontSize: gainFontSize,
+      fontWeight: FontWeight.bold,
+    );
+    const submitIcon = Icon(
+      Icons.done_all,
+      color: Colors.orange,
+      size: gainFontSize / 2,
+    );
+
+    const topBorderBlack = BoxDecoration(
+      border: Border(
+        top: BorderSide(
+          color: Colors.black,
+          width: 2,
         ),
       ),
-      padding: EdgeInsets.only(
-        top: 5,
+    );
+
+    return Container(
+      decoration: topBorderBlack,
+      padding: const EdgeInsets.only(
+        top: 10,
       ),
       child: Row(
         mainAxisAlignment: MainAxisAlignment.end,
         crossAxisAlignment: CrossAxisAlignment.center,
         children: [
           Text(
-            '+' + _counter.computePoints().toString(),
-            style: TextStyle(
-              fontFamily: 'Blocks',
-              fontSize: fontSize,
-              fontWeight: FontWeight.bold,
+            '+${_counter.computePoints()}',
+            style: gainTestStyle,
+            textHeightBehavior: const TextHeightBehavior(
+              applyHeightToFirstAscent: false,
+              applyHeightToLastDescent: false,
             ),
           ),
-          SizedBox(
-            width: 10,
-          ),
+          const SizedBox(width: 10),
           IconButton(
             padding: EdgeInsets.zero,
-            constraints: BoxConstraints(),
-            icon: Icon(
-              Icons.done_all,
-              color: Colors.orange,
-              size: fontSize / 2.5,
+            constraints: const BoxConstraints(),
+            style: const ButtonStyle(
+              tapTargetSize: MaterialTapTargetSize.shrinkWrap,
             ),
+            icon: submitIcon,
             onPressed: () {
               _score = _score + _counter.computePoints();
               _counter.reset();
               myProvider.toggleCurrentPlayer();
             },
           ),
-          SizedBox(
-            width: 10,
-          ),
+          const SizedBox(width: 10),
         ],
       ),
     );
   }
 
   Widget buildPlayerBoard(Data myProvider, double screenWidth, bool isActive) {
-    double tetriminoBlockWidth = screenWidth / 2.3;
-    Color borderColor = isActive ? Colors.greenAccent : Colors.blueGrey;
-    double borderWidth = 10;
+    final double tetriminoBlockWidth = screenWidth / 2.3;
+    final Color borderColor = isActive ? Colors.greenAccent : Colors.blueGrey;
+    const double borderWidth = 10;
 
     return Column(
       mainAxisAlignment: MainAxisAlignment.center,
@@ -118,11 +121,15 @@ class Player {
       children: [
         Text(
           _score.toString(),
-          style: TextStyle(
+          style: const TextStyle(
             fontFamily: 'Blocks',
             fontSize: 130,
             fontWeight: FontWeight.bold,
           ),
+          textHeightBehavior: const TextHeightBehavior(
+            applyHeightToFirstAscent: false,
+            applyHeightToLastDescent: false,
+          ),
         ),
         Container(
           decoration: BoxDecoration(
@@ -132,8 +139,8 @@ class Player {
             ),
           ),
           child: Row(
-            mainAxisAlignment: MainAxisAlignment.center,
-            crossAxisAlignment: CrossAxisAlignment.start,
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            crossAxisAlignment: CrossAxisAlignment.center,
             children: [
               isActive
                   ? buildTetriminoWidget(myProvider, tetriminoBlockWidth)
diff --git a/lib/layout/board.dart b/lib/layout/board.dart
index 34118b7efe03e5db5e1ba0a634ee357e6bc4c803..b324c6ff4d0dfd583761f8e95a157ae889dfbf46 100644
--- a/lib/layout/board.dart
+++ b/lib/layout/board.dart
@@ -1,31 +1,37 @@
 import 'package:flutter/material.dart';
+
 import 'package:tetrisdual/provider/data.dart';
 
 class Board {
-  static Container buildGameBoard(Data myProvider, double screenWidth) {
-    Widget player1 = new RotatedBox(
+  static Widget buildGameBoard(Data myProvider, double screenWidth) {
+    final Widget player1 = RotatedBox(
       quarterTurns: 2,
       child: myProvider
           .getPlayer(1)
           .buildPlayerBoard(myProvider, screenWidth, myProvider.currentPlayer == 1),
     );
-    Widget player2 = myProvider
+
+    final Widget player2 = myProvider
         .getPlayer(2)
         .buildPlayerBoard(myProvider, screenWidth, myProvider.currentPlayer == 2);
 
-    Widget togglePlayerWidget = GestureDetector(
+    final Widget togglePlayerWidget = GestureDetector(
       onTapUp: (details) {
         myProvider.toggleCurrentPlayer();
       },
-      child: Text(
+      child: const Text(
         '🔄',
         style: TextStyle(
           fontSize: 50,
         ),
+        textHeightBehavior: TextHeightBehavior(
+          applyHeightToFirstAscent: false,
+          applyHeightToLastDescent: false,
+        ),
       ),
     );
 
-    return Container(
+    return Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         crossAxisAlignment: CrossAxisAlignment.center,
diff --git a/lib/layout/board_painter.dart b/lib/layout/board_painter.dart
index 1ec3cc1b91c718e077b8761b9009767e8e75c2b6..1ada211ad7ce141581510a49bb35bc5e21feff87 100644
--- a/lib/layout/board_painter.dart
+++ b/lib/layout/board_painter.dart
@@ -7,10 +7,15 @@ class BoardPainter extends CustomPainter {
 
   final int currentTetrimino;
 
-  void drawPixels(List<List<int>> pixels, Canvas canvas, double drawSize, Color pixelColor) {
+  void drawPixels(
+    List<List<int>> pixels,
+    Canvas canvas,
+    double drawSize,
+    Color pixelColor,
+  ) {
     int blockWidth = 1;
     int blockHeight = 1;
-    pixels.forEach((pixel) {
+    for (List<int> pixel in pixels) {
       int x = pixel[0] + 1;
       int y = pixel[1] + 1;
       if (x > blockWidth) {
@@ -19,52 +24,53 @@ class BoardPainter extends CustomPainter {
       if (y > blockHeight) {
         blockHeight = y;
       }
-    });
+    }
 
-    double pixelSize = drawSize / (max(blockWidth, blockHeight) + 2);
-    double xOffset =
+    final double pixelSize = drawSize / (max(blockWidth, blockHeight) + 2);
+    final double xOffset =
         (blockHeight > blockWidth) ? (blockHeight - blockWidth) * pixelSize / 2 : 0;
-    double yOffset =
+    final double yOffset =
         (blockWidth > blockHeight) ? (blockWidth - blockHeight) * pixelSize / 2 : 0;
 
     // Fill background
     final paintPixelBackground = Paint();
     paintPixelBackground.color = pixelColor;
     paintPixelBackground.style = PaintingStyle.fill;
-    pixels.forEach((pixel) {
-      int x = pixel[0];
-      int y = pixel[1];
+    for (List<int> pixel in pixels) {
+      final int x = pixel[0];
+      final int y = pixel[1];
       final Rect pixelBackground = Rect.fromPoints(
           Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)),
           Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2)));
       canvas.drawRect(pixelBackground, paintPixelBackground);
-    });
+    }
 
     // Border lines
     final paintPixelBorder = Paint();
     paintPixelBorder.color = Colors.grey.shade200;
     paintPixelBorder.style = PaintingStyle.stroke;
     paintPixelBorder.strokeWidth = 4;
-    pixels.forEach((pixel) {
-      int x = pixel[0];
-      int y = pixel[1];
+    for (List<int> pixel in pixels) {
+      final int x = pixel[0];
+      final int y = pixel[1];
       final Rect rectBackground = Rect.fromPoints(
           Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)),
           Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2)));
       canvas.drawRect(rectBackground, paintPixelBorder);
-    });
+    }
   }
 
   @override
   void paint(Canvas canvas, Size size) {
-    double drawSize = min(size.width, size.height);
+    final double drawSize = min(size.width, size.height);
 
     // Fill background
     final paintBackground = Paint();
     paintBackground.color = Colors.grey.shade800;
     paintBackground.style = PaintingStyle.fill;
 
-    final Rect rectBackground = Rect.fromPoints(Offset(0, 0), Offset(drawSize, drawSize));
+    final Rect rectBackground =
+        Rect.fromPoints(const Offset(0, 0), Offset(drawSize, drawSize));
     canvas.drawRect(rectBackground, paintBackground);
 
     // Add tetrimino
diff --git a/lib/layout/game.dart b/lib/layout/game.dart
index 4d44d2dcde0bbafe9763eca9673c285d22538b1c..b8a54c803d424b0059b7c509f2d2e82072d453cf 100644
--- a/lib/layout/game.dart
+++ b/lib/layout/game.dart
@@ -1,20 +1,19 @@
 import 'package:flutter/material.dart';
+
 import 'package:tetrisdual/layout/board.dart';
 import 'package:tetrisdual/provider/data.dart';
 import 'package:tetrisdual/utils/game_utils.dart';
 
 class Game {
-  static Container buildGameWidget(Data myProvider, double screenWidth) {
-    return Container(
-      child: !myProvider.isGameFinished
-          ? Board.buildGameBoard(myProvider, screenWidth)
-          : Game.buildEndGameMessage(myProvider),
-    );
+  static Widget buildGameWidget(Data myProvider, double screenWidth) {
+    return !myProvider.isGameFinished
+        ? Board.buildGameBoard(myProvider, screenWidth)
+        : Game.buildEndGameMessage(myProvider);
   }
 
   static TextButton buildQuitGameButton(Data myProvider) {
     return TextButton(
-      child: Image(
+      child: const Image(
         image: AssetImage('assets/icons/button_back.png'),
         fit: BoxFit.fill,
       ),
@@ -23,21 +22,21 @@ class Game {
   }
 
   static Container buildEndGameMessage(Data myProvider) {
-    String decorationImageAssetName = 'assets/icons/game_fail.png';
+    const String decorationImageAssetName = 'assets/icons/game_fail.png';
 
-    Widget decorationWidget = TextButton(
-      child: Image(
+    final Widget decorationWidget = TextButton(
+      child: const Image(
         image: AssetImage(decorationImageAssetName),
         fit: BoxFit.fill,
       ),
-      onPressed: () => null,
+      onPressed: () {},
     );
 
     return Container(
-      margin: EdgeInsets.all(2),
-      padding: EdgeInsets.all(2),
+      margin: const EdgeInsets.all(2),
+      padding: const EdgeInsets.all(2),
       child: Table(
-        defaultColumnWidth: IntrinsicColumnWidth(),
+        defaultColumnWidth: const IntrinsicColumnWidth(),
         children: [
           TableRow(
             children: [
diff --git a/lib/layout/parameters.dart b/lib/layout/parameters.dart
index b2d26077c5baee475f01adc4cde5487447388bab..97f81cfd2939f44abb01b4b754ca3a139b477f9a 100644
--- a/lib/layout/parameters.dart
+++ b/lib/layout/parameters.dart
@@ -1,55 +1,54 @@
 import 'package:flutter/material.dart';
+
 import 'package:tetrisdual/provider/data.dart';
 import 'package:tetrisdual/utils/game_utils.dart';
 
 class Parameters {
-  static double separatorHeight = 2.0;
-  static double blockMargin = 3.0;
-  static double blockPadding = 2.0;
-  static Color buttonBackgroundColor = Colors.white;
-  static Color buttonBorderColorActive = Colors.blue;
-  static Color buttonBorderColorInactive = Colors.white;
-  static double buttonBorderWidth = 10.0;
-  static double buttonBorderRadius = 8.0;
-  static double buttonPadding = 0.0;
-  static double buttonMargin = 0.0;
-
-  static Container buildParametersSelector(Data myProvider) {
-    List<Widget> lines = [];
-
-    List parameters = myProvider.availableParameters;
-    for (var index = 0; index < parameters.length; index++) {
+  static const double separatorHeight = 2.0;
+  static const double blockMargin = 3.0;
+  static const double blockPadding = 2.0;
+  static const Color buttonBackgroundColor = Colors.white;
+  static const Color buttonBorderColorActive = Colors.blue;
+  static const Color buttonBorderColorInactive = Colors.white;
+  static const double buttonBorderWidth = 10.0;
+  static const double buttonBorderRadius = 8.0;
+  static const double buttonPadding = 0.0;
+  static const double buttonMargin = 0.0;
+
+  static Widget buildParametersSelector(Data myProvider) {
+    final List<Widget> lines = [];
+
+    final List<String> parameters = myProvider.availableParameters;
+    for (int index = 0; index < parameters.length; index++) {
       lines.add(buildParameterSelector(myProvider, parameters[index]));
-      lines.add(SizedBox(height: separatorHeight));
+      lines.add(const SizedBox(height: separatorHeight));
     }
 
-    Widget buttonsBlock = buildStartNewGameButton(myProvider);
+    final Widget buttonsBlock = buildStartNewGameButton(myProvider);
 
-    return Container(
-      child: Column(
-        mainAxisAlignment: MainAxisAlignment.start,
-        crossAxisAlignment: CrossAxisAlignment.center,
-        children: [
-          SizedBox(height: separatorHeight),
-          Expanded(
-            child: Column(
-              mainAxisSize: MainAxisSize.min,
-              mainAxisAlignment: MainAxisAlignment.center,
-              children: lines,
-            ),
-          ),
-          SizedBox(height: separatorHeight),
-          Container(
-            child: buttonsBlock,
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.start,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        const SizedBox(height: separatorHeight),
+        Expanded(
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: lines,
           ),
-        ],
-      ),
+        ),
+        const SizedBox(height: separatorHeight),
+        Container(
+          child: buttonsBlock,
+        ),
+      ],
     );
   }
 
   static Image buildImageWidget(String imageAssetCode) {
     return Image(
-      image: AssetImage('assets/icons/' + imageAssetCode + '.png'),
+      image: AssetImage('assets/icons/$imageAssetCode.png'),
       fit: BoxFit.fill,
     );
   }
@@ -65,7 +64,7 @@ class Parameters {
       children: [
         TextButton(
           child: buildImageContainerWidget('placeholder'),
-          onPressed: () => null,
+          onPressed: () {},
         ),
       ],
     );
@@ -73,10 +72,10 @@ class Parameters {
 
   static Container buildStartNewGameButton(Data myProvider) {
     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: [
@@ -98,18 +97,18 @@ class Parameters {
   }
 
   static Widget buildParameterSelector(Data myProvider, String parameterCode) {
-    List availableValues = myProvider.getParameterAvailableValues(parameterCode);
+    final List<String> availableValues = myProvider.getParameterAvailableValues(parameterCode);
 
     if (availableValues.length == 1) {
-      return SizedBox(height: 0.0);
+      return const SizedBox(height: 0.0);
     }
 
     return Table(
-      defaultColumnWidth: IntrinsicColumnWidth(),
+      defaultColumnWidth: const IntrinsicColumnWidth(),
       children: [
         TableRow(
           children: [
-            for (var index = 0; index < availableValues.length; index++)
+            for (int index = 0; index < availableValues.length; index++)
               Column(
                 children: [
                   _buildParameterButton(myProvider, parameterCode, availableValues[index])
@@ -122,16 +121,19 @@ class Parameters {
   }
 
   static Widget _buildParameterButton(
-      Data myProvider, String parameterCode, String parameterValue) {
-    String currentValue = myProvider.getParameterValue(parameterCode).toString();
+    Data myProvider,
+    String parameterCode,
+    String parameterValue,
+  ) {
+    final String currentValue = myProvider.getParameterValue(parameterCode).toString();
 
-    bool isActive = (parameterValue == currentValue);
-    String imageAsset = parameterCode + '_' + parameterValue;
+    final bool isActive = (parameterValue == currentValue);
+    final String imageAsset = '${parameterCode}_$parameterValue';
 
     return TextButton(
       child: Container(
-        margin: EdgeInsets.all(buttonMargin),
-        padding: EdgeInsets.all(buttonPadding),
+        margin: const EdgeInsets.all(buttonMargin),
+        padding: const EdgeInsets.all(buttonPadding),
         decoration: BoxDecoration(
           color: buttonBackgroundColor,
           borderRadius: BorderRadius.circular(buttonBorderRadius),
diff --git a/lib/main.dart b/lib/main.dart
index b232341f260a92893c59aad787f867e50df4faad..121d1109f25290bd210df2442c310a169db8ab28 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,17 +1,20 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:tetrisdual/provider/data.dart';
-import 'package:tetrisdual/screens/home.dart';
 import 'package:provider/provider.dart';
 import 'package:overlay_support/overlay_support.dart';
 
+import 'package:tetrisdual/provider/data.dart';
+import 'package:tetrisdual/screens/home.dart';
+
 void main() {
   WidgetsFlutterBinding.ensureInitialized();
   SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
-      .then((value) => runApp(MyApp()));
+      .then((value) => runApp(const MyApp()));
 }
 
 class MyApp extends StatelessWidget {
+  const MyApp({super.key});
+
   @override
   Widget build(BuildContext context) {
     return ChangeNotifierProvider(
@@ -19,14 +22,13 @@ class MyApp extends StatelessWidget {
       child: Consumer<Data>(builder: (context, data, child) {
         return OverlaySupport(
           child: MaterialApp(
-            debugShowCheckedModeBanner: false,
             theme: ThemeData(
               primaryColor: Colors.blue,
               visualDensity: VisualDensity.adaptivePlatformDensity,
             ),
-            home: Home(),
+            home: const Home(),
             routes: {
-              Home.id: (context) => Home(),
+              Home.id: (context) => const Home(),
             },
           ),
         );
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index 061baf17929c050ac48f182ec5c8041889cef5b2..b1f4ad0e5d4c79c0252a7762b9fa900f5da04412 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -2,32 +2,30 @@ import 'dart:math';
 
 import 'package:flutter/foundation.dart';
 import 'package:shared_preferences/shared_preferences.dart';
+
 import 'package:tetrisdual/entity/player.dart';
 
 class Data extends ChangeNotifier {
   // Configuration available parameters
-  List _availableParameters = [];
+  final List<String> _availableParameters = [];
 
-  List get availableParameters => _availableParameters;
+  List<String> get availableParameters => _availableParameters;
 
   // Application default configuration
 
   // Application current configuration
   String getParameterValue(String parameterCode) {
-    switch (parameterCode) {
-    }
+    switch (parameterCode) {}
     return '';
   }
 
-  List getParameterAvailableValues(String parameterCode) {
-    switch (parameterCode) {
-    }
+  List<String> getParameterAvailableValues(String parameterCode) {
+    switch (parameterCode) {}
     return [];
   }
 
   void setParameterValue(String parameterCode, String parameterValue) async {
-    switch (parameterCode) {
-    }
+    switch (parameterCode) {}
     final prefs = await SharedPreferences.getInstance();
     prefs.setString(parameterCode, parameterValue);
   }
@@ -75,12 +73,12 @@ class Data extends ChangeNotifier {
   }
 
   Player getPlayer(int playerId) {
-    int playerIndex = playerId - 1;
+    final int playerIndex = playerId - 1;
     Player? player = _players[playerIndex];
 
     // Create new player if none
     if (null == player) {
-      player = new Player(playerId);
+      player = Player(playerId);
       _players[playerIndex] = player;
     }
 
@@ -98,7 +96,7 @@ class Data extends ChangeNotifier {
   void resetGame() {
     _gameIsRunning = false;
     _gameIsFinished = false;
-    _players = [new Player(1), new Player(2)];
+    _players = [Player(1), Player(2)];
     notifyListeners();
   }
 }
diff --git a/lib/screens/home.dart b/lib/screens/home.dart
index 5b8ee82f10c9b18fdcaf0aaccb32a9b69e3b44bd..34cdc098057ec2fe06739f673a9aec55382fbbf2 100644
--- a/lib/screens/home.dart
+++ b/lib/screens/home.dart
@@ -1,19 +1,22 @@
 import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import 'package:overlay_support/overlay_support.dart';
+
 import 'package:tetrisdual/layout/game.dart';
 import 'package:tetrisdual/layout/parameters.dart';
 import 'package:tetrisdual/provider/data.dart';
 import 'package:tetrisdual/utils/game_utils.dart';
-import 'package:provider/provider.dart';
-import 'package:overlay_support/overlay_support.dart';
 
 class Home extends StatefulWidget {
+  const Home({super.key});
+
   static const String id = 'home';
 
   @override
-  _HomeState createState() => _HomeState();
+  HomeState createState() => HomeState();
 }
 
-class _HomeState extends State<Home> {
+class HomeState extends State<Home> {
   @override
   void initState() {
     super.initState();
@@ -21,42 +24,29 @@ class _HomeState extends State<Home> {
 
   @override
   Widget build(BuildContext context) {
-    Data myProvider = Provider.of<Data>(context);
-    double screenWidth = MediaQuery.of(context).size.width;
+    final Data myProvider = Provider.of<Data>(context);
+    final double screenWidth = MediaQuery.of(context).size.width;
 
-    List<Widget> menuActions = [];
+    final List<Widget> menuActions = [];
 
     if (myProvider.isGameRunning) {
-      menuActions = [
-        TextButton(
-          child: Container(
-            decoration: BoxDecoration(
-              borderRadius: BorderRadius.circular(4),
-              border: Border.all(
-                color: Colors.blue,
-                width: 4,
-              ),
-            ),
-            child: Image(
-              image: AssetImage('assets/icons/button_back.png'),
-              fit: BoxFit.fill,
-            ),
-          ),
-          onPressed: () => toast('Long press to quit game...'),
-          onLongPress: () => GameUtils.quitGame(myProvider),
+      menuActions.add(TextButton(
+        child: const Image(
+          image: AssetImage('assets/icons/button_back.png'),
+          fit: BoxFit.fill,
         ),
-      ];
+        onPressed: () => toast('Long press to quit game...'),
+        onLongPress: () => GameUtils.quitGame(myProvider),
+      ));
     }
 
     return Scaffold(
       appBar: AppBar(
         actions: menuActions,
       ),
-      body: SafeArea(
-        child: myProvider.isGameRunning
-            ? Game.buildGameWidget(myProvider, screenWidth)
-            : Parameters.buildParametersSelector(myProvider),
-      ),
+      body: myProvider.isGameRunning
+          ? Game.buildGameWidget(myProvider, screenWidth)
+          : Parameters.buildParametersSelector(myProvider),
     );
   }
 }
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index 5bd436ba68ef0e2c9943efce9b629e8e90326049..fed7b66ae2d25e27d9b6e4fc1ef9d702228f0ca2 100644
--- a/lib/utils/game_utils.dart
+++ b/lib/utils/game_utils.dart
@@ -6,8 +6,6 @@ class GameUtils {
   }
 
   static Future<void> startNewGame(Data myProvider) async {
-    print('Starting game');
-
     myProvider.resetGame();
     myProvider.enableRandomPlayer();
     myProvider.getCurrentPlayer().pickRandomTetrimino();
diff --git a/pubspec.lock b/pubspec.lock
index f78ae3bfbc5b91625f56452dcbc944e3e78db356..394474ffa93627c54bc013d08e68346854cf7420 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -21,52 +21,68 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.2"
+    version: "1.18.0"
   ffi:
     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:
       name: file
-      sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
+      sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
       url: "https://pub.dev"
     source: hosted
-    version: "6.1.4"
+    version: "7.0.0"
   flutter:
     dependency: "direct main"
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_lints:
+    dependency: "direct dev"
+    description:
+      name: flutter_lints
+      sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.1"
   flutter_web_plugins:
     dependency: transitive
     description: flutter
     source: sdk
     version: "0.0.0"
+  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: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
+      sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
       url: "https://pub.dev"
     source: hosted
-    version: "1.9.1"
+    version: "1.11.0"
   nested:
     dependency: transitive
     description:
@@ -87,10 +103,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_linux:
     dependency: transitive
     description:
@@ -103,10 +119,10 @@ packages:
     dependency: transitive
     description:
       name: path_provider_platform_interface
-      sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
+      sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   path_provider_windows:
     dependency: transitive
     description:
@@ -119,34 +135,34 @@ packages:
     dependency: transitive
     description:
       name: platform
-      sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
+      sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.2"
+    version: "3.1.4"
   plugin_platform_interface:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.6"
+    version: "2.1.8"
   provider:
     dependency: "direct main"
     description:
       name: provider
-      sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
+      sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
       url: "https://pub.dev"
     source: hosted
-    version: "6.0.5"
+    version: "6.1.1"
   shared_preferences:
     dependency: "direct main"
     description:
       name: shared_preferences
-      sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac
+      sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.2.2"
   shared_preferences_android:
     dependency: transitive
     description:
@@ -159,42 +175,42 @@ packages:
     dependency: transitive
     description:
       name: shared_preferences_foundation
-      sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
+      sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.4"
+    version: "2.3.5"
   shared_preferences_linux:
     dependency: transitive
     description:
       name: shared_preferences_linux
-      sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a
+      sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.3.2"
   shared_preferences_platform_interface:
     dependency: transitive
     description:
       name: shared_preferences_platform_interface
-      sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
+      sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.3.2"
   shared_preferences_web:
     dependency: transitive
     description:
       name: shared_preferences_web
-      sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
+      sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.3.0"
   shared_preferences_windows:
     dependency: transitive
     description:
       name: shared_preferences_windows
-      sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f
+      sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.3.2"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -212,26 +228,26 @@ packages:
     dependency: transitive
     description:
       name: web
-      sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
+      sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad"
       url: "https://pub.dev"
     source: hosted
-    version: "0.1.4-beta"
+    version: "0.5.0"
   win32:
     dependency: transitive
     description:
       name: win32
-      sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
+      sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
       url: "https://pub.dev"
     source: hosted
-    version: "5.0.9"
+    version: "5.2.0"
   xdg_directories:
     dependency: transitive
     description:
       name: xdg_directories
-      sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.3"
+    version: "1.0.4"
 sdks:
-  dart: ">=3.1.0-185.0.dev <4.0.0"
-  flutter: ">=3.7.0"
+  dart: ">=3.3.0 <4.0.0"
+  flutter: ">=3.19.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 239b6c1531400caa90940eaa3d23a4906488535e..456fd9def63bf71f451809812bbdd4363fa54843 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
 name: tetrisdual
 description: Tetris Dual Game
 publish_to: 'none'
-version: 1.0.0+1
+version: 0.0.9+9
 
 environment:
   sdk: '^3.0.0'
@@ -13,6 +13,9 @@ dependencies:
   shared_preferences: ^2.2.1
   overlay_support: ^2.1.0
 
+dev_dependencies:
+  flutter_lints: ^3.0.1
+
 flutter:
   uses-material-design: true
   assets: