import 'package:flutter_custom_toolbox/flutter_toolbox.dart'; import 'package:solitaire/models/game/board.dart'; import 'package:solitaire/models/game/cell.dart'; import 'package:solitaire/models/settings/settings_game.dart'; import 'package:solitaire/models/settings/settings_global.dart'; class Game { Game({ // Settings required this.gameSettings, required this.globalSettings, // State this.isRunning = false, this.isStarted = false, this.isFinished = false, this.animationInProgress = false, // Base data required this.board, // Game data this.movesCount = 0, this.remainingPegsCount = 0, this.allowedMovesCount = 0, }); // Settings final GameSettings gameSettings; final GlobalSettings globalSettings; // State bool isRunning; bool isStarted; bool isFinished; bool animationInProgress; // Base data final Board board; // Game data int movesCount; int remainingPegsCount; int allowedMovesCount; factory Game.createEmpty() { return Game( // Settings gameSettings: GameSettings.createDefault(), globalSettings: GlobalSettings.createDefault(), // Base data board: Board.createEmpty(), ); } factory Game.createNew({ GameSettings? gameSettings, GlobalSettings? globalSettings, }) { final GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault(); final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault(); return Game( // Settings gameSettings: newGameSettings, globalSettings: newGlobalSettings, // State isRunning: true, // Base data board: Board.createNew(gameSettings: newGameSettings), ); } bool get canBeResumed => isStarted && !isFinished; bool get gameWon => isRunning && isStarted && isFinished; int get boardSize => board.boardSize; List<Cell> listRemainingPegs() { final List<Cell> pegs = []; final BoardCells cells = board.cells; for (int rowIndex = 0; rowIndex < cells.length; rowIndex++) { for (int colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) { Cell tile = cells[rowIndex][colIndex]; if (tile.hasPeg == true) { pegs.add(tile); } } } return pegs; } int countRemainingPegs() { return listRemainingPegs().length; } int countAllowedMoves() { int allowedMovesCount = 0; final List<Cell> pegs = listRemainingPegs(); for (Cell tile in pegs) { final int row = tile.location.row; final int col = tile.location.col; final List<int> source = [col, row]; final List<List<int>> targets = [ [col - 2, row], [col + 2, row], [col, row - 2], [col, row + 2], ]; for (List<int> target in targets) { if (board.isMoveAllowed( source: source, target: target, )) { allowedMovesCount++; } } } return allowedMovesCount; } void dump() { printlog(''); printlog('## Current game dump:'); printlog('$Game:'); printlog(' Settings'); gameSettings.dump(); globalSettings.dump(); printlog(' State'); printlog(' isRunning: $isRunning'); printlog(' isStarted: $isStarted'); printlog(' isFinished: $isFinished'); printlog(' animationInProgress: $animationInProgress'); printlog(' Base data'); board.dump(); printlog(' Game data'); printlog(' movesCount: $movesCount'); printlog(' remainingPegsCount: $remainingPegsCount'); printlog(' allowedMovesCount: $allowedMovesCount'); printlog(''); } @override String toString() { return '$Game(${toJson()})'; } Map<String, dynamic>? toJson() { return <String, dynamic>{ // Settings 'gameSettings': gameSettings.toJson(), 'globalSettings': globalSettings.toJson(), // State 'isRunning': isRunning, 'isStarted': isStarted, 'isFinished': isFinished, 'animationInProgress': animationInProgress, // Base data 'board': board.toJson(), // Game data 'movesCount': movesCount, 'remainingPegsCount': remainingPegsCount, 'allowedMovesCount': allowedMovesCount, }; } }