Ported crazyhouse piece. Working on crazyhouse game state.
[tagua.git] / src / hlvariant / chess / gamestate.h
blob1f3d73b6164d7e0d1445183d5881bbba15a63be5
1 #ifndef HLVARIANT__CHESS__GAMESTATE_H
2 #define HLVARIANT__CHESS__GAMESTATE_H
4 #include "../board.h"
5 #include "piece.h"
6 #include "move.h"
7 #include "nopool.h"
8 #include "export.h"
10 namespace HLVariant {
11 namespace Chess {
13 struct TAGUA_EXPORT CastlingData {
14 bool wk : 1;
15 bool wq : 1;
16 bool bk : 1;
17 bool bq : 1;
19 CastlingData();
20 CastlingData(bool, bool, bool, bool);
21 bool operator==(const CastlingData& other) const;
24 template <typename _Board, typename _Move>
25 class GameState {
26 public:
27 typedef _Board Board;
28 typedef _Move Move;
29 typedef typename Board::Piece Piece;
30 typedef NoPool Pool;
31 protected:
32 Board m_board;
33 CastlingData m_castling;
34 Point m_en_passant;
35 typename Piece::Color m_turn;
36 public:
37 GameState();
38 virtual ~GameState() { }
40 virtual Board& board();
41 virtual const Board& board() const;
43 virtual void setup();
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;
67 // IMPLEMENTATION
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 {
83 return m_en_passant;
86 template <typename Board, typename Move>
87 bool GameState<Board, Move>::kingCastling(typename Piece::Color color) const {
88 if (color == Piece::WHITE) {
89 return m_castling.wk;
91 else {
92 return m_castling.bk;
96 template <typename Board, typename Move>
97 bool GameState<Board, Move>::queenCastling(typename Piece::Color color) const {
98 if (color == Piece::WHITE) {
99 return m_castling.wq;
101 else {
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;
168 else {
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());
195 basicMove(m);
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);
206 switchTurn();
209 template <typename Board, typename Move>
210 typename Board::Piece::Color GameState<Board, Move>::turn() const {
211 return m_turn;
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) {
221 m_turn = 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);
245 } // namespace Chess
246 } // namespace HLVariant
248 #endif // HLVARIANT__CHESS__GAMESTATE_H