-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathking.cpp
More file actions
145 lines (135 loc) · 4.84 KB
/
Copy pathking.cpp
File metadata and controls
145 lines (135 loc) · 4.84 KB
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
/* king.cpp - Written by Michael Wermert and Pengda Xie
*
* This files contains functions definitions for the
* king class in the piece.h file.
*/
#include "piece.h"
#include <cmath>
#include <utility>
using namespace std;
//initialize king piece
King::King(int row, int col, char color):Piece(row, col, color, 'K', 900)
{
}
//set moves multimap to contains all valid moves that the king can make
//in the current board state
void King::ValidMoves(multimap<int, int> &moves, const vector<vector<Piece*> > &board)
{
moves.clear();
vector<pair<int, int>> allMoves;
int r, c;
Piece* pPtr;
//add potential moves
allMoves.push_back(make_pair(row - 1, col - 1));
allMoves.push_back(make_pair(row - 1, col));
allMoves.push_back(make_pair(row - 1, col + 1));
allMoves.push_back(make_pair(row, col - 1));
allMoves.push_back(make_pair(row, col + 1));
allMoves.push_back(make_pair(row + 1, col - 1));
allMoves.push_back(make_pair(row + 1, col));
allMoves.push_back(make_pair(row + 1, col + 1));
//check if potential moves are valid
for(unsigned int i = 0; i < allMoves.size(); i++)
{
r = allMoves[i].first;
c = allMoves[i].second;
//if col and row are within the bound
if(r >= 0 && r < (int)board.size() && c >= 0 && c < (int)board.size())
{
pPtr = board[r][c];
//if the target cell is a valid move
if(pPtr == nullptr || pPtr->GetColor () != this->piece_color)
{
//king cannot move to cell that is under attack
if(!isInCheck(board, r, c))
moves.insert(allMoves[i]);
}
}
}
//chek for castle
//king never moved
if(move_count == 0)
{
//get both rooks
Piece* kSideR = board[row][7];
Piece* qSideR = board[row][0];
//king side castle
if(kSideR != nullptr &&
kSideR->GetMoveCount() == 0 &&
kSideR->GetSymbol() == 'R' &&
kSideR->GetColor() == this->piece_color)
{
//no piece should be between the king and the rook
if(board[row][col + 1] == nullptr && board[row][col + 2] == nullptr)
{
//the king is not currently in check
//and the king does not move through a square that is under attack
if(!isInCheck(board, row, col) &&
!isInCheck(board, row, col + 1) &&
!isInCheck(board, row, col + 2))
{
moves.insert(make_pair(row, col + 2));
}
}
}
//queen side castle
if(qSideR != nullptr &&
qSideR->GetMoveCount() == 0 &&
qSideR->GetSymbol() == 'R' &&
qSideR->GetColor() == this->piece_color)
{
//no piece should be between the king and the rook
if(board[row][col - 1] == nullptr &&
board[row][col - 2] == nullptr &&
board[row][col - 3] == nullptr)
{
//the king is not currently in check
//and the king does not move through a square that is under attack
if(!isInCheck(board, row, col) &&
!isInCheck(board, row, col - 1) &&
!isInCheck(board, row, col - 2))
{
moves.insert(make_pair(row, col - 2));
}
}
}
}
}
//return true if king is in check after moving to the target cell
bool King::isInCheck(const vector<vector<Piece*> > &board, int r, int c)
{
//make a copy of the board
vector<vector<Piece*> > newBoard = board;
multimap<int, int> moves;
multimap<int, int>::iterator it;
//move the king on the copied board
newBoard[r][c] = newBoard[this->row][this->col];
newBoard[this->row][this->col] = nullptr;
for(unsigned int i = 0; i < board.size(); i++)
{
for(unsigned int j = 0; j < board[i].size(); j++)
{
//goes through each opponent's piece on the board
if(board[i][j] != nullptr && board[i][j]->GetColor() != this->piece_color)
{
//if enemy king is 1 cell away, current king is in check
if(board[i][j]->GetSymbol() == 'K')
{
if((abs(r - i) <= 1) && (abs(c - j) <= 1))
return true;
}
else
{
//check whether any other piece can attack this cell
board[i][j]->ValidMoves(moves, newBoard);
for(it = moves.begin(); it != moves.end(); ++it)
{
if(it->first == r && it->second == c)
return true;
}
}
}
}
}
return false;
}