Select Git revision
game_cubit.dart
-
Benoît Harrault authoredBenoît Harrault authored
game_cubit.dart 4.12 KiB
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:jeweled/models/game.dart';
import 'package:jeweled/models/cell_location.dart';
import 'package:jeweled/models/game_settings.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(
board: state.currentGame.board,
settings: state.currentGame.settings,
isRunning: state.currentGame.isRunning,
isFinished: state.currentGame.isFinished,
availableBlocksCount: state.currentGame.availableBlocksCount,
movesCount: state.currentGame.movesCount,
score: state.currentGame.score,
);
// game.dump();
updateState(game);
}
void quitGame() {
state.currentGame.updateGameIsRunning(false);
refresh();
}
void updateCellValue(CellLocation locationToUpdate, int? value) {
state.currentGame.updateCellValue(locationToUpdate, value);
refresh();
}
void increaseMovesCount() {
this.state.currentGame.increaseMovesCount();
refresh();
}
void increaseScore(int increment) {
this.state.currentGame.increaseScore(increment);
refresh();
}
void updateAvailableBlocksCount() {
this.state.currentGame.updateAvailableBlocksCount();
refresh();
}
void updateGameIsFinished(bool gameIsFinished) {
this.state.currentGame.updateGameIsFinished(gameIsFinished);
refresh();
}
moveCellsDown() {
final Game currentGame = this.state.currentGame;
final int boardSizeHorizontal = currentGame.settings.boardSize;
final int boardSizeVertical = currentGame.settings.boardSize;
for (int row = 0; row < boardSizeVertical; row++) {
for (int col = 0; col < boardSizeHorizontal; col++) {
// empty cell?
if (currentGame.getCellValue(CellLocation.go(row, col)) == null) {
// move cells down
for (int r = row; r > 0; r--) {
this.updateCellValue(CellLocation.go(r, col),
currentGame.getCellValue(CellLocation.go(r - 1, col)));
}
// fill top empty cell
this.updateCellValue(
CellLocation.go(0, col), currentGame.getFillValue(CellLocation.go(row, col)));
}
}
}
}
void deleteBlock(List<CellLocation> block) {
// Sort cells from top to bottom
block.sort((cell1, cell2) => cell1.row.compareTo(cell2.row));
// Delete all cells
block.forEach((CellLocation blockItemToDelete) {
this.updateCellValue(blockItemToDelete, null);
});
}
int getScoreFromBlock(int blockSize) {
return 3 * (blockSize - 2);
}
List<CellLocation> tapOnCell(CellLocation tappedCellLocation) {
final Game currentGame = this.state.currentGame;
final int? cellValue = currentGame.getCellValue(tappedCellLocation);
if (cellValue != null) {
List<CellLocation> blockCells = currentGame.getSiblingCells(tappedCellLocation, []);
if (blockCells.length >= 3) {
this.deleteBlock(blockCells);
this.increaseMovesCount();
this.increaseScore(getScoreFromBlock(blockCells.length));
return blockCells;
}
}
return [];
}
void postAnimate() {
this.moveCellsDown();
this.updateAvailableBlocksCount();
refresh();
if (!this.state.currentGame.hasAtLeastOneAvailableBlock()) {
print('no more block found. finish game.');
this.updateGameIsFinished(true);
}
}
void startNewGame(GameSettings settings) {
Game newGame = Game.createNew(
gameSettings: settings,
);
newGame.dump();
updateState(newGame);
this.postAnimate();
}
@override
GameState? fromJson(Map<String, dynamic> json) {
Game currentGame = json['currentGame'] as Game;
return GameState(
currentGame: currentGame,
);
}
@override
Map<String, dynamic>? toJson(GameState state) {
return <String, dynamic>{
'currentGame': state.currentGame.toJson(),
};
}
}