import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:solitaire/models/game/cell_location.dart'; import 'package:solitaire/models/game/game.dart'; import 'package:solitaire/models/settings/settings_game.dart'; import 'package:solitaire/models/settings/settings_global.dart'; import 'package:solitaire/utils/tools.dart'; part 'game_state.dart'; class GameCubit extends HydratedCubit<GameState> { GameCubit() : super(GameState( currentGame: Game.createEmpty(), )); void updateState(Game game) { emit(GameState( currentGame: game, )); } void refresh() { final Game game = Game( // Settings gameSettings: state.currentGame.gameSettings, globalSettings: state.currentGame.globalSettings, // State isRunning: state.currentGame.isRunning, isStarted: state.currentGame.isStarted, isFinished: state.currentGame.isFinished, animationInProgress: state.currentGame.animationInProgress, // Base data board: state.currentGame.board, // Game data movesCount: state.currentGame.movesCount, remainingPegsCount: state.currentGame.remainingPegsCount, allowedMovesCount: state.currentGame.allowedMovesCount, ); // game.dump(); updateState(game); } void startNewGame({ required GameSettings gameSettings, required GlobalSettings globalSettings, }) { final Game newGame = Game.createNew( // Settings gameSettings: gameSettings, globalSettings: globalSettings, ); newGame.dump(); updateState(newGame); updateRemainingPegsCount(newGame.countRemainingPegs()); updateAllowedMovesCount(newGame.countAllowedMoves()); refresh(); } void quitGame() { state.currentGame.isRunning = false; refresh(); } void resumeSavedGame() { state.currentGame.isRunning = true; refresh(); } void deleteSavedGame() { state.currentGame.isRunning = false; state.currentGame.isFinished = true; refresh(); } void updatePegValue(CellLocation location, bool hasPeg) { state.currentGame.board.cells[location.row][location.col].hasPeg = hasPeg; refresh(); } void incrementMovesCount() { state.currentGame.isStarted = true; state.currentGame.movesCount++; refresh(); } void updateRemainingPegsCount(int count) { state.currentGame.remainingPegsCount = count; refresh(); } void updateAllowedMovesCount(int count) { state.currentGame.allowedMovesCount = count; if (count == 0) { state.currentGame.isFinished = true; } refresh(); } void move({ required Game currentGame, required List<int> source, required List<int> target, }) { printlog('Move from $source to $target'); final int sourceCol = source[0]; final int sourceRow = source[1]; final int targetCol = target[0]; final int targetRow = target[1]; final int middleRow = (sourceRow + ((targetRow - sourceRow) / 2)).round(); final int middleCol = (sourceCol + ((targetCol - sourceCol) / 2)).round(); updatePegValue(CellLocation.go(sourceRow, sourceCol), false); updatePegValue(CellLocation.go(targetRow, targetCol), true); updatePegValue(CellLocation.go(middleRow, middleCol), false); incrementMovesCount(); updateRemainingPegsCount(currentGame.countRemainingPegs()); updateAllowedMovesCount(currentGame.countAllowedMoves()); } @override GameState? fromJson(Map<String, dynamic> json) { final Game currentGame = json['currentGame'] as Game; return GameState( currentGame: currentGame, ); } @override Map<String, dynamic>? toJson(GameState state) { return <String, dynamic>{ 'currentGame': state.currentGame.toJson(), }; } }