rp-scrabble
Simple, terminal-based Scrabble game
board.cc
Go to the documentation of this file.
1 
4 #include <iostream>
5 #include "player.h"
6 #include "board.h"
7 #include "tile.h"
8 #include "rack.h"
9 
10 using namespace std;
11 
19 {
20  enum_sqType quarterBoard[7][7] = {
21  { TWS, N, N, DLS, N, N, N },
22  { N, DWS, N, N, N, TLS, N },
23  { N, N, DWS, N, N, N, DLS },
24  { DLS, N, N, DWS, N, N, N },
25  { N, N, N, N, DWS, N, N },
26  { N, TLS, N, N, N, TLS, N },
27  { N, N, DLS, N, N, N, DLS }
28  };
29 
30  enum_sqType strip[7] = {TWS, N, N, DLS, N, N, N};
31 
32  // Top Left quarter
33  for(int i = 0; i < NUM_ROWS/2; i++) {
34  for(int j = 0; j < NUM_COLS/2; j++) {
35  board[i][j] = new Square(quarterBoard[i][j], i, j);
36  }
37  }
38 
39  // Top Right quarter
40  for(int i = 0; i < NUM_ROWS/2; i++) {
41  for(int j = 0; j < NUM_COLS/2; j++) {
42  int j2 = NUM_COLS - 1 - j;
43  board[i][j2] = new Square(quarterBoard[i][j], i, j2);
44  }
45  }
46 
47  // Bottom Left quarter
48  for(int i = 0; i < NUM_ROWS/2; i++) {
49  for(int j = 0; j < NUM_COLS/2; j++) {
50  int i2 = NUM_ROWS - 1 - i;
51  board[i2][j] = new Square(quarterBoard[i][j], i2, j);
52  }
53  }
54 
55  // Bottom Right quarter
56  for(int i = 0; i < NUM_ROWS/2; i++) {
57  for(int j = 0; j < NUM_COLS/2; j++) {
58  int i2 = NUM_ROWS - 1 - i;
59  int j2 = NUM_COLS - 1 - j;
60  board[i2][j2] = new Square(quarterBoard[i][j], i2, j2);
61  }
62  }
63 
64  // Horizontal strips
65  for(int j = 0; j < NUM_COLS/2; j++) {
66  board[NUM_ROWS/2][j] = new Square(strip[j], NUM_ROWS/2, j);
67  }
68 
69  for(int j = NUM_COLS - 1; j > NUM_COLS/2; j--) {
70  board[NUM_ROWS/2][j] = new Square(strip[NUM_COLS - 1 - j], NUM_ROWS/2, j);
71  }
72 
73  // Vertical strips
74  for(int j = 0; j < NUM_ROWS/2; j++) {
75  board[j][NUM_COLS/2] = new Square(strip[j], j, NUM_COLS/2);
76  }
77 
78  for(int j = NUM_ROWS - 1; j > NUM_ROWS/2; j--) {
79  board[j][NUM_COLS/2] = new Square(strip[NUM_ROWS - 1 - j], j, NUM_COLS/2);
80  }
81 
82  // Center
83  board[7][7] = new Square(DWS, 7, 7);
84 
85  // Set neighbours
86  Square* currSquare = nullptr;
87  for(int i = 0; i < NUM_ROWS; i++) {
88  for(int j = 0; j < NUM_COLS; j++) {
89  currSquare = board[i][j];
90  if(j - 1 > -1) {
91  currSquare->setLeft(board[i][j - 1]);
92  }
93  if(j + 1 < NUM_COLS) {
94  currSquare->setRight(board[i][j + 1]);
95  }
96  if(i - 1 > -1) {
97  currSquare->setAbove(board[i - 1][j]);
98  }
99  if(i + 1 < NUM_ROWS) {
100  currSquare->setBelow(board[i + 1][j]);
101  }
102  }
103  }
104 }
105 
110 {
111  for(int i = 0; i < NUM_ROWS; i++) {
112  for(int j = 0; j < NUM_COLS; j++) {
113  delete board[i][j];
114  }
115  }
116 }
117 
122 {
123  string toPrint;
124  Square* currSquare;
125 
126 
127  cout << " "; // 35 spaces
128  for(int k = 0; k < NUM_COLS; k++) {
129  BOARD_COLOURS("+-----");
130  }
131 
132  BOARD_COLOURS("+");
133  cout << "\n";
134 
135  for(int i = 0; i < NUM_ROWS; i++) {
136  if(i < 10) {
137  BOLD_WHITE_FG(" " + to_string(i) + " ");
138  }
139  else {
140  BOLD_WHITE_FG(" " + to_string(i) + " ");
141  }
142 
143  BOARD_COLOURS("| ");
144  for(int j = 0; j < NUM_COLS; j++) {
145  toPrint = " ";
146  currSquare = board[i][j];
147  if(currSquare->isEmpty()) {
148  if(i == 7 && j == 7) {
149  PINK_BG(" ");
150  }
151  else {
152  toPrint = " ";
153  switch(currSquare->getType()) {
154  case 0:
155  BOARD_COLOURS(toPrint);
156  break;
157  case 1:
158  PINK_BG(toPrint);
159  break;
160  case 2:
161  RED_BG(toPrint);
162  break;
163  case 3:
164  LIGHT_BLUE_BG(toPrint);
165  break;
166  case 4:
167  DARK_BLUE_BG(toPrint);
168  break;
169  }
170  }
171  }
172  else {
173  toPrint = " " + currSquare->getTile()->getLetterStr() + " ";
174  TILE_COLOURS(toPrint);
175  }
176  if(j < NUM_COLS - 1) {
177  BOARD_COLOURS(" | ");
178  }
179  }
180  BOARD_COLOURS(" |");
181  cout << "\n";
182  cout << " ";
183  for(int k = 0; k < NUM_COLS; k++) {
184  BOARD_COLOURS("+-----");
185  }
186 
187  BOARD_COLOURS("+");
188  cout << "\n";
189  }
190 
191  BOLD_WHITE_FG(" 0 ");
192  for(int k = 1; k < NUM_COLS; k++)
193  if(k < 10) {
194  BOLD_WHITE_FG(" " + to_string(k) + " ");
195  }
196  else {
197  BOLD_WHITE_FG(" " + to_string(k) + " ");
198  }
199  cout << "\n\n";
200 }
201 
213 bool Board::placeTile(Tile* t, int r, int c)
214 {
215  if(r < 0 || r > NUM_ROWS - 1) {
216  throw string("Invalid row number\n");
217  }
218  else if (c < 0 || c > NUM_COLS - 1) {
219  throw string("Invalid column number\n");
220  }
221  else {
222  Square* curr = board[r][c];
223  if(curr->isEmpty()) {
224  curr->setTile(t);
225  t->setSquare(curr);
226  t->setLoc(2);
227  return true;
228  }
229  else {
230  return false;
231  }
232  }
233 }
234 
246 void Board::placeTileStr(Rack* rack, vector<Tile*> tilesInStr, int r, int c, char dir)
247 {
248  auto it = tilesInStr.begin();
249  int currRow = r;
250  int currCol = c;
251  vector<Tile*> placed;
252  try {
253  while(it != tilesInStr.end()) {
254  if(dir == 'h') {
255  if(placeTile(*it, currRow, currCol++)) {
256  placed.push_back(*it);
257  it++;
258  }
259  }
260  else if(dir == 'v') {
261  if(placeTile(*it, currRow++, currCol)) {
262  placed.push_back(*it);
263  it++;
264  }
265  }
266  else {
267  throw(string("Invalid direction\n"));
268  }
269  }
270  }
271  catch(string err) {
272  int currRow = r;
273  int currCol = c;
274  if(dir == 'h') {
275  for(unsigned long i = 0; i < placed.size(); i++) {
276  rack->addTile(retrieve(currRow, currCol++));
277  }
278  }
279  else if(dir == 'v') {
280  for(unsigned long i = 0; i < placed.size(); i++) {
281  rack->addTile(retrieve(currRow++, currCol));
282  }
283  }
284  for(unsigned long i = placed.size(); i < tilesInStr.size(); i ++) {
285  rack->addTile(tilesInStr[i]);
286  }
287  throw(err + " Because some of the tiles won't fit on the board\n");
288  }
289 }
290 
301 Tile* Board::retrieve(int r, int c)
302 {
303  Tile* t = nullptr;
304  if(!board[r][c]->isEmpty()) {
305  t = board[r][c]->getTile();
306  board[r][c]->setTile(nullptr);
307  }
308  return t;
309 }
310 
321 Square* Board::getSquare(int r, int c)
322 {
323  if(r > -1 && r < NUM_ROWS && c > -1 && c < NUM_COLS) {
324  return board[r][c];
325  }
326  else {
327  throw(string("Square out of bounds\n"));
328  }
329 }
bool placeTile(Tile *t, int r, int c)
Definition: board.cc:213
Tile * retrieve(int r, int c)
Definition: board.cc:301
Board()
Definition: board.cc:18
void placeTileStr(Rack *rack, std::vector< Tile * > tilesInStr, int r, int c, char dir)
Definition: board.cc:246
void show()
Definition: board.cc:121
~Board()
Definition: board.cc:109
Square * getSquare(int r, int c)
Definition: board.cc:321
Definition: rack.h:17
void addTile(Tile *t)
Definition: rack.cc:120
Definition: square.h:30
void setAbove(Square *u)
Definition: square.cc:203
void setBelow(Square *d)
Definition: square.cc:215
int getType()
Definition: square.cc:125
bool isEmpty()
Definition: square.cc:137
void setTile(Tile *t)
Definition: square.cc:155
void setLeft(Square *l)
Definition: square.cc:179
void setRight(Square *r)
Definition: square.cc:191
Tile * getTile()
Definition: square.cc:167
Definition: tile.h:22
void setSquare(Square *s)
Definition: tile.cc:207
std::string getLetterStr()
Definition: tile.cc:109
void setLoc(int loc)
Definition: tile.cc:183
enum_sqType
Definition: square.h:12
@ N
Definition: square.h:14
@ DWS
Definition: square.h:16
@ TWS
Definition: square.h:18
@ TLS
Definition: square.h:22
@ DLS
Definition: square.h:20
void PINK_BG(std::string x)
Definition: utils.h:107
void BOARD_COLOURS(std::string x)
Definition: utils.h:132
void RED_BG(std::string x)
Definition: utils.h:102
void DARK_BLUE_BG(std::string x)
Definition: utils.h:112
#define NUM_COLS
Definition: utils.h:19
#define NUM_ROWS
Definition: utils.h:17
void BOLD_WHITE_FG(std::string x)
Definition: utils.h:72
void TILE_COLOURS(std::string x)
Definition: utils.h:127
void LIGHT_BLUE_BG(std::string x)
Definition: utils.h:117