2024-06-16 23:56:48 +02:00
|
|
|
import 'dart:async';
|
|
|
|
|
2024-06-19 23:40:31 +02:00
|
|
|
import 'package:bubbletwist/game/stone/triggerable_special_stone.dart';
|
|
|
|
|
2024-06-17 16:24:51 +02:00
|
|
|
import '../enums/stone_color.dart';
|
|
|
|
import 'board.dart';
|
|
|
|
import 'i_game_consumer.dart';
|
|
|
|
import 'stone/stone.dart';
|
|
|
|
import 'stone/stone_location.dart';
|
2024-06-16 23:56:48 +02:00
|
|
|
|
|
|
|
class Game {
|
|
|
|
IGameConsumer gameConsumer;
|
|
|
|
late int timeInSeconds;
|
|
|
|
int startTime = 60; // hardcoded
|
|
|
|
int points = 0;
|
|
|
|
bool running = false;
|
|
|
|
late Board board;
|
|
|
|
late Timer counterTimer;
|
|
|
|
StoneLocation stoneToSwap = StoneLocation(row: -1, column: -1);
|
|
|
|
|
|
|
|
Game(this.gameConsumer) {
|
|
|
|
timeInSeconds = startTime;
|
|
|
|
board = Board(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
int getPoints() => points;
|
|
|
|
|
|
|
|
int getTimeInSeconds() => timeInSeconds;
|
|
|
|
|
|
|
|
void addPoints(int pointsToAdd) {
|
|
|
|
if (timeInSeconds != 0 && running) {
|
|
|
|
points += pointsToAdd;
|
|
|
|
gameConsumer.updatePoints();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void addTime(int timeToAdd) {
|
|
|
|
if (timeInSeconds != 0 && running) {
|
|
|
|
timeInSeconds += timeToAdd;
|
|
|
|
gameConsumer.updateTime();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-19 22:08:49 +02:00
|
|
|
void endGame(bool gameIsCanceled) {
|
2024-06-16 23:56:48 +02:00
|
|
|
running = false;
|
2024-06-17 10:48:31 +02:00
|
|
|
counterTimer.cancel();
|
2024-06-19 22:08:49 +02:00
|
|
|
if (!gameIsCanceled) {
|
|
|
|
gameConsumer.gameStopped();
|
|
|
|
}
|
2024-06-16 23:56:48 +02:00
|
|
|
}
|
|
|
|
|
2024-06-17 10:48:31 +02:00
|
|
|
void countDown() {
|
|
|
|
timeInSeconds--;
|
|
|
|
gameConsumer.updateTime();
|
|
|
|
if (timeInSeconds == 0 && running) {
|
2024-06-19 22:08:49 +02:00
|
|
|
endGame(false);
|
2024-06-16 23:56:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StoneColors? getStoneColor(StoneLocation location) {
|
|
|
|
return board.getStone(location)?.getStoneColor();
|
|
|
|
}
|
|
|
|
|
|
|
|
Stone? getStone(StoneLocation location) {
|
|
|
|
return board.getStone(location);
|
|
|
|
}
|
|
|
|
|
|
|
|
void start() {
|
|
|
|
if (!running) {
|
|
|
|
timeInSeconds = startTime;
|
|
|
|
points = 0;
|
|
|
|
board = Board(this);
|
|
|
|
gameConsumer.updateStones();
|
2024-06-19 22:08:49 +02:00
|
|
|
counterTimer =
|
|
|
|
Timer.periodic(const Duration(seconds: 1), (_) => countDown());
|
2024-06-16 23:56:48 +02:00
|
|
|
gameConsumer.updatePoints();
|
|
|
|
running = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void stop() {
|
|
|
|
if (running) {
|
|
|
|
running = false;
|
|
|
|
timeInSeconds = 0;
|
|
|
|
counterTimer.cancel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool swapStones(StoneLocation sl1, StoneLocation sl2) {
|
|
|
|
return board.swapStones(sl1, sl2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateBoard() {
|
|
|
|
if (running) {
|
|
|
|
gameConsumer.updateStones();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isRunning() => running;
|
|
|
|
|
|
|
|
bool swap(StoneLocation sl) {
|
|
|
|
if (stoneToSwap.row == -1) {
|
|
|
|
stoneToSwap = sl;
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
swapStones(stoneToSwap, sl);
|
|
|
|
stoneToSwap = StoneLocation(row: -1, column: -1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool performSpecialStone(StoneLocation sl) {
|
2024-06-19 23:40:31 +02:00
|
|
|
Stone? s = getStone(sl);
|
2024-06-17 10:48:31 +02:00
|
|
|
if (s is TriggerableSpecialStone) {
|
2024-06-16 23:56:48 +02:00
|
|
|
s.setActivationLocation(sl);
|
|
|
|
board.performSpecialStone(s, sl);
|
|
|
|
return true;
|
2024-06-19 23:40:31 +02:00
|
|
|
}
|
2024-06-16 23:56:48 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|