2 * agent++ : A Sample agent for UCC::Progcomp2013
4 * @purpose Definitions for game related classes; Piece, Square, Board
14 * @param new_x, new_y - Position of piece
15 * @param new_colour - Colour of piece
16 * @param type1, type2 - Types of piece
17 * @param index - Index for initial type of piece
19 Piece::Piece(int new_x, int new_y, const string & new_colour, const string & type1, const string & type2, int index)
20 : x(new_x), y(new_y), colour(new_colour), type_index(index), types(), current_type()
22 types[0] = type1; types[1] = type2;
23 if (index < 0 || index >= 2)
25 current_type = "unknown";
29 current_type = types[index];
35 * @param cpy - Piece to copy construct from
37 Piece::Piece(const Piece & cpy) : x(cpy.x), y(cpy.y), colour(cpy.colour), type_index(cpy.type_index)
39 types[0] = cpy.types[0];
40 types[1] = cpy.types[1];
45 * @param choose_types - Indicates whether Board should setup the 2nd types of pieces; default false
47 Board::Board(bool choose_types)
50 // initialise all the Squares
51 for (int x = 0; x < BOARD_WIDTH; ++x)
53 for (int y = 0; y < BOARD_HEIGHT; ++y)
60 // const arrays simplify below code
61 string colours[] = {"black", "white"};
62 string types[] = {"rook", "bishop", "knight", "queen", "pawn"};
64 // frequency of each type of piece
65 map<string, int> freq;
72 // for white and black...
73 for (int i = 0; i < 2; ++i)
75 vector<Piece*> & v = pieces(colours[i]); // get vector of pieces
80 int y = (i == 0) ? 1 : BOARD_HEIGHT-2;
81 for (int x = 0; x < BOARD_WIDTH; ++x)
83 Piece * p = new Piece(x, y, colours[i], "pawn", "unknown");
88 y = (i == 0) ? 0 : BOARD_HEIGHT-1;
89 v.push_back(new Piece(0, y, colours[i], "rook", "unknown"));
90 v.push_back(new Piece(BOARD_WIDTH-1, y, colours[i], "rook", "unknown"));
91 v.push_back(new Piece(1, y, colours[i], "knight", "unknown"));
92 v.push_back(new Piece(BOARD_WIDTH-2, y, colours[i], "knight", "unknown"));
93 v.push_back(new Piece(2, y, colours[i], "bishop", "unknown"));
94 v.push_back(new Piece(BOARD_WIDTH-3, y, colours[i], "bishop", "unknown"));
95 v.push_back(new Piece(3, y, colours[i], "queen", "unknown"));
97 Piece * k = new Piece(4, y, colours[i], "king", "king", 1);
104 // add to board and choose second types if required
105 map<string, int> f(freq);
107 for (unsigned j = 0; j < v.size(); ++j)
110 grid[p->x][p->y].piece = p;
113 if (p->types[1] != "unknown")
119 } while (f[types[type2]] <= 0);
120 f[types[type2]] -= 1;
122 p->types[1] = types[type2];
136 * @param cpy - Board to copy construct from; each Piece in the copy will be *copied*
137 * The Piece's in the copied Board may be altered without affecting the original
139 Board::Board(const Board & cpy)
141 for (int x = 0; x < BOARD_WIDTH; ++x)
143 for (int y = 0; y < BOARD_HEIGHT; ++y)
148 if (cpy.grid[x][y].piece != NULL)
150 grid[x][y].piece = new Piece(*(cpy.grid[x][y].piece));
151 pieces(grid[x][y].piece->colour).push_back(grid[x][y].piece);
164 for (int x = 0; x < BOARD_WIDTH; ++x)
166 for (int y = 0; y < BOARD_HEIGHT; ++y)
168 delete grid[x][y].piece;
175 * @funct Update_select
176 * @purpose Update Piece that has been selected
177 * @param x, y - Position of Piece to update
178 * @param index - 0 or 1 - State the Piece "collapsed" into
179 * @param type - Type of the Piece
181 void Board::Update_select(int x, int y, int index, const string & type)
183 cerr << "Updating " << x << "," << y << " " << grid[x][y].piece << " " << index << " " << type << "\n";
184 Square & s = grid[x][y];
185 assert(s.piece != NULL);
186 assert(index >= 0 && index < 2);
187 s.piece->type_index = index;
188 s.piece->types[index] = type;
189 s.piece->current_type = type;
194 * @purpose Move a Piece from one square to another
195 * @param x1, y1 - Coords of Square containing moving Piece
196 * @param x2, y2 - Coords of Square to move into
197 * NOTE: Any Piece in the destination Square will be destroyed ("taken")
198 * and the Board's other members updated accordingly
200 void Board::Update_move(int x1, int y1, int x2, int y2)
202 Square & s1 = grid[x1][y1];
203 Square & s2 = grid[x2][y2];
204 if (s2.piece != NULL)
206 vector<Piece*> & p = pieces(s2.piece->colour);
207 vector<Piece*>::iterator i = p.begin();
217 Piece * k = king(s2.piece->colour);
220 if (k->colour == "white")
238 * @purpose Get all moves for a Piece and store them
240 * @param v - vector to store Squares in. Will *not* be cleared.
242 void Board::Get_moves(Piece * p, vector<Square*> & v)
244 assert(p->current_type != "unknown");
245 int x = p->x; int y = p->y;
246 if (p->current_type == "king")
252 Move(p, x+1, y+1, v);
253 Move(p, x+1, y-1, v);
254 Move(p, x-1, y+1, v);
255 Move(p, x-1, y-1, v);
257 else if (p->current_type == "knight")
259 Move(p, x+2, y+1, v);
260 Move(p, x+2, y-1, v);
261 Move(p, x-2, y+1, v);
262 Move(p, x-2, y-1, v);
263 Move(p, x+1, y+2, v);
264 Move(p, x-1, y+2, v);
265 Move(p, x+1, y-2, v);
266 Move(p, x-1, y-2, v);
268 else if (p->current_type == "pawn")
270 int y1 = (p->colour == "white") ? BOARD_HEIGHT-2 : 1;
271 int y2 = (p->colour == "white") ? y1 - 2 : y1 + 2;
272 if (p->types[0] == "pawn" && p->y == y1)
277 y2 = (p->colour == "white") ? y - 1 : y + 1;
280 if (Valid_position(x-1, y2) && grid[x-1][y2].piece != NULL)
282 if (Valid_position(x+1, y2) && grid[x+1][y2].piece != NULL)
285 else if (p->current_type == "bishop")
292 else if (p->current_type == "rook")
299 else if (p->current_type == "queen")
315 * @purpose Add a move to the vector, if it is valid
316 * @param p - Piece that would move
317 * @param x, y - Destination Square coords
318 * @param v - vector to put the destination Square in, if the move is valid
320 void Board::Move(Piece * p, int x, int y, vector<Square*> & v)
322 if (Valid_position(x, y) && (grid[x][y].piece == NULL || grid[x][y].piece->colour != p->colour))
324 v.push_back(&(grid[x][y]));
327 // cerr << "Square " << x << "," << y << " invalid; " << grid[x][y].piece << "\n";
332 * @purpose Add moves in a specified direction to the vector, until we get to an invalid move
333 * @param p - Piece to start scanning from
334 * @param vx, vy - "velocity" - change in coords each move
335 * @param v - vector to store valid Squares in
337 void Board::Scan(Piece * p, int vx, int vy, vector<Square*> & v)
341 while (Valid_position(x, y) && (grid[x][y].piece == NULL || grid[x][y].piece->colour != p->colour))
343 v.push_back(&(grid[x][y]));