Jeu d'échec
 
Loading...
Searching...
No Matches
echiquier.cpp
Go to the documentation of this file.
1#include "echiquier.hpp"
2#include "pieces/tour.hpp"
3#include "pieces/cavalier.hpp"
4#include "pieces/fou.hpp"
5#include "pieces/reine.hpp"
6#include "pieces/roi.hpp"
7#include "pieces/pion.hpp"
8#include <iostream>
9#include <algorithm>
10
11class Piece;
12
14{
15 for (auto & row : board)
16 {
17 for (auto & col : row)
18 {
19 col = nullptr;
20 }
21 }
22
23 is_check = false;
24
25 pieces[WHITE] = {
26 new Tour("\u2656", "R", WHITE, 0, Square(0, 0), this),
27 new Cavalier("\u2658", "N", WHITE, 1, Square(0, 1), this),
28 new Fou("\u2657", "B", WHITE, 2, Square(0, 2), this),
29 new Reine("\u2655", "Q", WHITE, 3, Square(0, 3), this),
30 new Roi("\u2654", "K", WHITE, 4, Square(0, 4), this),
31 new Fou("\u2657", "B", WHITE, 5, Square(0, 5), this),
32 new Cavalier("\u2658", "N", WHITE, 6, Square(0, 6), this),
33 new Tour("\u2656", "R", WHITE, 7, Square(0, 7), this)};
34
35 pieces[BLACK] = {
36 new Tour("\u265C", "R", BLACK, 0, Square(7, 0), this),
37 new Cavalier("\u265E", "N", BLACK, 1, Square(7, 1), this),
38 new Fou("\u265D", "B", BLACK, 2, Square(7, 2), this),
39 new Reine("\u265B", "Q", BLACK, 3, Square(7, 3), this),
40 new Roi("\u265A", "K", BLACK, 4, Square(7, 4), this),
41 new Fou("\u265D", "B", BLACK, 5, Square(7, 5), this),
42 new Cavalier("\u265E", "N", BLACK, 6, Square(7, 6), this),
43 new Tour("\u265C", "R", BLACK, 7, Square(7, 7), this)};
44
45 for (int i = 0; i < 8; i++)
46 {
47 pieces[WHITE].push_back(new Pion("\u2659", "P", WHITE, 8 + i, Square(1, i), this));
48 pieces[BLACK].push_back(new Pion("\u265F", "P", BLACK, 8 + i, Square(6, i), this));
49 }
50}
51
52bool Echiquier::castling(Color player, bool big){
53 Roi* roi = dynamic_cast<Roi *>(get_piece_from_id(4, player));
54 Tour* tour = dynamic_cast<Tour *>(get_piece_from_id(big ? 0 : 7, player));
55 Square roiPos = roi->get_pos();
56 Square tourPos = tour->get_pos();
57 if(check_castling(player, big)){
58 set_pos(nullptr, roiPos);
59 set_pos(nullptr, tourPos);
60 if(big){
61 set_pos(roi, Square(player == WHITE ? 0 : 7, 2));
62 set_pos(tour, Square(player == WHITE ? 0 : 7, 3));
63 }else{
64 set_pos(roi, Square(player == WHITE ? 0 : 7, 6));
65 set_pos(tour, Square(player == WHITE ? 0 : 7, 5));
66 }
67 return true;
68 }
69 return false;
70}
71
72bool Echiquier::check_castling(Color player, bool big) const {
73 Roi* roi = dynamic_cast<Roi*>(get_piece_from_id(4, player));
74 Tour* tour = dynamic_cast<Tour*>(get_piece_from_id(big ? 0 : 7, player));
75 if(is_check) return false;
76 if(big){
77 if(get_piece(Square(player == WHITE ? 0 : 7, 1)) == nullptr
78 && get_piece(Square(player == WHITE ? 0 : 7, 2)) == nullptr
79 && get_piece(Square(player == WHITE ? 0 : 7, 3)) == nullptr
80 && !check_check(player, Square(player == WHITE ? 0 : 7, 1))
81 && !check_check(player, Square(player == WHITE ? 0 : 7, 2))
82 && !check_check(player, Square(player == WHITE ? 0 : 7, 3))) {
83 return !roi->get_has_moved() && !tour->get_has_moved();
84 }
85 return false;
86 }
87
88 if(get_piece(Square(player == WHITE ? 0 : 7, 5)) == nullptr
89 && get_piece(Square(player == WHITE ? 0 : 7, 6)) == nullptr
90 && !check_check(player, Square(player == WHITE ? 0 : 7, 5))
91 && !check_check(player, Square(player == WHITE ? 0 : 7, 6))) {
92 return !roi->get_has_moved() && !tour->get_has_moved();
93 }
94 return false;
95}
96
98 auto &vec = pieces[player];
99 auto it = std::find_if(vec.begin(), vec.end(), [id](const Piece* piece) {
100 return piece->get_id() == id;
101 });
102 if(it != vec.end()) return *it;
103 return nullptr;
104}
105
106bool Echiquier::check_check(Color player, Square pos, Piece* exclude) const {
107 for(int row = 0; row < 8; row++){
108 for(int col = 0; col < 8; col++){
109 Piece* piece = get_piece(Square(row, col));
110 if(piece == nullptr) continue;
111 if(piece->get_color() == player) continue;
112 if(piece->est_menace(Square(row,col), pos)){
113 return true;
114 }
115 }
116 }
117
118 return false;
119}
120
122{
123 std::string output;
124 for (int row = 0; row <= 7; row++)
125 {
126 for (int col = 0; col <= 7; col++)
127 {
128 auto piece = get_piece(Square(row, col));
129 output += (piece == nullptr ? "" : piece->canonical(true, true)) + ",";
130 }
131 }
132 return output;
133}
134
136{
137 std::cout << " a b c d e f g h " << std::endl;
138 std::cout << "┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐" << std::endl;
139
140 for (int row = 7; row >= 0; row--)
141 {
142 if (row != 7) std::cout << "├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤" << std::endl;
143 std::cout << "│";
144 for (int col = 0; col <= 7; col++)
145 {
146 Piece *piece = get_piece(Square(row, col));
147 std::cout << " " << ((piece == nullptr) ? " " : piece->get_name()) << " │";
148 }
149 std::cout << " " << row + 1 << std::endl;
150 }
151
152 std::cout << "└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘" << std::endl;
153}
154
155bool Echiquier::check_move(Square from, Square to, Color player) {
156
157 Piece *piece = get_piece(from);
158 if (piece == nullptr) return false;
159 if (!piece->est_mouvement_legal(from, to)) return false;
160
161 bool flag = true;
162 // On copie l'échiquier actuel dans un autre échiquier
163 Piece *old_board[8][8];
164
165 for(int i = 0; i < 8; i++){
166 std::copy_n(board[i], 8, old_board[i]);
167 }
168
169 set_pos(nullptr, from);
170 set_pos(piece, to);
171
172 // On vérifie si le roi va être mis en échec
173 Roi* roi_player = dynamic_cast<Roi*>(get_piece_from_id(4, player));
174
175 if(roi_player != nullptr) {
176 Square pos_roi = roi_player->get_pos();
177 if(check_check(player, pos_roi)){
178 flag = false;
179 }
180 }
181
182 // On remet l'échiquier à sa situation d'avant
183
184 piece->set_pos(from);
185 for(int i = 0; i < 8; i++){
186 std::copy_n(old_board[i], 8, board[i]);
187 }
188
189 return flag;
190}
191
193 return check_stalemate(player) && is_check;
194}
195
197 auto vect = pieces[player];
198 for (Piece *piece : vect) {
199 if(!piece->get_is_active()) continue;
200 for (int i = 0; i < 8; ++i) {
201 for (int j = 0; j < 8; ++j) {
202 if (check_move(piece->get_pos(), Square(i,j), player)) {
203 return false;
204 }
205 }
206 }
207 }
208
209 return true;
210}
211
212
213bool Echiquier::move(Square from, Square to, Color player)
214{
215 Piece *piece = get_piece(from);
216 Piece *old_piece = get_piece(to);
217
218 if (piece == nullptr) return false;
219 if (!check_move(from, to, player)) return false;
220
221 set_pos(nullptr, from);
222 set_pos(piece, to);
223
224 piece->move_event(from);
225
226 // Le roi de celui qui joue n'est plus en échec après avoir joué son coup
227 Roi* roi_player = dynamic_cast<Roi*>(get_piece_from_id(4, player));
228
229 if (roi_player != nullptr && is_check) {
230 roi_player->set_is_checked(false);
231 set_is_check(false);
232 }
233
234 // On vérifie si le roi ennemi est mis en échec.
235 Roi* roi_ennemi = dynamic_cast<Roi*>(get_piece_from_id(4, player == WHITE ? BLACK : WHITE));
236 if (check_check(player == WHITE ? BLACK : WHITE, roi_ennemi->get_pos())) {
237 roi_ennemi->set_is_checked(true);
238 set_is_check(true);
239 }
240
241 // On mange la pièce s'il y en avait une
242 if (old_piece != nullptr) old_piece->set_is_active(false);
243 moves.emplace_back(*piece, from, to);
244 return true;
245}
246
248{
249 for (auto piece : pieces[WHITE]) set_pos(piece, piece->get_pos());
250 for (auto piece : pieces[BLACK]) set_pos(piece, piece->get_pos());
251}
252
254{
255 int row, col;
256 pos.get_row_col(row, col);
257 return board[7 - row][col];
258}
259
261{
262 int row, col;
263 pos.get_row_col(row, col);
264 board[7 - row][col] = piece;
265 if(piece == nullptr) return;
266 piece->set_pos(pos);
267}
268
270{
271 for (Piece *piece : pieces[WHITE]) delete piece;
272 for (Piece *piece : pieces[BLACK]) delete piece;
273}
274
275bool Echiquier::promote(Pion *pion, const std::string& type)
276{
277 auto &vect = pieces[pion->get_color()];
278 if(type == "N"){
279 auto new_piece = new Cavalier(
280 pion->get_color() == WHITE ? "\u2658" : "\u265E",
281 "N",
282 pion->get_color(),
283 pion->get_id() + 8,
284 pion->get_pos(),
285 this
286 );
287 new_piece->set_has_moved(true);
288 vect.push_back(new_piece);
289 set_pos(new_piece, pion->get_pos());
290 }
291 if(type == "Q"){
292 auto new_piece = new Reine(
293 pion->get_color() == WHITE ? "\u2655" : "\u265B",
294 "Q",
295 pion->get_color(),
296 pion->get_id() + 8,
297 pion->get_pos(),
298 this
299 );
300 new_piece->set_has_moved(true);
301 vect.push_back(new_piece);
302 set_pos(new_piece, pion->get_pos());
303 }
304 if(type == "B"){
305 auto new_piece = new Fou(
306 pion->get_color() == WHITE ? "\u2657" : "\u265D",
307 "B",
308 pion->get_color(),
309 pion->get_id() + 8,
310 pion->get_pos(),
311 this
312 );
313 new_piece->set_has_moved(true);
314 vect.push_back(new_piece);
315 set_pos(new_piece, pion->get_pos());
316 }
317 if(type == "R") {
318 auto new_piece = new Tour(
319 pion->get_color() == WHITE ? "\u2656" : "\u265C",
320 "R",
321 pion->get_color(),
322 pion->get_id() + 8,
323 pion->get_pos(),
324 this
325 );
326 new_piece->set_has_moved(true);
327 vect.push_back(new_piece);
328 set_pos(new_piece, pion->get_pos());
329 }
330 else return false;
331
332 pion->set_is_active(false);
333 return true;
334}
335
336const std::list<Move>& Echiquier::get_moves() const {
337 return moves;
338}
Cavalier dans le jeu d'échec.
Definition cavalier.hpp:7
bool check_stalemate(Color player)
Vérifie si le joueur est en situation de pat.
Piece * get_piece(Square pos) const
Récupère une pièce se trouvant à la position donnée.
void set_pos(Piece *piece, Square pos)
Place une pièce à un endroit sur le plateau.
bool check_castling(Color player, bool big) const
Vérifie si un joueur peut roquer ou non.
Definition echiquier.cpp:72
bool promote(Pion *pion, const std::string &type)
Permet de promouvoir un pion en une autre pièce.
void setup()
Place les pions et pièces à leur emplacement de départ.
bool move(Square from, Square to, Color player)
Permet d'effectuer un mouvement de pièce.
const std::list< Move > & get_moves() const
Récupère la liste des coups effectués lors de la partie.
Piece * get_piece_from_id(int id, Color player) const
Récupère une pièce d'un joueur à partir de son id.
Definition echiquier.cpp:97
void print_board() const
Affiche l'échiquier.
bool check_move(Square from, Square to, Color player)
Vérifie si le coup entre from et to est légal pour le joueur player.
bool castling(Color player, bool big)
Effectue le roque d'un joueur.
Definition echiquier.cpp:52
bool check_check(Color player, Square pos, Piece *exclude=nullptr) const
Vérifie si une case est menacée par un joueur.
void set_is_check(bool is_check)
Définit s'il y a un échec ou non.
Definition echiquier.hpp:75
std::string canonical_position() const
Retourne la position canonique de l'échiquier.
bool check_check_mate(Color player)
Vérifie si le joueur est en situation d'échec et mat.
Fou dans le jeu d'échec.
Definition fou.hpp:7
Classe décrivant une pièce.
Definition piece.hpp:12
void set_pos(const Square pos)
Définit la position de la pièce.
Definition piece.hpp:111
int get_id() const
Definition piece.hpp:78
virtual std::string get_name() const
Definition piece.hpp:66
Square get_pos() const
Récupère la position actuelle de la pièce.
Definition piece.hpp:107
Color get_color() const
Definition piece.hpp:75
bool get_has_moved() const
Vérifie si la pièce a déjà bougée ou non.
Definition piece.hpp:99
virtual bool est_mouvement_legal(Square origine, Square destination) const
Vérifie si un mouvement de la case origine à la case destination est valide.
Definition piece.cpp:6
virtual void move_event(Square from)
Fonction appelée quand une pièce bouge.
Definition piece.hpp:70
virtual bool est_menace(Square origine, Square destination) const
Vérifie si la pièce est une menace pour l'adversaire.
Definition piece.cpp:18
void set_is_active(bool is_active)
Définit si la pièce est mangée ou non.
Definition piece.hpp:55
Pion dans le jeu d'échec.
Definition pion.hpp:7
Reine dans le jeu d'échec.
Definition reine.hpp:9
Roi dans le jeu d'échec.
Definition roi.hpp:7
void set_is_checked(bool is_checked)
Définit si le roi est en échec ou non.
Definition roi.hpp:34
Décrit une case de l'échiquier.
Definition square.hpp:7
void get_row_col(int &row, int &col) const
Récupère la ligne et la colonne décrite par l'objet.
Definition square.hpp:15
Tour dans le jeu d'échec.
Definition tour.hpp:7
Color
Liste des équipes.
Definition enums.hpp:5
@ WHITE
Definition enums.hpp:6
@ BLACK
Definition enums.hpp:7