From 6f0470f530c0c866bf2d29be0fcc275e267885dc Mon Sep 17 00:00:00 2001 From: Lachfrosch Date: Wed, 19 Jun 2024 23:40:31 +0200 Subject: [PATCH] Added Special Stones --- lib/game/board.dart | 37 +++++++++-------- lib/game/game.dart | 6 ++- lib/game/stone/quad_special_stone.dart | 40 +++++++++++++++++++ lib/game/stone/special_stone.dart | 6 ++- lib/game/stone/triggerable_special_stone.dart | 14 +++++++ lib/game/stone/triple_special_stone.dart | 25 ++++++++++++ lib/main.dart | 11 ++++- 7 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 lib/game/stone/quad_special_stone.dart create mode 100644 lib/game/stone/triggerable_special_stone.dart create mode 100644 lib/game/stone/triple_special_stone.dart diff --git a/lib/game/board.dart b/lib/game/board.dart index 99ef9da..a512e06 100644 --- a/lib/game/board.dart +++ b/lib/game/board.dart @@ -1,6 +1,8 @@ import 'dart:math'; +import 'package:bubbletwist/game/stone/quad_special_stone.dart'; import 'package:bubbletwist/game/stone/special_stone.dart'; +import 'package:bubbletwist/game/stone/triple_special_stone.dart'; import '../enums/stone_color.dart'; import 'game.dart'; @@ -11,13 +13,16 @@ import 'stone/stone_location.dart'; class Board { static const int boardSize = 8; final Game game; - late final List> stones = List.generate(boardSize, (i) => List.generate(boardSize, (j) => Stone())); + late final List> stones = + List.generate(boardSize, (i) => List.generate(boardSize, (j) => Stone())); + bool specialStonesEnabled = false; Board(this.game) { // The map generates with pairs of 3+ stones already in place. // To fix that we just let the game remove all 3+ stone pairs until none are left - while (checkBoard()){} + while (checkBoard()) {} } + void updateBoard() { game.updateBoard(); } @@ -99,13 +104,13 @@ class Board { removeStone(st); stuffDeleted = true; } - if (counter == 3 && game.isRunning()) { - //stones[row][startPosition] = TripleSpecialStone(this); + if (counter == 3 && game.isRunning() && specialStonesEnabled) { + stones[row][startPosition] = TripleSpecialStone(this); } - if (counter == 4 && game.isRunning()) { - //stones[row][startPosition] = QuadSpecialStone(this, false); + if (counter == 4 && game.isRunning() && specialStonesEnabled) { + stones[row][startPosition] = QuadSpecialStone(this, false); } - if (counter == 5 && game.isRunning()) { + if (counter == 5 && game.isRunning() && specialStonesEnabled) { stones[row][startPosition] = PentaSpecialStone(this); } } @@ -148,13 +153,13 @@ class Board { removeStone(st); stuffDeleted = true; } - if (counter == 3 && game.isRunning()) { - //stones[startPosition][column] = TripleSpecialStone(this); + if (counter == 3 && game.isRunning() && specialStonesEnabled) { + stones[startPosition][column] = TripleSpecialStone(this); } - if (counter == 4 && game.isRunning()) { - //stones[startPosition][column] = QuadSpecialStone(this, true); + if (counter == 4 && game.isRunning() && specialStonesEnabled) { + stones[startPosition][column] = QuadSpecialStone(this, true); } - if (counter == 5 && game.isRunning()) { + if (counter == 5 && game.isRunning() && specialStonesEnabled) { stones[startPosition][column] = PentaSpecialStone(this); } } @@ -181,7 +186,7 @@ class Board { if (!game.isRunning()) { // If game is not running, just give the stones a new color stones[sl.row][sl.column]!.stoneColor = - StoneColors.values[Random().nextInt(StoneColors.values.length -1)]; + StoneColors.values[Random().nextInt(StoneColors.values.length - 1)]; } else { // Otherwise mark stones as deleted stones[sl.row][sl.column] = null; @@ -209,9 +214,9 @@ class Board { stonesHaveFallenDown); // Continue doing so until all deleted Stones are at the top most position // Then generate new stones that rain from the sky) - for (int i = 0; i < boardSize; i++){ - for (int j = 0; j < boardSize; j++){ - if (stones[i][j] == null){ + for (int i = 0; i < boardSize; i++) { + for (int j = 0; j < boardSize; j++) { + if (stones[i][j] == null) { stones[i][j] = Stone(); } } diff --git a/lib/game/game.dart b/lib/game/game.dart index 3008c37..d6f6de9 100644 --- a/lib/game/game.dart +++ b/lib/game/game.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'package:bubbletwist/game/stone/triggerable_special_stone.dart'; + import '../enums/stone_color.dart'; import 'board.dart'; import 'i_game_consumer.dart'; @@ -108,12 +110,12 @@ class Game { } bool performSpecialStone(StoneLocation sl) { - /*Stone? s = getStone(sl); + Stone? s = getStone(sl); if (s is TriggerableSpecialStone) { s.setActivationLocation(sl); board.performSpecialStone(s, sl); return true; - }*/ + } return false; } } diff --git a/lib/game/stone/quad_special_stone.dart b/lib/game/stone/quad_special_stone.dart new file mode 100644 index 0000000..a0ecc3f --- /dev/null +++ b/lib/game/stone/quad_special_stone.dart @@ -0,0 +1,40 @@ +import 'package:bubbletwist/game/stone/stone_location.dart'; +import 'package:bubbletwist/game/stone/triggerable_special_stone.dart'; + +import '../board.dart'; + +class QuadSpecialStone extends TriggerableSpecialStone { + bool vertical; + + QuadSpecialStone(super.board, this.vertical); + + @override + int getSpecialStoneNumber() { + return 4; + } + + @override + void performSpecialStoneAction() { + StoneLocation sl = StoneLocation(row: 0, column: 0); + if (vertical) { + for (int i = 0; i < Board.boardSize; ++i) { + if (i == row) { + continue; // Skip Stone itself to prevent self deleting + } + sl.row = i; + sl.column = column; + + board.removeStone(sl); + } + } else { + for (int i = 0; i < Board.boardSize; ++i) { + if (i == column) { + continue; // Skip Stone itself to prevent self deleting + } + sl.row = row; + sl.column = i; + board.removeStone(sl); + } + } + } +} diff --git a/lib/game/stone/special_stone.dart b/lib/game/stone/special_stone.dart index 24aa73e..07f775d 100644 --- a/lib/game/stone/special_stone.dart +++ b/lib/game/stone/special_stone.dart @@ -1,10 +1,14 @@ +import 'package:bubbletwist/enums/stone_color.dart'; + import '../board.dart'; import 'stone.dart'; abstract class SpecialStone extends Stone { final Board board; - SpecialStone(this.board); + SpecialStone(this.board) { + setColor(StoneColors.special); + } /// Returns the associated number of the special stone int getSpecialStoneNumber(); diff --git a/lib/game/stone/triggerable_special_stone.dart b/lib/game/stone/triggerable_special_stone.dart new file mode 100644 index 0000000..ab51dec --- /dev/null +++ b/lib/game/stone/triggerable_special_stone.dart @@ -0,0 +1,14 @@ +import 'package:bubbletwist/game/stone/special_stone.dart'; +import 'package:bubbletwist/game/stone/stone_location.dart'; + +abstract class TriggerableSpecialStone extends SpecialStone { + late int row; + late int column; + + TriggerableSpecialStone(super.board); + + void setActivationLocation(StoneLocation sl) { + row = sl.row; + column = sl.column; + } +} diff --git a/lib/game/stone/triple_special_stone.dart b/lib/game/stone/triple_special_stone.dart new file mode 100644 index 0000000..51bd0ca --- /dev/null +++ b/lib/game/stone/triple_special_stone.dart @@ -0,0 +1,25 @@ +import 'package:bubbletwist/game/stone/stone_location.dart'; +import 'package:bubbletwist/game/stone/triggerable_special_stone.dart'; + +class TripleSpecialStone extends TriggerableSpecialStone { + TripleSpecialStone(super.board); + + @override + int getSpecialStoneNumber() { + return 3; + } + + @override + void performSpecialStoneAction() { + // remove stone checks the array bounds + board.removeStone(StoneLocation(row: row + 1, column: column)); + board.removeStone(StoneLocation(row: row + 1, column: column + 1)); + board.removeStone(StoneLocation(row: row + 1, column: column - 1)); + board.removeStone(StoneLocation(row: row, column: column)); + board.removeStone(StoneLocation(row: row, column: column + 1)); + board.removeStone(StoneLocation(row: row, column: column - 1)); + board.removeStone(StoneLocation(row: row - 1, column: column)); + board.removeStone(StoneLocation(row: row - 1, column: column + 1)); + board.removeStone(StoneLocation(row: row - 1, column: column - 1)); + } +} diff --git a/lib/main.dart b/lib/main.dart index 2269a5e..e92f1c3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -360,8 +360,15 @@ class _MyHomePageState extends State implements IGameConsumer { void handleTap(int row, int col) { if (sl1 == null) { - sl1 = StoneLocation(row: row, column: col); - return; + if (game.getStoneColor(StoneLocation(row: row, column: col)) == + StoneColors.special) { + game.performSpecialStone(StoneLocation(row: row, column: col)); + sl1 = null; + return; + } else { + sl1 = StoneLocation(row: row, column: col); + return; + } } else { game.swapStones(sl1!, StoneLocation(row: row, column: col)); sl1 = null;