diff --git a/android/gradle.properties b/android/gradle.properties
index 621336f47b3be71128005116384f1c3636771131..518a71328fa72488a4d0435c21984a21b90946da 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=1.0.40
-app.versionCode=41
+app.versionName=1.0.41
+app.versionCode=42
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
index 231ed500fe9439775ae1ed1a07336c481052ba30..336c70ff15f76901a98ee556c2dfb489e64f445b 100644
--- a/lib/cubit/game_cubit.dart
+++ b/lib/cubit/game_cubit.dart
@@ -1,7 +1,8 @@
 import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
-import 'package:random/models/game_data.dart';
+
+import 'package:random/models/game/game.dart';
 
 part 'game_state.dart';
 
@@ -12,13 +13,13 @@ class GameCubit extends HydratedCubit<GameState> {
     emit(gameState);
   }
 
-  void updateGameState(GameData gameData) {
+  void updateGameState(Game gameData) {
     emit(GameState(game: gameData));
   }
 
   @override
   GameState? fromJson(Map<String, dynamic> json) {
-    GameData game = json['game'] as GameData;
+    Game game = json['game'] as Game;
 
     return GameState(
       game: game,
diff --git a/lib/cubit/game_state.dart b/lib/cubit/game_state.dart
index ea6c33cf1ce0150ac8b9c358005e42a64447ab0d..3e4d0d092cf5da751fd66f72dedea0501878acbd 100644
--- a/lib/cubit/game_state.dart
+++ b/lib/cubit/game_state.dart
@@ -6,7 +6,7 @@ class GameState extends Equatable {
     this.game,
   });
 
-  final GameData? game;
+  final Game? game;
 
   @override
   List<Object?> get props => <Object?>[
diff --git a/lib/models/game/game.dart b/lib/models/game/game.dart
new file mode 100644
index 0000000000000000000000000000000000000000..bf777d743a798124664fa152ab8121e5c694442f
--- /dev/null
+++ b/lib/models/game/game.dart
@@ -0,0 +1,93 @@
+import 'dart:math';
+
+import 'package:random/models/game/game_board.dart';
+import 'package:random/models/game/game_cell.dart';
+import 'package:random/models/game/game_settings.dart';
+
+class Game {
+  GameBoard board;
+  GameSettings settings;
+  bool isRunning = false;
+  bool isFinished = false;
+  int availableBlocksCount = 0;
+  int movesCount = 0;
+  int score = 0;
+
+  Game({
+    required this.board,
+    required this.settings,
+    this.isRunning = false,
+  });
+
+  factory Game.createNull() {
+    return Game(
+      board: GameBoard.createNull(),
+      settings: GameSettings.createDefault(),
+    );
+  }
+
+  factory Game.createNew({GameSettings? gameSettings}) {
+    GameSettings settings = gameSettings ?? GameSettings.createDefault();
+
+    return Game(
+      board: GameBoard.createRandom(settings),
+      settings: settings,
+      isRunning: true,
+    );
+  }
+
+  void stop() {
+    this.isRunning = false;
+    this.isFinished = true;
+  }
+
+  GameCell getCell(int x, int y) {
+    return this.board.cells[y][x];
+  }
+
+  int? getCellValue(int x, int y) {
+    return this.getCell(x, y).value;
+  }
+
+  void updateCellValue(int x, int y, int? value) {
+    this.board.cells[y][x].value = value;
+  }
+
+  void setRandomCellValue(int x, int y, GameSettings settings) {
+    final int maxValue = settings.colorsCount;
+    final rand = new Random();
+    int value = 1 + rand.nextInt(maxValue);
+
+    this.board.cells[y][x].value = value;
+  }
+
+  void increaseMovesCount() {
+    this.movesCount += 1;
+  }
+
+  void increaseScore(int? count) {
+    this.score += (count ?? 0);
+  }
+
+  String toString() {
+    return 'Game(' + this.toJson().toString() + ')';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'board': this.board.toJson(),
+      'settings': this.settings.toJson(),
+      'isRunning': this.isRunning,
+      'isFinished': this.isFinished,
+      'availableBlocksCount': this.availableBlocksCount,
+      'movesCount': this.movesCount,
+      'score': this.score,
+    };
+  }
+
+  void dump() {
+    GameBoard.printGrid(this.board.cells);
+    print(this.settings.toJson());
+    print(this.toJson());
+  }
+}
diff --git a/lib/models/game/game_board.dart b/lib/models/game/game_board.dart
new file mode 100644
index 0000000000000000000000000000000000000000..65654940e1fea58ca44dfaf290fab8d34a9d2806
--- /dev/null
+++ b/lib/models/game/game_board.dart
@@ -0,0 +1,61 @@
+import 'dart:math';
+
+import 'package:random/models/game/game_cell.dart';
+import 'package:random/models/game/game_settings.dart';
+
+class GameBoard {
+  final List<List<GameCell>> cells;
+
+  GameBoard({
+    required this.cells,
+  });
+
+  factory GameBoard.createNull() {
+    return GameBoard(cells: []);
+  }
+
+  factory GameBoard.createRandom(GameSettings gameSettings) {
+    final int boardSizeHorizontal = gameSettings.boardSize;
+    final int boardSizeVertical = gameSettings.boardSize;
+    final int maxValue = gameSettings.colorsCount;
+
+    final rand = new Random();
+
+    List<List<GameCell>> grid = [];
+    for (var rowIndex = 0; rowIndex < boardSizeVertical; rowIndex++) {
+      List<GameCell> row = [];
+      for (var colIndex = 0; colIndex < boardSizeHorizontal; colIndex++) {
+        int value = 1 + rand.nextInt(maxValue);
+        row.add(GameCell(value));
+      }
+      grid.add(row);
+    }
+    printGrid(grid);
+
+    return GameBoard(cells: grid);
+  }
+
+  static printGrid(List<List<GameCell>> cells) {
+    print('');
+    print('-------');
+    for (var rowIndex = 0; rowIndex < cells.length; rowIndex++) {
+      String row = '';
+      for (var colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
+        row += cells[rowIndex][colIndex].value.toString();
+      }
+      print(row);
+    }
+    print('-------');
+    print('');
+  }
+
+  String toString() {
+    return 'Board(' + this.toJson().toString() + ')';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'cells': this.cells.toString(),
+    };
+  }
+}
diff --git a/lib/models/game/game_cell.dart b/lib/models/game/game_cell.dart
new file mode 100644
index 0000000000000000000000000000000000000000..25667ccf76bfbd4ef65f8651c120a7dbaab641b8
--- /dev/null
+++ b/lib/models/game/game_cell.dart
@@ -0,0 +1,17 @@
+class GameCell {
+  int? value;
+
+  GameCell(
+    this.value,
+  );
+
+  String toString() {
+    return 'Cell(' + this.toJson().toString() + ')';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'value': this.value,
+    };
+  }
+}
diff --git a/lib/models/game/game_settings.dart b/lib/models/game/game_settings.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4610c789c81b6f0d92745b45c089035c899c0772
--- /dev/null
+++ b/lib/models/game/game_settings.dart
@@ -0,0 +1,45 @@
+class DefaultGameSettings {
+  static const int defaultBoardSizeValue = 6;
+  static const List<int> allowedBoardSizeValues = [
+    5,
+    6,
+    10,
+    15,
+  ];
+
+  static const int defaultColorsCountValue = 7;
+  static const List<int> allowedColorsCountValues = [
+    4,
+    5,
+    6,
+    7,
+  ];
+}
+
+class GameSettings {
+  final int boardSize;
+  final int colorsCount;
+
+  GameSettings({
+    required this.boardSize,
+    required this.colorsCount,
+  });
+
+  factory GameSettings.createDefault() {
+    return GameSettings(
+      boardSize: DefaultGameSettings.defaultBoardSizeValue,
+      colorsCount: DefaultGameSettings.defaultColorsCountValue,
+    );
+  }
+
+  String toString() {
+    return 'GameSettings(' + this.toJson().toString() + ')';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'boardSize': this.boardSize,
+      'colorsCount': this.colorsCount,
+    };
+  }
+}
diff --git a/lib/models/game_data.dart b/lib/models/game_data.dart
deleted file mode 100644
index 6a519d5bb925009b7cb338ad245eb00586130803..0000000000000000000000000000000000000000
--- a/lib/models/game_data.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-import 'dart:convert';
-import 'dart:math';
-
-class GameDataItem {
-  final int? value;
-
-  const GameDataItem({
-    required this.value,
-  });
-
-  factory GameDataItem.fromValue(int? value) {
-    return GameDataItem(
-      value: value,
-    );
-  }
-
-  factory GameDataItem.fromJson(Map<String, dynamic>? json) {
-    return GameDataItem(
-      value: (json?['value'] != null) ? (json?['value'] as int) : null,
-    );
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      'value': this.value,
-    };
-  }
-
-  String toString() {
-    return jsonEncode(this.toJson());
-  }
-}
-
-class GameData {
-  final bool isReady;
-  final int boardSize;
-  final List<List<GameDataItem>> board;
-
-  const GameData({
-    required this.isReady,
-    required this.boardSize,
-    required this.board,
-  });
-
-  factory GameData.createNew(int boardSize) {
-    final List<List<GameDataItem>> cells = [];
-
-    for (var y = 0; y < boardSize; y++) {
-      final List<GameDataItem> line = [];
-      for (var x = 0; x < boardSize; x++) {
-        final GameDataItem item = new GameDataItem(value: null);
-        line.add(item);
-      }
-
-      cells.add(line);
-    }
-
-    return GameData(
-      isReady: true,
-      boardSize: boardSize,
-      board: cells,
-    );
-  }
-
-  factory GameData.createRandom(int boardSize) {
-    const allowedValues = [0, 1, 2, 3, 4, 5];
-    final allowedValuesSize = allowedValues.length;
-
-    final List<List<GameDataItem>> cells = [];
-
-    for (var y = 0; y < boardSize; y++) {
-      final List<GameDataItem> line = [];
-      for (var x = 0; x < boardSize; x++) {
-        final value = allowedValues[Random().nextInt(allowedValuesSize)];
-        final GameDataItem item = new GameDataItem(value: value);
-        line.add(item);
-      }
-
-      cells.add(line);
-    }
-
-    return GameData(
-      isReady: true,
-      boardSize: boardSize,
-      board: cells,
-    );
-  }
-
-  GameDataItem getCell(int x, int y) {
-    return this.board[y][x];
-  }
-
-  int? getCellValue(int x, int y) {
-    return this.getCell(x, y).value;
-  }
-
-  void updateCellValue(int x, int y, int? value) {
-    this.board[y][x] = new GameDataItem.fromValue(value);
-  }
-
-  factory GameData.fromJson(Map<String, dynamic>? json) {
-    return GameData(
-      isReady: (json?['isReady'] != null) ? (json?['isReady'] as bool) : false,
-      boardSize: (json?['boardSize'] != null) ? (json?['boardSize'] as int) : 0,
-      board: (json?['board'] != null) ? (json?['board'] as List<List<GameDataItem>>) : [],
-    );
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      'isReady': this.isReady,
-      'boardSize': this.boardSize,
-      'board': this.board,
-    };
-  }
-
-  String toString() {
-    return jsonEncode(this.toJson());
-  }
-}
diff --git a/lib/ui/painters/cell_painter.dart b/lib/ui/painters/cell_painter.dart
index e50ce3d26370860f7137b60613de5b44a375c7c9..a2cf510a27634d1d33f6b15d92c2ce843aff7f36 100644
--- a/lib/ui/painters/cell_painter.dart
+++ b/lib/ui/painters/cell_painter.dart
@@ -19,7 +19,6 @@ class CellPainter extends CustomPainter {
       AppColors.contentColorYellow,
       AppColors.contentColorPink,
       AppColors.contentColorWhite,
-      AppColors.mainTextColor3,
     ];
 
     return availableColors[index % availableColors.length];
diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart
index 93cd8573714e6ecd1e1a31767cee758f05619302..7822504342cb02e8b352f05c080441c38e81fa57 100644
--- a/lib/ui/screens/game_page.dart
+++ b/lib/ui/screens/game_page.dart
@@ -3,8 +3,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:unicons/unicons.dart';
 
 import 'package:random/cubit/game_cubit.dart';
-import 'package:random/models/game_data.dart';
-import 'package:random/ui/widgets/game_board.dart';
+import 'package:random/models/game/game.dart';
+import 'package:random/ui/widgets/game/game_settings.dart';
+import 'package:random/ui/widgets/game/game_board.dart';
 
 class GamePage extends StatefulWidget {
   const GamePage({super.key});
@@ -13,133 +14,61 @@ class GamePage extends StatefulWidget {
   State<GamePage> createState() => _GamePageState();
 }
 
-class _GamePageState extends State<GamePage> with TickerProviderStateMixin {
-  static const boardSize = 6;
-
-  List<List<Animation<double>?>> animations = List.generate(
-    boardSize,
-    (i) => List.generate(
-      boardSize,
-      (i) => null,
-    ),
-  );
-
-  void resetAnimations() {
-    animations = List.generate(
-      boardSize,
-      (i) => List.generate(
-        boardSize,
-        (i) => null,
-      ),
-    );
-  }
-
-  void createNewGame(GameCubit gameCubit) {
-    final GameData newGame = GameData.createRandom(boardSize);
-    gameCubit.updateGameState(newGame);
-  }
-
-  void removeCell(GameCubit gameCubit, int x, int y) {
-    final GameData newGame = gameCubit.state.game ?? GameData.createRandom(boardSize);
-
-    // "remove" cell
-    newGame.updateCellValue(x, y, null);
-    setState(() {});
-
-    // "move down" cells
-    final controller = AnimationController(
-      vsync: this,
-      duration: Duration(milliseconds: 750),
-    )..addListener(() {
-        if (mounted) {
-          setState(() {});
-        }
-      });
-
-    if (mounted) {
-      setState(() {});
-    }
-
-    Animation<double> animation = Tween(
-      begin: 0.0,
-      end: 1.0,
-    ).animate(CurvedAnimation(
-      curve: Curves.bounceOut,
-      parent: controller,
-    ))
-      ..addStatusListener((status) {
-        if (status == AnimationStatus.completed) {
-          for (var i = 0; i < y; i++) {
-            newGame.updateCellValue(x, (y - i), newGame.getCellValue(x, (y - i) - 1));
-          }
-          newGame.updateCellValue(x, 0, null);
-
-          resetAnimations();
-          setState(() {});
-
-          controller.dispose();
-        }
-      });
-
-    for (var i = 0; i < y; i++) {
-      animations[(y - i) - 1][x] = animation;
-    }
-
-    controller.forward().orCancel;
-  }
-
-  void updateCellValue(GameCubit gameCubit, int x, int y, int value) {
-    final GameData newGame = gameCubit.state.game ?? GameData.createRandom(boardSize);
-    newGame.updateCellValue(x, y, value);
-
-    gameCubit.updateGameState(newGame);
-    setState(() {});
+class _GamePageState extends State<GamePage> {
+  Widget buildGameActionsBloc(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(builder: (context, gameState) {
+      final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+
+      final List<Widget> buttons = [
+        IconButton(
+          onPressed: () {
+            gameCubit.updateGameState(Game.createNew());
+          },
+          icon: Icon(UniconsSolid.star),
+          color: Colors.white,
+        )
+      ];
+
+      if (gameState.game?.isRunning == true) {
+        buttons.add(IconButton(
+          onPressed: () {
+            final Game currentGame = gameCubit.state.game!;
+            currentGame.stop();
+
+            gameCubit.updateGameState(currentGame);
+            setState(() {});
+          },
+          icon: Icon(UniconsLine.exit),
+          color: Colors.white,
+        ));
+      }
+
+      return Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: buttons,
+      );
+    });
   }
 
   @override
   Widget build(BuildContext context) {
+    const double boardWidgetWidth = 300;
+    const double boardWidgetHeight = 300;
+
     return BlocBuilder<GameCubit, GameState>(
       builder: (context, gameState) {
-        const boardSize = 6;
-        const double boardWidgetWidth = 300;
-        const double boardWidgetHeight = 300;
-
-        final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-
-        if (gameState.game?.isReady != true) {
-          createNewGame(gameCubit);
-        }
-
         return Column(
           mainAxisAlignment: MainAxisAlignment.start,
           crossAxisAlignment: CrossAxisAlignment.center,
           children: [
-            GestureDetector(
-              child: gameState.game != null
-                  ? GameBoardWidget(
-                      gameData: gameState.game!,
-                      size: Size(boardWidgetWidth, boardWidgetHeight),
-                      animations: animations,
-                    )
-                  : SizedBox.shrink(),
-              onTapUp: (details) {
-                double xTap = details.localPosition.dx;
-                double yTap = details.localPosition.dy;
-
-                int x = (xTap / boardWidgetWidth * boardSize).toInt();
-                int y = (yTap / boardWidgetHeight * boardSize).toInt();
-                print('[' + x.toString() + ',' + y.toString() + ']');
-
-                removeCell(gameCubit, x, y);
-              },
-            ),
-            IconButton(
-              onPressed: () {
-                createNewGame(gameCubit);
-              },
-              icon: Icon(UniconsSolid.star),
-              color: Colors.white,
-            ),
+            gameState.game?.isRunning == true
+                ? GameBoardWidget(
+                    game: gameState.game!,
+                    widgetSize: Size(boardWidgetWidth, boardWidgetHeight),
+                  )
+                : GameSettingsWidget(),
+            buildGameActionsBloc(context),
           ],
         );
       },
diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart
new file mode 100644
index 0000000000000000000000000000000000000000..47453badc4b525abc18890a3e0e360fa6eb79536
--- /dev/null
+++ b/lib/ui/widgets/game/game_board.dart
@@ -0,0 +1,177 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:random/cubit/game_cubit.dart';
+import 'package:random/models/game/game.dart';
+import 'package:random/models/game/game_settings.dart';
+import 'package:random/ui/painters/cell_painter.dart';
+import 'package:random/ui/widgets/game/game_score.dart';
+
+class GameBoardWidget extends StatefulWidget {
+  const GameBoardWidget({
+    super.key,
+    required this.game,
+    required this.widgetSize,
+  });
+
+  final Game game;
+  final Size widgetSize;
+
+  @override
+  State<GameBoardWidget> createState() => _GameBoardWidget();
+}
+
+class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMixin {
+  List<List<Animation<double>?>> animations = [];
+
+  void resetAnimations(GameSettings gameSettings) {
+    final boardSize = gameSettings.boardSize;
+
+    animations = List.generate(
+      boardSize,
+      (i) => List.generate(
+        boardSize,
+        (i) => null,
+      ),
+    );
+  }
+
+  void removeCell(BuildContext context, int x, int y) {
+    final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+    final Game updatedGame = gameCubit.state.game ?? Game.createNew();
+
+    // "remove" cell, update counters
+    updatedGame.increaseScore(updatedGame.getCellValue(x, y));
+    updatedGame.increaseMovesCount();
+    updatedGame.updateCellValue(x, y, null);
+    setState(() {});
+
+    // "move down" cells
+    final controller = AnimationController(
+      vsync: this,
+      duration: Duration(milliseconds: 750),
+    )..addListener(() {
+        if (mounted) {
+          setState(() {});
+        }
+      });
+
+    if (mounted) {
+      setState(() {});
+    }
+
+    Animation<double> animation = Tween(
+      begin: 0.0,
+      end: 1.0,
+    ).animate(CurvedAnimation(
+      curve: Curves.bounceOut,
+      parent: controller,
+    ))
+      ..addStatusListener((status) {
+        if (status == AnimationStatus.completed) {
+          // Update cell values
+          for (var i = 0; i < y; i++) {
+            updatedGame.updateCellValue(x, (y - i), updatedGame.getCellValue(x, (y - i) - 1));
+          }
+          updatedGame.setRandomCellValue(x, 0, updatedGame.settings);
+
+          resetAnimations(updatedGame.settings);
+          setState(() {});
+
+          controller.dispose();
+        }
+      });
+
+    for (var i = 0; i < y; i++) {
+      animations[(y - i) - 1][x] = animation;
+    }
+
+    controller.forward().orCancel;
+  }
+
+  Widget buildBoard() {
+    final widgetWidth = widget.widgetSize.width;
+    final widgetHeight = widget.widgetSize.height;
+
+    final rowsCount = widget.game.settings.boardSize;
+    final columnsCount = widget.game.settings.boardSize;
+
+    final cellWidth = widgetWidth / columnsCount;
+    final cellHeight = widgetHeight / rowsCount;
+
+    if (animations.length == 0) {
+      resetAnimations(widget.game.settings);
+    }
+
+    final List<Widget> cells = [];
+
+    for (var y = 0; y < rowsCount; y++) {
+      for (var x = 0; x < columnsCount; x++) {
+        final int? value = widget.game.getCellValue(x, y);
+
+        if (value != null) {
+          final Animation<double>? translation = this.animations[y][x];
+
+          final Widget cellContent = CustomPaint(
+            size: Size(cellWidth, cellHeight),
+            willChange: false,
+            painter: CellPainter(value: value),
+          );
+
+          final Widget cellWidget = Positioned(
+            left: (x * cellWidth).toDouble(),
+            top: ((y + (translation?.value ?? 0)) * cellHeight).toDouble(),
+            child: Container(
+              width: cellWidth,
+              height: cellHeight,
+              child: cellContent,
+            ),
+          );
+
+          cells.add(cellWidget);
+        }
+      }
+    }
+
+    return Container(
+      width: widgetWidth,
+      height: widgetHeight,
+      color: Colors.black,
+      child: Stack(
+        children: cells,
+      ),
+    );
+  }
+
+  Widget interactiveBoard(BuildContext context) {
+    final widgetWidth = widget.widgetSize.width;
+    final widgetHeight = widget.widgetSize.height;
+
+    final rowsCount = widget.game.settings.boardSize;
+    final columnsCount = widget.game.settings.boardSize;
+
+    return GestureDetector(
+      child: buildBoard(),
+      onTapUp: (details) {
+        double xTap = details.localPosition.dx;
+        double yTap = details.localPosition.dy;
+
+        int x = (xTap / widgetWidth * columnsCount).toInt();
+        int y = (yTap / widgetHeight * rowsCount).toInt();
+        print('[' + x.toString() + ',' + y.toString() + ']');
+
+        removeCell(context, x, y);
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        interactiveBoard(context),
+        GameScoreWidget(game: widget.game),
+      ],
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/game_score.dart b/lib/ui/widgets/game/game_score.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e52193c8e551583a9432a22529bf26c705b9424e
--- /dev/null
+++ b/lib/ui/widgets/game/game_score.dart
@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+
+import 'package:random/models/game/game.dart';
+
+class GameScoreWidget extends StatelessWidget {
+  const GameScoreWidget({
+    super.key,
+    required this.game,
+  });
+
+  final Game game;
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: MediaQuery.of(context).size.width,
+      padding: EdgeInsets.all(5),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Text('Settings:'),
+          Text('  board size: ' + this.game.settings.boardSize.toString()),
+          Text('  colors count: ' + this.game.settings.colorsCount.toString()),
+          Text('Game:'),
+          Text('  isRunning: ' + this.game.isRunning.toString()),
+          Text('  isFinished: ' + this.game.isFinished.toString()),
+          Text('  movesCount: ' + this.game.movesCount.toString()),
+          Text('  score: ' + this.game.score.toString()),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/game_settings.dart b/lib/ui/widgets/game/game_settings.dart
new file mode 100644
index 0000000000000000000000000000000000000000..3170c695f5eb4fbb6b6cf8aa1b814c79d0b1420f
--- /dev/null
+++ b/lib/ui/widgets/game/game_settings.dart
@@ -0,0 +1,12 @@
+import 'package:flutter/material.dart';
+
+class GameSettingsWidget extends StatelessWidget {
+  const GameSettingsWidget({
+    super.key,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Text('(fake settings block)');
+  }
+}
diff --git a/lib/ui/widgets/game_board.dart b/lib/ui/widgets/game_board.dart
deleted file mode 100644
index 32e980c2283e14547676784e17deb4a9e37113ff..0000000000000000000000000000000000000000
--- a/lib/ui/widgets/game_board.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:random/models/game_data.dart';
-import 'package:random/ui/painters/cell_painter.dart';
-
-class GameBoardWidget extends StatelessWidget {
-  const GameBoardWidget({
-    super.key,
-    required this.gameData,
-    required this.size,
-    required this.animations,
-  });
-
-  final GameData gameData;
-  final Size size;
-  final List<List<Animation<double>?>> animations;
-
-  @override
-  Widget build(BuildContext context) {
-    final widgetWidth = this.size.width;
-    final widgetHeight = this.size.height;
-
-    final rowsCount = this.gameData.board.length;
-    final columnsCount = this.gameData.board[0].length;
-
-    final cellWidth = widgetWidth / columnsCount;
-    final cellHeight = widgetHeight / rowsCount;
-
-    final List<Widget> cells = [];
-
-    for (var y = 0; y < rowsCount; y++) {
-      for (var x = 0; x < columnsCount; x++) {
-        final GameDataItem item = this.gameData.board[y][x];
-        int? value = item.value;
-
-        if (value != null) {
-          final Animation<double>? translation = this.animations[y][x];
-
-          final Widget cellContent = CustomPaint(
-            size: Size(cellWidth, cellHeight),
-            willChange: false,
-            painter: CellPainter(value: value),
-          );
-
-          final Widget cellWidget = Positioned(
-            left: (x * cellWidth).toDouble(),
-            top: ((y + (translation?.value ?? 0)) * cellHeight).toDouble(),
-            child: Container(
-              width: cellWidth,
-              height: cellHeight,
-              child: cellContent,
-            ),
-          );
-
-          cells.add(cellWidget);
-        }
-      }
-    }
-
-    return Container(
-      width: widgetWidth,
-      height: widgetHeight,
-      color: Colors.black,
-      child: Stack(
-        children: cells,
-      ),
-    );
-  }
-}
diff --git a/pubspec.lock b/pubspec.lock
index 1b5533c24d0cf46bcaad81baa383d40e50b29b70..1505f2f3bab4e02e4b77d1b5d90e487a9eb593e5 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -61,10 +61,10 @@ packages:
     dependency: "direct main"
     description:
       name: dio
-      sha256: "417e2a6f9d83ab396ec38ff4ea5da6c254da71e4db765ad737a42af6930140b7"
+      sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3"
       url: "https://pub.dev"
     source: hosted
-    version: "5.3.3"
+    version: "5.4.0"
   easy_localization:
     dependency: "direct main"
     description:
@@ -148,10 +148,10 @@ packages:
     dependency: transitive
     description:
       name: http
-      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
+      sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
       url: "https://pub.dev"
     source: hosted
-    version: "1.1.0"
+    version: "1.2.0"
   http_parser:
     dependency: transitive
     description:
@@ -164,10 +164,10 @@ packages:
     dependency: "direct main"
     description:
       name: hydrated_bloc
-      sha256: "24994e61f64904d911683cce1a31dc4ef611619da5253f1de2b7b8fc6f79a118"
+      sha256: c925e49704c052a8f249226ae7603f86bfa776b910816390763b956c71d2cbaf
       url: "https://pub.dev"
     source: hosted
-    version: "9.1.2"
+    version: "9.1.3"
   intl:
     dependency: transitive
     description:
@@ -228,26 +228,26 @@ packages:
     dependency: "direct main"
     description:
       name: path_provider
-      sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
+      sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   path_provider_android:
     dependency: transitive
     description:
       name: path_provider_android
-      sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
+      sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.2.2"
   path_provider_foundation:
     dependency: transitive
     description:
       name: path_provider_foundation
-      sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
+      sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.3.2"
   path_provider_linux:
     dependency: transitive
     description:
@@ -260,10 +260,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:
@@ -276,18 +276,18 @@ packages:
     dependency: transitive
     description:
       name: platform
-      sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
+      sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.3"
+    version: "3.1.4"
   plugin_platform_interface:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.7"
+    version: "2.1.8"
   provider:
     dependency: transitive
     description:
@@ -316,10 +316,10 @@ 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:
@@ -332,10 +332,10 @@ packages:
     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:
@@ -377,10 +377,10 @@ packages:
     dependency: transitive
     description:
       name: synchronized
-      sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
+      sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.0"
+    version: "3.1.0+1"
   term_glyph:
     dependency: transitive
     description:
@@ -425,18 +425,18 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f"
+      sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
       url: "https://pub.dev"
     source: hosted
-    version: "5.1.0"
+    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.2.0 <4.0.0"
   flutter: ">=3.16.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index b0d6d8e00aee8565822bbc1ec0a993a2da234550..f5cb7122fe4613e95e7f1b613d540c3af2d7d38e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
 
 publish_to: 'none'
 
-version: 1.0.40+41
+version: 1.0.41+42
 
 environment:
   sdk: '^3.0.0'