-
Notifications
You must be signed in to change notification settings - Fork 0
/
Pawn.cpp
154 lines (133 loc) · 3.22 KB
/
Pawn.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
#include "StdAfx.h"
#include "Piece.h"
#include "Pawn.h"
#include "King.h"
#include "Board.h"
#include "Square.h"
CPawn::CPawn(EColour theColour, CBoard* pBoard, short thePosition)
: CPiece(theColour, pBoard, thePosition), moved(false)
{
}
CPawn::~CPawn(void)
{
}
bool CPawn::move(short sourceRow, short targetRow, short sourceColumn, short targetColumn)
{
bool bResult = true;
if (!CPiece::move(sourceRow, targetRow, sourceColumn, targetColumn))
{
return false;
}
// if the pawn is advancing one square and a nemesis piece adjacent to it did not move last turn and the user had an opportunity to do so, en passant applies
if (isEnPassant(targetRow, targetColumn))
{
// remove the relevant nemesis piece from the board
// WHAT IF THERE ARE TWO PIECES - ONE EITHER SIDE, AND NEITHER MOVED LAST TURN WITH A VALID OPPORTUNITY - TAKE BOTH OUT OF ACTION??? CLARIFY RULES
;
}
// TURN PAWN INTO QUEEN?
// we allow 2 steps forward on first move only
moved = true;
return bResult;
}
bool CPawn::isMoveLegal(short xrow, short yrow, short xcolumn, short ycolumn)
{
bool bResult = false;
short rowDiff = 0;
short columnDiff = 0;
if (ycolumn > xcolumn)
{
columnDiff = ycolumn - xcolumn;
}
else if (xcolumn > ycolumn)
{
columnDiff = xcolumn - ycolumn;
}
if (yrow > xrow)
{
if (eColour == eWhite)
{
rowDiff = yrow - xrow;
}
}
else if (xrow > yrow)
{
if (eColour == eBlack)
{
rowDiff = xrow - yrow;
}
}
if (moved == false)
{
// advance one row and optionally move diagonally to take a piece
if (rowDiff == 1)
{
if (columnDiff == 0)
{
bResult = true;
}
else if (columnDiff == 1)
{
if (pBoard->getSquares()[getPositionFromRowAndColumn(yrow, ycolumn)]->isSquareOccupied())
{
// it is only legal to move diagonally with a pawn when taking a nemesis piece
if (pBoard->getSquares()[getPositionFromRowAndColumn(yrow, ycolumn)]->getPiece()->getColour() != eColour)
{
bResult = true;
}
}
}
}
// advancing two rows in one move is only allowed if the pawn has not yet moved
if ( (rowDiff == 2) && (columnDiff == 0) )
{
bResult = true;
}
}
else
{
if (rowDiff == 1)
{
if ( (columnDiff == 0) || (columnDiff == 1) )
{
bResult = true;
}
}
}
return bResult;
}
bool CPawn::isMoveBlocked(short xrow, short yrow, short xcolumn, short ycolumn)
{
bool bResult = false;
short intermediateRow = -1;
short rowDiff = 0;
// verify path vertically up the board is not blocked
if (xrow < yrow)
{
rowDiff = yrow - xrow;
intermediateRow = xrow + 1;
}
else if (yrow < xrow)
{
rowDiff = xrow - yrow;
intermediateRow = yrow - 1;
}
if (rowDiff == 2)
{
// verify movement path is clear; it is forbidden to take a piece with a pawn when advancing two spaces
if (pBoard->getSquares()[getPositionFromRowAndColumn(intermediateRow, ycolumn)]->isSquareOccupied())
{
bResult = true;
}
}
// same colour piece on target square is a block
if (isTargetSquareBlocked(yrow, ycolumn))
{
bResult = true;
}
return bResult;
}
bool CPawn::isEnPassant(int x, int y)
{
return false;
}