Select Git revision
game_cubit.dart
-
Benoît Harrault authoredBenoît Harrault authored
game_cubit.dart 4.20 KiB
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:memory/models/game/game.dart';
import 'package:memory/models/settings/settings_game.dart';
import 'package:memory/models/settings/settings_global.dart';
part 'game_state.dart';
class GameCubit extends HydratedCubit<GameState> {
GameCubit()
: super(GameState(
currentGame: Game.createNull(),
));
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,
shufflingInProgress: state.currentGame.shufflingInProgress,
// Base data
board: state.currentGame.board,
// Game data
guessesCount: state.currentGame.guessesCount,
pairsFound: state.currentGame.pairsFound,
);
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);
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 allowInteractions(bool active) {
state.currentGame.animationInProgress = !active;
refresh();
}
void unselectAllTiles() {
for (int i = 0; i < state.currentGame.board.tiles.length; i++) {
state.currentGame.board.tiles[i].selected = false;
}
refresh();
}
void markTilesAsPaired(List<int> tilesIndexes) {
for (int i = 0; i < tilesIndexes.length; i++) {
state.currentGame.board.tiles[tilesIndexes[i]].paired = true;
}
refresh();
}
void tapOnTile(int tileIndex) {
// Already selected? -> skip
if (state.currentGame.board.tiles[tileIndex].selected) {
return;
}
// Already paired? -> skip
if (state.currentGame.board.tiles[tileIndex].paired) {
return;
}
// Flip selected tile
state.currentGame.board.tiles[tileIndex].selected = true;
refresh();
// Is first tile selected?
List<int> selectedTilesIndexes = [];
for (int i = 0; i < state.currentGame.board.tiles.length; i++) {
if (state.currentGame.board.tiles[i].selected) {
selectedTilesIndexes.add(i);
}
}
if (selectedTilesIndexes.length >= 2) {
allowInteractions(false);
// does all selected tiles have same value?
bool hasSameValue = true;
for (int i = 1; i < selectedTilesIndexes.length; i++) {
if (state.currentGame.board.tiles[selectedTilesIndexes[i]].value !=
state.currentGame.board.tiles[selectedTilesIndexes[i - 1]].value) {
hasSameValue = false;
}
}
state.currentGame.guessesCount++;
refresh();
// timer + check pair + unselect
Timer(const Duration(seconds: 2), () {
if (hasSameValue) {
markTilesAsPaired(selectedTilesIndexes);
final int itemValue = state.currentGame.board.tiles[selectedTilesIndexes[0]].value;
state.currentGame.pairsFound.add(itemValue);
refresh();
}
state.currentGame.isFinished = state.currentGame.gameWon;
refresh();
unselectAllTiles();
allowInteractions(true);
});
}
}
@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(),
};
}
}