1 #ifndef HLVARIANT__CHESS__GAMESTATE_H
2 #define HLVARIANT__CHESS__GAMESTATE_H
13 struct TAGUA_EXPORT CastlingData
{
20 CastlingData(bool, bool, bool, bool);
21 bool operator==(const CastlingData
& other
) const;
24 template <typename _Board
, typename _Move
>
29 typedef typename
Board::Piece Piece
;
33 CastlingData m_castling
;
35 typename
Piece::Color m_turn
;
38 virtual ~GameState() { }
40 virtual Board
& board();
41 virtual const Board
& board() const;
45 virtual bool operator==(const GameState
<Board
, Move
>& other
) const;
47 virtual Point
enPassant() const;
48 virtual bool kingCastling(typename
Piece::Color color
) const;
49 virtual bool queenCastling(typename
Piece::Color color
) const;
51 virtual void move(const Move
& m
);
52 virtual void basicMove(const Move
& m
);
53 virtual void handleCastling(const Piece
& piece
, const Move
& m
);
54 virtual void captureOn(const Point
& p
);
56 virtual void setTurn(typename
Piece::Color color
);
57 virtual typename
Piece::Color
previousTurn() const;
58 virtual void switchTurn();
59 virtual typename
Piece::Color
turn() const;
61 virtual int startingRank(typename
Piece::Color color
) const;
62 virtual int promotionRank(typename
Piece::Color color
) const;
63 virtual Point
kingStartingPosition(typename
Piece::Color color
) const;
64 virtual Point
direction(typename
Piece::Color color
) const;
69 template <typename Board
, typename Move
>
70 GameState
<Board
, Move
>::GameState()
71 : m_board(Point(8, 8))
72 , m_en_passant(Point::invalid())
73 , m_turn(Piece::WHITE
) { }
75 template <typename Board
, typename Move
>
76 Board
& GameState
<Board
, Move
>::board() { return m_board
; }
78 template <typename Board
, typename Move
>
79 const Board
& GameState
<Board
, Move
>::board() const { return m_board
; }
81 template <typename Board
, typename Move
>
82 Point GameState
<Board
, Move
>::enPassant() const {
86 template <typename Board
, typename Move
>
87 bool GameState
<Board
, Move
>::kingCastling(typename
Piece::Color color
) const {
88 if (color
== Piece::WHITE
) {
96 template <typename Board
, typename Move
>
97 bool GameState
<Board
, Move
>::queenCastling(typename
Piece::Color color
) const {
98 if (color
== Piece::WHITE
) {
102 return m_castling
.bq
;
106 template <typename Board
, typename Move
>
107 void GameState
<Board
, Move
>::setup() {
108 for (int c
= 0; c
< 2; c
++) {
109 typename
Piece::Color color
= static_cast<typename
Piece::Color
>(c
);
110 int rank
= startingRank(color
);
111 for (int i
= 0; i
< m_board
.size().x
; i
++) {
112 m_board
.set(Point(i
, rank
+ direction(color
).y
),
113 Piece(color
, Piece::PAWN
));
114 m_board
.set(Point(0, rank
), Piece(color
, Piece::ROOK
));
115 m_board
.set(Point(1, rank
), Piece(color
, Piece::KNIGHT
));
116 m_board
.set(Point(2, rank
), Piece(color
, Piece::BISHOP
));
117 m_board
.set(Point(3, rank
), Piece(color
, Piece::QUEEN
));
118 m_board
.set(Point(4, rank
), Piece(color
, Piece::KING
));
119 m_board
.set(Point(5, rank
), Piece(color
, Piece::BISHOP
));
120 m_board
.set(Point(6, rank
), Piece(color
, Piece::KNIGHT
));
121 m_board
.set(Point(7, rank
), Piece(color
, Piece::ROOK
));
126 template <typename Board
, typename Move
>
127 bool GameState
<Board
, Move
>::operator==(const GameState
<Board
, Move
>& other
) const {
128 return m_board
== other
.m_board
&&
129 m_castling
== other
.m_castling
&&
130 m_en_passant
== other
.m_en_passant
;
133 template <typename Board
, typename Move
>
134 void GameState
<Board
, Move
>::captureOn(const Point
& p
) {
135 m_board
.set(p
, Piece());
138 template <typename Board
, typename Move
>
139 void GameState
<Board
, Move
>::basicMove(const Move
& m
) {
140 if (m
.from() != m
.to()) {
141 m_board
.set(m
.to(), m_board
.get(m
.from()));
142 m_board
.set(m
.from(), Piece());
146 template <typename Board
, typename Move
>
147 void GameState
<Board
, Move
>::handleCastling(const Piece
& piece
, const Move
& m
) {
148 if (m
.kingSideCastling()) {
149 Point rookSquare
= m
.to() + Point(1,0);
150 Point rookDestination
= m
.from() + Point(1,0);
151 basicMove(Move(rookSquare
, rookDestination
));
154 else if (m
.queenSideCastling()) {
155 Point rookSquare
= m
.to() - Point(2,0);
156 Point rookDestination
= m
.from() - Point(1,0);
157 basicMove(Move(rookSquare
, rookDestination
));
160 typename
Piece::Type type
= piece
.type();
161 typename
Piece::Color color
= piece
.color();
163 if (type
== Piece::KING
) {
164 if (color
== Piece::WHITE
) {
165 m_castling
.wk
= false;
166 m_castling
.wq
= false;
169 m_castling
.bk
= false;
170 m_castling
.bq
= false;
174 if (m
.from() == Point(0,0) || m
.to() == Point(0,0))
175 m_castling
.bq
= false;
176 else if (m
.from() == Point(7,0) || m
.to() == Point(7,0))
177 m_castling
.bk
= false;
178 else if (m
.from() == Point(0,7) || m
.to() == Point(0,7))
179 m_castling
.wq
= false;
180 else if (m
.from() == Point(7,7) || m
.to() == Point(7,7))
181 m_castling
.wk
= false;
184 template <typename Board
, typename Move
>
185 void GameState
<Board
, Move
>::switchTurn() {
186 m_turn
= Piece::oppositeColor(m_turn
);
189 template <typename Board
, typename Move
>
190 void GameState
<Board
, Move
>::move(const Move
& m
) {
191 Piece piece
= m_board
.get(m
.from());
192 if (piece
== Piece()) return;
194 captureOn(m
.captureSquare());
197 m_en_passant
= m
.enPassantTrigger();
199 typename
Piece::Type promotion_type
=
200 static_cast<typename
Piece::Type
>(m
.promoteTo());
201 if (promotion_type
!= Piece::INVALID_TYPE
) {
202 m_board
.set(m
.to(), Piece(piece
.color(), promotion_type
));
205 handleCastling(piece
, m
);
209 template <typename Board
, typename Move
>
210 typename
Board::Piece::Color GameState
<Board
, Move
>::turn() const {
214 template <typename Board
, typename Move
>
215 typename
Board::Piece::Color GameState
<Board
, Move
>::previousTurn() const {
216 return Piece::oppositeColor(m_turn
);
219 template <typename Board
, typename Move
>
220 void GameState
<Board
, Move
>::setTurn(typename
Piece::Color color
) {
224 template <typename Board
, typename Move
>
225 int GameState
<Board
, Move
>::startingRank(typename
Piece::Color color
) const {
226 return color
== Piece::WHITE
? m_board
.size().y
- 1 : 0;
229 template <typename Board
, typename Move
>
230 int GameState
<Board
, Move
>::promotionRank(typename
Piece::Color color
) const {
231 return startingRank(Piece::oppositeColor(color
));
234 template <typename Board
, typename Move
>
235 Point GameState
<Board
, Move
>::kingStartingPosition(typename
Piece::Color color
) const {
236 return Point(4, startingRank(color
));
239 template <typename Board
, typename Move
>
240 Point GameState
<Board
, Move
>::direction(typename
Piece::Color color
) const {
241 return Point(0, color
== Piece::WHITE
? -1 : 1);
246 } // namespace HLVariant
248 #endif // HLVARIANT__CHESS__GAMESTATE_H