-
Notifications
You must be signed in to change notification settings - Fork 1
/
Board.h
171 lines (140 loc) · 4.11 KB
/
Board.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//
// Created by Mitchell on 6/6/2021.
//
#ifndef FLOODIT_AI_BOARD_H
#define FLOODIT_AI_BOARD_H
#include <chrono>
#include <iostream>
class Board
{
private:
int width;
int height;
int colourCount;
int **grid;
public:
/* Initialise */
Board(int seed = -1, int colours = 6, int w = 20, int h = 20);
/* Game Functionality */
bool outOfBounds(int row, int col);
bool isValidMove(int row, int col, int colour);
bool makeMove(int row, int col, int colour);
void floodFill(int row, int col, int initialColour, int newColour);
bool checkWin();
/* Output */
void print();
/* Getters */
int getWidth()
{ return width; }
int getHeight()
{ return height; }
int getColourCount()
{ return colourCount; }
int **getGrid()
{ return grid; }
};
/* == Board::Board ==
* Initialises the board to state as determined by the seed (or random if seed==-1).
*/
Board::Board(int seed, int colours, int w, int h)
{
// Init props
width = w;
height = h;
colourCount = colours;
// Initialise seed
if (seed == -1) seed = time(NULL);
srand(seed);
// Initialise the grid randomly
grid = new int *[height];
for (int row = 0; row < height; row++)
{
grid[row] = new int[width];
for (int col = 0; col < width; col++)
{
grid[row][col] = rand() % colours;
}
}
}
/* == Board::outOfBounds ==
* Returns true if the given position is out of bounds on the board, returns false otherwise.
*/
bool Board::outOfBounds(int row, int col)
{
return row < 0 || col < 0 || row >= height || col >= width;
}
/* == Board::isValidMove ==
* Returns true if the given move is valid on the board.
* False if;
* -- the move is out of bounds OR
* -- the position given is already the specified colour
*/
bool Board::isValidMove(int row, int col, int colour)
{
return !outOfBounds(row, col) && grid[row][col] != colour;
}
/* == Board::makeMove ==
* Makes the given move on the board.
* row, col: position on the board
* colour: the NEW colour
*
* Returns true if the move was legal and successful.
* Returns false if the move was illegal or unsuccessful.
* -- Example: The colour of the grid at [row][col] cannot match colour - the move must make some meaningful change to the board
* -- OR: The move was out of bounds.
*/
bool Board::makeMove(int row, int col, int colour)
{
// Player made an invalid move
if (!isValidMove(row, col, colour)) return false;
floodFill(row, col, grid[row][col], colour);
return true;
}
/* == Board::floodFill ==
* Flood fills from the specified position with the specified colour.
*
* Uses taxicab geometry - i.e., up, down, left, right are the only neighbours of a cell (distance 1 from the cell)
* https://en.wikipedia.org/wiki/Taxicab_geometry
*/
void Board::floodFill(int row, int col, int initialColour, int newColour)
{
// Only flood to neighbours squares of the initial colour (and are not out of bounds)
if (outOfBounds(row, col) || grid[row][col] != initialColour) return;
grid[row][col] = newColour; // Fills the cell
// For simplicity's sake:
floodFill(row - 1, col, initialColour, newColour); // up
floodFill(row, col + 1, initialColour, newColour); // right
floodFill(row + 1, col, initialColour, newColour); // down
floodFill(row, col - 1, initialColour, newColour); // left
}
/* == Board::checkWin ==
* Returns true if the board is in the win state, false otherwise.
* Win state is defined as the whole board being a uniform colour.
*/
bool Board::checkWin()
{
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
if (grid[row][col] != grid[0][0]) return false;
}
}
return true;
}
// TODO update print
/* == Board::print ==
*
* Prints the board to the screen. Feel free to modify this as you wish.
*/
void Board::print()
{
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{ std::cout << grid[row][col]; }
std::cout << "\n";
}
std::cout << "\n";
}
#endif //FLOODIT_AI_BOARD_H