-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChess.cpp
266 lines (231 loc) · 7.55 KB
/
Chess.cpp
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#include "Chess.h"
#include <iterator>
#include <cctype>
using std::map;
using std::pair;
using std::make_pair;
/////////////////////////////////////
// DO NOT MODIFY THIS FUNCTION!!!! //
/////////////////////////////////////
Chess::Chess( void ) : _turn_white( true )
{
// Add the pawns
for( int i=0 ; i<8 ; i++ )
{
_board.add_piece( std::pair< char , char >( 'A'+i , '1'+1 ) , 'P' );
_board.add_piece( std::pair< char , char >( 'A'+i , '1'+6 ) , 'p' );
}
// Add the rooks
_board.add_piece( std::pair< char , char >( 'A'+0 , '1'+0 ) , 'R' );
_board.add_piece( std::pair< char , char >( 'A'+7 , '1'+0 ) , 'R' );
_board.add_piece( std::pair< char , char >( 'A'+0 , '1'+7 ) , 'r' );
_board.add_piece( std::pair< char , char >( 'A'+7 , '1'+7 ) , 'r' );
// Add the knights
_board.add_piece( std::pair< char , char >( 'A'+1 , '1'+0 ) , 'N' );
_board.add_piece( std::pair< char , char >( 'A'+6 , '1'+0 ) , 'N' );
_board.add_piece( std::pair< char , char >( 'A'+1 , '1'+7 ) , 'n' );
_board.add_piece( std::pair< char , char >( 'A'+6 , '1'+7 ) , 'n' );
// Add the bishops
_board.add_piece( std::pair< char , char >( 'A'+2 , '1'+0 ) , 'B' );
_board.add_piece( std::pair< char , char >( 'A'+5 , '1'+0 ) , 'B' );
_board.add_piece( std::pair< char , char >( 'A'+2 , '1'+7 ) , 'b' );
_board.add_piece( std::pair< char , char >( 'A'+5 , '1'+7 ) , 'b' );
// Add the kings and queens
_board.add_piece( std::pair< char , char >( 'A'+3 , '1'+0 ) , 'Q' );
_board.add_piece( std::pair< char , char >( 'A'+4 , '1'+0 ) , 'K' );
_board.add_piece( std::pair< char , char >( 'A'+3 , '1'+7 ) , 'q' );
_board.add_piece( std::pair< char , char >( 'A'+4 , '1'+7 ) , 'k' );
}
bool Chess::make_move( std::pair< char , char > start , std::pair< char , char > end )
{
// Get const pointers to the first and end piece
const Piece* first_piece = _board(start);
// Check if first_piece is NULL
if(first_piece == NULL) {
// Starting piece is NULL
return false;
}
if(first_piece->is_white() != _turn_white) {
// Wrong Color
return false;
}
// Check if first_piece makes a legal move assuming no pieces around
if(!(first_piece->legal_move_shape(start, end))) {
// Not a legal move shape
return false;
}
// Check if path is clear
if(!(_board.path_is_clear(start,end))) {
// Path is NOT clear
return false;
}
// Check endpoint
if(!(_board.check_end_location(start, end))) {
// Cannot place piece at end location
return false;
}
// Execute Move on Board Copy
Board b = _board;
b.execute_move(start, end);
// Check if board is in check now
if(in_p_check(_turn_white, b)) {
// Move would result in your king in check
return false;
}
// Execute Move
_board.execute_move(start,end);
// Change color of player:
if(_turn_white) {
_turn_white = false;
}
else {
_turn_white = true;
}
return true;
}
bool Chess::in_p_check( bool white, const Board& b ) const
{
char king;
if( white ) {
king = 'K';
} else {
king = 'k';
}
pair<char, char> start;
pair<char, char> end;
// Finds where the king in question is
for(map<pair<char, char>, Piece*>::const_iterator it = b.occ().cbegin(); it != b.occ().cend(); ++it) {
if(it->second->to_ascii() == king) {
end = it->first;
break;
}
}
// Runs through the rest of the map
for(map<pair<char, char>, Piece*>::const_iterator it = b.occ().cbegin(); it != b.occ().cend(); ++it) {
// Make sure piece is opposite color to continue for check
if(white != (it->second)->is_white()) {
start = it->first;
// If possible move by the piece, check if the path is clear
if(it->second->legal_move_shape(start, end)) {
if(b.path_is_clear(start, end)) {
if(b.check_end_location(start, end)) {
return true;
}
}
}
}
}
return false;
}
bool Chess::in_check( bool white ) const
{
if(in_p_check(white, _board)) {
return true;
}
return false;
}
bool Chess::in_mate( bool white ) const
{
// King is not in check, return false
if(!in_check(white)) {
return false;
}
pair<char, char> end = std::make_pair('A','1');
pair<char, char> start;
// Logic Check: Mate = no possible move for anything
for(map<pair<char, char>, Piece*>::const_iterator it = _board.occ().cbegin(); it != _board.occ().cend(); ++it) {
// Checks to make sure that the new piece is the same color
if(white == it->second->is_white()) {
start = it->first;
// Loop through whole 8x8 board to iterate through possible end locations
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
// Check if path is legal, clear, and end location is valid
if(it->second->legal_move_shape(start, end)) {
if(_board.path_is_clear(start,end)) {
if(_board.check_end_location(start, end)) {
// CHECK TO MAKE SURE THAT THE NEW BOARD STILL RETAINS CHECK
Board b = _board;
b.execute_move(start, end);
if(!in_p_check(white, b)) {
// If new board not in check, then it is possible to escape check
return false;
}
}
}
}
end.second++;
}
end.first++;
end.second = '1';
}
end.first = 'A';
}
}
// No possible moves can be made without getting king in check
return true;
}
bool Chess::in_stalemate( bool white ) const
{
pair<char, char> start;
pair<char, char> end;
// Runs through the 8x8 chess board
for(char i = 'A'; i <= 'H'; i++) {
for(char j = '1'; j <= '8'; j++) {
end = make_pair(i, j);
// Runs through map of chess pieces on the board
for(map<pair<char, char>, Piece*>::const_iterator it =_board.occ().cbegin();
it!= _board.occ().cend(); ++it) {
// Make sure piece that we check is a piece the current player owns
if(white == (it->second)->is_white()) {
start = it->first;
// Ensure hypothetical path is legal, clear, and end location is valid
if(it->second->legal_move_shape(start, end)) {
if(_board.path_is_clear(start, end)) {
if(_board.check_end_location(start, end)) {
// CHECK TO MAKE SURE THAT THE NEW BOARD STILL RETAINS CHECK
Board b = _board;
b.execute_move(start, end);
if(!in_p_check(white, b)) {
// New board not in check, so there is a move to not have board in stalemate
return false;
}
}
}
}
}
}
}
}
// No possible moves can be made without getting king in check
return true;
}
/////////////////////////////////////
// DO NOT MODIFY THIS FUNCTION!!!! //
/////////////////////////////////////
std::ostream& operator << ( std::ostream& os , const Chess& chess )
{
// Write the board out and then either the character 'w' or the character 'b', depending on whose turn it is
return os << chess.board() << ( chess.turn_white() ? 'w' : 'b' );
}
std::istream& operator >> ( std::istream& is , Chess& chess )
{
// Clear the map of _board contained in chess
// clear_board() is a method in the Board class
chess._board.clear_board();
char piece;
for(char number = '8'; number >= '1'; number--) {
for(char letter = 'A'; letter <= 'H'; letter++) {
is >> piece;
if(piece != '-') {
chess._board.add_piece(pair< char , char >( letter , number ) , piece );
}
}
}
// After 64 characters are read, this last reading
// reads the last character which determines if the board
// is at white or black's turn
is >> piece;
chess.set_turn_white(piece);
return is;
}