BlueBubble 1.0
A recommendation algorithm for movies based on a Netlfix database
Loading...
Searching...
No Matches
board.cc
Go to the documentation of this file.
1#include "board.h"
2#include <string>
3
5 last_move(0,0)
6{
9 white_pieces = {};
10 for(int i = 0; i < 8; i++){
11 white_pieces.push_back(new pawn(true,coordinates(i,1)));
12 }
13 white_pieces.push_back(new rook(true,coordinates(0,0)));
14 white_pieces.push_back(new knight(true,coordinates(1,0)));
15 white_pieces.push_back(new bishop(true,coordinates(2,0)));
16 white_pieces.push_back(new queen(true,coordinates(3,0)));
17 white_pieces.push_back(new king(true,coordinates(4,0)));
18 white_pieces.push_back(new bishop(true,coordinates(5,0)));
19 white_pieces.push_back(new knight(true,coordinates(6,0)));
20 white_pieces.push_back(new rook(true,coordinates(7,0)));
21
22 black_pieces = {};
23 for(int i = 0; i < 8; i++){
24 black_pieces.push_back(new pawn(false,coordinates(i,6)));
25 }
26 black_pieces.push_back(new rook(false,coordinates(0,7)));
27 black_pieces.push_back(new knight(false,coordinates(1,7)));
28 black_pieces.push_back(new bishop(false,coordinates(2,7)));
29 black_pieces.push_back(new queen(false,coordinates(3,7)));
30 black_pieces.push_back(new king(false,coordinates(4,7)));
31 black_pieces.push_back(new bishop(false,coordinates(5,7)));
32 black_pieces.push_back(new knight(false,coordinates(6,7)));
33 black_pieces.push_back(new rook(false,coordinates(7,7)));
34
35 // Initialize the board with empty pieces
36 for(int i = 0; i < 8; i++){
37 for(int j = 0; j < 8; j++){
38 board_data[i][j] = nullptr;
39 }
40 }
41
42 // Putting the pieces in place
43 for(int i = 0; i < white_pieces.size(); i++){
44 put(white_pieces[i]);
45 }
46 for(int i = 0; i < black_pieces.size(); i++){
47 put(black_pieces[i]);
48 }
49}
50
53board::board(const board& other):
54 last_move(other.last_move), last_move_en_passant_eligible(other.last_move_en_passant_eligible)
55{
57 white_pieces = {};
58 for(int i = 0; i < other.white_pieces.size(); i++){
59 switch (other.white_pieces[i]->get_type())
60 {
61 case pawn_type:
62 white_pieces.push_back(new pawn(other.white_pieces[i]->get_color(),other.white_pieces[i]->get_coord()));
63 break;
64 case bishop_type:
65 white_pieces.push_back(new bishop(other.white_pieces[i]->get_color(),other.white_pieces[i]->get_coord()));
66 break;
67 case knight_type:
68 white_pieces.push_back(new knight(other.white_pieces[i]->get_color(),other.white_pieces[i]->get_coord()));
69 break;
70 case rook_type:
71 white_pieces.push_back(new rook(other.white_pieces[i]->get_color(),other.white_pieces[i]->get_coord()));
72 break;
73 case queen_type:
74 white_pieces.push_back(new queen(other.white_pieces[i]->get_color(),other.white_pieces[i]->get_coord()));
75 break;
76 case king_type:
77 white_pieces.push_back(new king(other.white_pieces[i]->get_color(),other.white_pieces[i]->get_coord()));
78 break;
79 }
80 }
81 black_pieces = {};
82 for(int i = 0; i < other.black_pieces.size(); i++){
83 switch (other.black_pieces[i]->get_type())
84 {
85 case pawn_type:
86 black_pieces.push_back(new pawn(other.black_pieces[i]->get_color(),other.black_pieces[i]->get_coord()));
87 break;
88 case bishop_type:
89 black_pieces.push_back(new bishop(other.black_pieces[i]->get_color(),other.black_pieces[i]->get_coord()));
90 break;
91 case knight_type:
92 black_pieces.push_back(new knight(other.black_pieces[i]->get_color(),other.black_pieces[i]->get_coord()));
93 break;
94 case rook_type:
95 black_pieces.push_back(new rook(other.black_pieces[i]->get_color(),other.black_pieces[i]->get_coord()));
96 break;
97 case queen_type:
98 black_pieces.push_back(new queen(other.black_pieces[i]->get_color(),other.black_pieces[i]->get_coord()));
99 break;
100 case king_type:
101 black_pieces.push_back(new king(other.black_pieces[i]->get_color(),other.black_pieces[i]->get_coord()));
102 break;
103 }
104 }
105 // Initialize the board with empty pieces
106 for(int i = 0; i < 8; i++){
107 for(int j = 0; j < 8; j++){
108 board_data[i][j] = nullptr;
109 }
110 }
111
112 // Putting the pieces in place
113 for(int i = 0; i < white_pieces.size(); i++){
114 put(white_pieces[i]);
115 }
116 for(int i = 0; i < black_pieces.size(); i++){
117 put(black_pieces[i]);
118 }
119}
120
123void board::put(piece* to_put){
124 coordinates coord = to_put->get_coord();
125 board_data[coord.get_x()][coord.get_y()] = to_put;
126}
127
131 std::cout << std::endl;
132}
133
136void print_line_separator(bool inverted){
137 bool switcher = false;
138 for(int i = 0; i < 8; i++){
140 if((switcher&&!inverted)||(!switcher&&inverted)){
142 }else{
144 }
145 std::cout << " ";
146 switcher = !switcher;
147 }
148}
149
152 std::cout << " a b c d e f g h ";
154 std::cout << " ";
157 bool line_switcher = true;
158 bool column_switcher = false;
159 print_line_separator(!line_switcher);
161 for(int y = 7; y > -1; y--){
163 std::cout << y + 1;
164 std::cout << " ";
165 if(line_switcher){
167 }else{
169 }
170 column_switcher = true;
172 if((line_switcher&&!column_switcher)||(!line_switcher&&column_switcher)){
174 }else{
176 }
177 std::cout << " ";
178 for(int x = 0; x < 8; x++){
179 if(board_data[x][y] == nullptr){
180 std::cout << " ";
181 }else{
182 board_data[x][y]->print_piece();
183 }
184 if(x==7){
185 std::cout << " ";
187 std::cout << " " << y + 1;
189 }else{
190 std::cout << " ";
191 column_switcher = !column_switcher;
192 if((line_switcher&&!column_switcher)||(!line_switcher&&column_switcher)){
194 }else{
196 }
197 std::cout << " ";
198 }
199 }
200 if(y!=0){
202 std::cout << " ";
205 print_line_separator(line_switcher);
207 }
208
209 line_switcher = !line_switcher;
210 }
211 std::cout << " a b c d e f g h " << std::endl;
212 // std::cout << "white:" << std::endl;
213 // for(int i = 0; i < white_pieces.size(); i ++){
214 // white_pieces[i]->canonical_print_piece();
215 // std::cout << " x=" << white_pieces[i]->get_coord().get_x() << " y=" << white_pieces[i]->get_coord().get_y() << std::endl;
216 // }
217 // std::cout << "black:" << std::endl;
218 // for(int i = 0; i < black_pieces.size(); i ++){
219 // black_pieces[i]->canonical_print_piece();
220 // std::cout << " x=" << black_pieces[i]->get_coord().get_x() << " y=" << black_pieces[i]->get_coord().get_y() << std::endl;
221 // }
222}
223
226 for(int y = 0; y < 8; y++){
227 for(int x = 0; x < 8; x++){
228 if(board_data[x][y]!=nullptr){
230 }
231 std::cout << ",";
232 }
233 }
234}
235
239 // Reset the counter
241 bool piece_found = false;
242 for(int i = 0; i < white_pieces.size() && !piece_found; i++){
243 if(white_pieces[i]->get_coord().get_x() == coord.get_x() && white_pieces[i]->get_coord().get_y() == coord.get_y()){
244 piece_found = true;
245 white_pieces.erase(white_pieces.begin() + i);
246 }
247 }
248 for(int i = 0; i < black_pieces.size() && !piece_found; i++){
249 if(black_pieces[i]->get_coord().get_x() == coord.get_x() && black_pieces[i]->get_coord().get_y() == coord.get_y()){
250 piece_found = true;
251 black_pieces.erase(black_pieces.begin() + i);
252 }
253 }
254}
255
259void board::move(coordinates move_from, coordinates move_to){
260 // Increment the counter if not a pawn, else reset it
261 if(board_data[move_from.get_x()][move_from.get_y()]->get_type() == pawn_type){
263 }else{
265 }
266 if(board_data[move_to.get_x()][move_to.get_y()] != nullptr){
267 //Attack case : remove the other piece
268 erase_piece(move_to);
269 }
270 board_data[move_to.get_x()][move_to.get_y()] = board_data[move_from.get_x()][move_from.get_y()];
271 board_data[move_to.get_x()][move_to.get_y()]->move(move_to,false);
272 board_data[move_from.get_x()][move_from.get_y()] = nullptr;
273 last_move.move(move_to);
274 // last_move_en_passant_eligible attribute update if the piece moved is a pawn and it moves 2 cases.
275 last_move_en_passant_eligible = (board_data[move_to.get_x()][move_to.get_y()]->get_type() == pawn_type)&&
276 (abs(move_to.get_y() - move_from.get_y()) == 2);
277}
278
279bool board::is_en_passant_legal(coordinates move_from, coordinates move_to, bool white_move){
280 // We successively check all conditions
281 // First, checking the moving piece type
282 if(board_data[move_from.get_x()][move_from.get_y()]->get_type() != pawn_type){
283 return false;
284 }
285 // The en passant move is the same as the attack one
286 if(!board_data[move_from.get_x()][move_from.get_y()]->is_possible_attack(move_to)){
287 return false;
288 }
289 // The captured piece need to be the last played one, and be en_passant eligible
290 if((last_move.get_x() != move_to.get_x()) || (last_move.get_y() != move_from.get_y()) || !last_move_en_passant_eligible){
291 return false;
292 }
293 // The captured piece need to be one the same x of the destination, and on the same y of the starting point, and the opposite color
294 if(board_data[move_to.get_x()][move_from.get_y()]->get_color() == white_move){
295 return false;
296 }
297 // The captured piece need to be one the same x of the destination, and on the same y of the starting point, and a pawn
298 if(board_data[move_to.get_x()][move_from.get_y()]->get_type() != pawn_type){
299 return false;
300 }
301 return true;
302}
303
309bool board::is_legal(coordinates move_from, coordinates move_to, bool white_move){
310 //Check the move isn't off the board
311 if(move_from.get_x() < 0 || move_from.get_x() > 7 || move_from.get_y() < 0 || move_from.get_y() > 7 ||
312 move_to.get_x() < 0 || move_to.get_x() > 7 || move_to.get_y() < 0 || move_to.get_y() > 7){
313 return false;
314 }
315
316 if(board_data[move_from.get_x()][move_from.get_y()] == nullptr){
317 //Moving from an empty space, wrong move
318 return false;
319 }
320
321 if(board_data[move_from.get_x()][move_from.get_y()]->get_color() != white_move){
322 //Moving a piece that the player isn't owning, wrong move
323 return false;
324 }
325 std::vector<coordinates> empty_check = {};
326 if(board_data[move_to.get_x()][move_to.get_y()] == nullptr){
327 //Destination case is empty
328 if(is_en_passant_legal(move_from,move_to,white_move)){
329 // The en-passant special case, we capture the corresponding pawn
330 erase_piece(coordinates(move_to.get_x(),move_from.get_y()));
331 board_data[move_to.get_x()][move_from.get_y()] = nullptr;
332 }else{
333 if(!board_data[move_from.get_x()][move_from.get_y()]->is_possible(move_to)){
334 // The normal move isn't possible
335 return false;
336 }
337 }
338
339 board_data[move_from.get_x()][move_from.get_y()]->needed_space(move_to, &empty_check);
340
341
342 }else{
343 if(board_data[move_to.get_x()][move_to.get_y()]->get_color() == white_move){
344 //Destination case support a piece of the same color, wrong move
345 return false;
346 }else{
347 //Destination case support a piece of a different color
348 if(!board_data[move_from.get_x()][move_from.get_y()]->is_possible_attack(move_to)){
349 // The attack move isn't possible
350 return false;
351 }
352 board_data[move_from.get_x()][move_from.get_y()]->needed_space(move_to, &empty_check);
353 }
354 }
355 bool result = true;
356 for(int i = 0; i < empty_check.size(); i++){
357 result = result && (board_data[empty_check[i].get_x()][empty_check[i].get_y()] == nullptr);
358 }
359 return result;
360
361}
362
367 int result_y = atoi(&move[1]) - 1;
368 int result_x = 0;
369 std::vector<char> x_traduction = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
370 for(int i = 0; i < 8; i++){
371 if(move[0] == x_traduction[i]){
372 result_x = i;
373 }
374 }
375 return coordinates(result_x,result_y);
376}
377
382 coordinates result (0,0);
383 if(white_king){
384 for(int i = 0; i < white_pieces.size(); i++){
385 if(white_pieces[i]->get_type() == king_type){
386 result = white_pieces[i]->get_coord();
387 }
388 }
389 }else{
390 for(int i = 0; i < black_pieces.size(); i++){
391 if(black_pieces[i]->get_type() == king_type){
392 result = black_pieces[i]->get_coord();
393 }
394 }
395 }
396 return result;
397}
398
402bool board::is_check(bool white_king){
403 bool result = false;
404 if(white_king){
405 for(int i = 0; i < black_pieces.size(); i++){
406 if(black_pieces[i]->get_type() == queen_type){
407 }
408 result = result || is_legal(black_pieces[i]->get_coord(),get_king_coord(white_king),!white_king);
409 }
410 }else{
411 for(int i = 0; i < white_pieces.size(); i++){
412 result = result || is_legal(white_pieces[i]->get_coord(),get_king_coord(white_king),!white_king);
413 }
414 }
415 return result;
416}
417
421bool board::is_king_castling_legal(bool white_move){
422 int y;
423 if(white_move){
424 y = 0;
425 }else{
426 y = 7;
427 }
428 //We first check that the two pieces are in place
429 if(board_data[4][y] == nullptr || board_data[7][y] == nullptr){
430 return false;
431 }
432 //We then check that the two pieces didn't moved. Don't need to check the type since we check they didn't moved
433 if(board_data[4][y]->get_has_moved() || board_data[7][y]->get_has_moved()){
434 return false;
435 }
436 //We then check if there is space to perform the castling
437 return (board_data[5][y] == nullptr) && (board_data[6][y] == nullptr);
438}
439
443bool board::is_queen_castling_legal(bool white_move){
444 int y;
445 if(white_move){
446 y = 0;
447 }else{
448 y = 7;
449 }
450 //We first check that the two pieces are in place
451 if(board_data[4][y] == nullptr || board_data[0][y] == nullptr){
452 return false;
453 }
454 //We then check that the two pieces didn't moved
455 if(board_data[4][y]->get_has_moved() || board_data[0][y]->get_has_moved()){
456 return false;
457 }
458 //We then check if there is space to perform the castling
459 return (board_data[1][y] == nullptr) && (board_data[2][y] == nullptr) && (board_data[3][y] == nullptr);
460}
461
464void board::king_castle(bool white_move){
465 int y;
466 if(white_move){
467 y = 0;
468 }else{
469 y = 7;
470 }
471 move(coordinates(4,y),coordinates(6,y));
472 move(coordinates(7,y),coordinates(5,y));
473}
474
477void board::queen_castle(bool white_move){
478 int y;
479 if(white_move){
480 y = 0;
481 }else{
482 y = 7;
483 }
484 move(coordinates(4,y),coordinates(2,y));
485 move(coordinates(0,y),coordinates(3,y));
486}
487
488
489
493void board::promote(coordinates to_promote, piece_type new_type){
494 bool color = board_data[to_promote.get_x()][to_promote.get_y()]->get_color();
495 erase_piece(to_promote);
496 if(color){
497 switch (new_type)
498 {
499 case rook_type:
500 white_pieces.push_back(new rook(color,to_promote));
501 break;
502 case bishop_type:
503 white_pieces.push_back(new bishop(color,to_promote));
504 break;
505 case knight_type:
506 white_pieces.push_back(new knight(color,to_promote));
507 break;
508 case queen_type:
509 white_pieces.push_back(new queen(color,to_promote));
510 break;
511 }
512 //Put the newly added piece on the board
513 put(white_pieces[white_pieces.size() - 1]);
514 }else{
515 switch (new_type)
516 {
517 case rook_type:
518 black_pieces.push_back(new rook(color,to_promote));
519 break;
520 case bishop_type:
521 black_pieces.push_back(new bishop(color,to_promote));
522 break;
523 case knight_type:
524 black_pieces.push_back(new knight(color,to_promote));
525 break;
526 case queen_type:
527 black_pieces.push_back(new queen(color,to_promote));
528 break;
529 }
530 //Put the newly added piece on the board
531 put(black_pieces[black_pieces.size() - 1]);
532 }
533
534}
535
540 return((board_data[coord.get_x()][coord.get_y()]->get_type() == pawn_type) && ((coord.get_y() == 0)||(coord.get_y() == 7)));
541}
542
546bool board::is_checkmate_or_pat(bool white_move){
547 // 50 moves rule
549 return true;
550 }
551 bool result = true;
552 // The copy of the copy
553 board *chess_board_copy;
554 // A check board copy
555 board *chess_board;
556 coordinates start(0,0);
557 coordinates end(0,0);
558 if(white_move){
559 for(int i = 0; i < black_pieces.size(); i++){
560 // For each piece, we test all moves
561 // We don't have to check the castling moves because they're unauthorized when in a check state
562 for(int j = 0; j < black_pieces[i]->get_legals().size(); j++){
563 // For a move, we check if it's still in check
564 chess_board = new board(*this);
565 start.move(black_pieces[i]->get_coord());
566 // Simulate a movement
567 end.move(coordinates(black_pieces[i]->get_coord().get_x() + black_pieces[i]->get_legals()[j].get_x(),
568 black_pieces[i]->get_coord().get_y() + black_pieces[i]->get_legals()[j].get_y()));
569 if(chess_board->is_legal(start,end,!white_move)){
570 //Apply the movement on a chess board copy and verify the check state of the current player's king
571 chess_board_copy = new board(*chess_board);
572 chess_board_copy->move(start,end);
573 if(chess_board_copy->is_check(!white_move)){
574 //The move is making the active player in check state, illegal
575 }else{
576 //The move is legal and the player isn't in check, therefore it isn't a checkmate.
577 result = false;
578 }
579 delete chess_board_copy;
580 }
581 delete chess_board;
582 }
583 }
584 }else{
585 for(int i = 0; i < white_pieces.size(); i++){
586 // For each piece, we test all moves
587 // We don't have to check the castling moves because they're unauthorized when in a check state
588 for(int j = 0; j < white_pieces[i]->get_legals().size(); j++){
589 // For a move, we check if it's still in check
590 chess_board = new board(*this);
591 start.move(white_pieces[i]->get_coord());
592 // Simulate a movement
593 end.move(coordinates(white_pieces[i]->get_coord().get_x() + white_pieces[i]->get_legals()[j].get_x(),
594 white_pieces[i]->get_coord().get_y() + white_pieces[i]->get_legals()[j].get_y()));
595 if(chess_board->is_legal(start,end,!white_move)){
596 //Apply the movement on a chess board copy and verify the check state of the current player's king
597 chess_board_copy = new board(*chess_board);
598 chess_board_copy->move(start,end);
599 if(chess_board_copy->is_check(!white_move)){
600 //The move is making the active player in check state, illegal
601 }else{
602 //The move is legal and the player isn't in check, therefore it isn't a checkmate.
603 result = false;
604 }
605 delete chess_board_copy;
606 }
607 delete chess_board;
608 }
609 }
610 }
611 return result;
612}
void print_neutral_endl()
print a neutral font color and background color new line
Definition board.cc:129
coordinates get_coord_from_string(std::string move)
Retrieve coordinates from a string.
Definition board.cc:366
void print_line_separator(bool inverted)
print a line separator with board matching background colors
Definition board.cc:136
void print_neutral_endl()
print a neutral font color and background color new line
Definition board.cc:129
void print_line_separator(bool inverted)
print a line separator with board matching background colors
Definition board.cc:136
the bishop piece class.
Definition bishop.h:9
A class representing the chess board.
Definition board.h:19
bool is_promotion_needed(coordinates coord)
check if a promotion is needed
Definition board.cc:539
std::vector< piece * > black_pieces
Definition board.h:23
void canonical_print()
print the board in canonical form
Definition board.cc:225
bool is_check(bool white_king)
check if the selected player is in check state
Definition board.cc:402
board()
Definition board.cc:4
bool is_king_castling_legal(bool white_move)
check if the king-side castling move is legal, without checking it in regards to king check state
Definition board.cc:421
bool is_checkmate_or_pat(bool white_move)
check if the other player can move without being in a check state
Definition board.cc:546
bool is_legal(coordinates move_from, coordinates move_to, bool white_move)
Check if a move is legal, without checking it in regards to king check state.
Definition board.cc:309
void print()
print the board
Definition board.cc:151
piece * board_data[8][8]
Definition board.h:21
bool is_queen_castling_legal(bool white_move)
check if the queen-side castling move is legal, without checking it in regards to king check state
Definition board.cc:443
void move(coordinates move_from, coordinates move_to)
Move a piece from one position to another, supposing that the move is legal.
Definition board.cc:259
void king_castle(bool white_move)
perform the king-side castling move
Definition board.cc:464
void erase_piece(coordinates coord)
Erase a piece from its corresponding vector according to its coordinates.
Definition board.cc:238
bool is_en_passant_legal(coordinates move_from, coordinates move_to, bool white_move)
Definition board.cc:279
bool last_move_en_passant_eligible
Definition board.h:25
void put(piece *to_put)
put a piece onto the board according to its coordinates
Definition board.cc:123
void promote(coordinates to_promote, piece_type new_type)
Perform a promotion on the specified coordinates. Don't check anything.
Definition board.cc:493
coordinates get_king_coord(bool white_king)
retrieve the king coordinates
Definition board.cc:381
void queen_castle(bool white_move)
perform the queen-side castling move
Definition board.cc:477
int without_attack_or_pawn_counter
Definition board.h:26
coordinates last_move
Definition board.h:24
std::vector< piece * > white_pieces
Definition board.h:22
a class representing coordinates
Definition coordinates.h:5
int get_x()
a function to get the x-axis attribute
Definition coordinates.cc:6
int get_y()
a function to get the y-axis attribute
void move(coordinates move_to)
change the coordinate values to move the associated piece
the king piece class.
Definition king.h:9
the knight piece class.
Definition knight.h:9
the pawn piece class.
Definition pawn.h:9
a generic piece class. white is a boolean indicating the piece's color. legals is a vector indicating...
Definition piece.h:11
bool is_possible(coordinates dest)
verify if a move is within piece range
Definition piece.cc:18
bool get_color()
retrieve the piece's color
Definition piece.cc:79
virtual void move(coordinates dest, bool debug_info)
called to move the piece
Definition piece.cc:57
virtual bool is_possible_attack(coordinates dest)
verify if a move is within piece attack range
Definition piece.cc:29
piece_type get_type()
retrieve the piece's type
Definition piece.cc:91
coordinates get_coord()
retrieve the piece's coordinates
Definition piece.cc:73
virtual void canonical_print_piece()
print the piece to the standard output in canonical form
Definition piece.cc:50
virtual void print_piece()
print the piece to the standard output
Definition piece.cc:45
virtual void needed_space(coordinates dest, std::vector< coordinates > *to_calculate)
calculate the space needed for the piece to move
Definition piece.cc:40
the queen piece class.
Definition queen.h:9
the rook piece class.
Definition rook.h:9
#define BACKGROUND_COLOR2
Definition config.h:9
#define BACKGROUND_COLOR1
Definition config.h:8
#define PIECES_COLOR
Definition config.h:10
piece_type
Represent a piece type. Undefined for default piece.
Definition piece.h:8
@ knight_type
Definition piece.h:8
@ queen_type
Definition piece.h:8
@ king_type
Definition piece.h:8
@ rook_type
Definition piece.h:8
@ pawn_type
Definition piece.h:8
@ bishop_type
Definition piece.h:8
void terminal_reset_all()
reset all terminal attributes
Definition utilities.cc:79
void terminal_set_background_color(terminal_color color)
set the terminal background color to the input
Definition utilities.cc:48
void terminal_set_text_color(terminal_color color)
set the terminal font color to the input
Definition utilities.cc:16