Deal with non-promotable shogi pieces.
[tagua/yd.git] / src / hlvariant / shogi / gamestate.h
blobd580d67f14dea9fa64849e655036eaed428ccb2e
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #ifndef HLVARIANT__SHOGI__GAMESTATE_H
12 #define HLVARIANT__SHOGI__GAMESTATE_H
14 #include "../crazyhouse/gamestate.h"
15 #include "../pool.h"
16 #include "../poolcollection.h"
18 namespace HLVariant {
19 namespace Shogi {
21 template <typename _Board, typename _Move>
22 class GameState {
23 public:
24 typedef _Board Board;
25 typedef _Move Move;
26 typedef typename Board::Piece Piece;
27 typedef Pool<Piece> Pool;
28 typedef PoolCollection<Pool> Pools;
29 private:
30 Board m_board;
31 Pools m_pools;
32 typename Piece::Color m_turn;
33 public:
34 GameState();
35 virtual ~GameState();
37 virtual Board& board();
38 virtual const Board& board() const;
40 virtual Pools& pools();
41 virtual const Pools& pools() const;
43 virtual void setup();
45 virtual bool operator==(const GameState<Board, Move>& other) const;
47 virtual void move(const Move& m);
48 virtual void basicMove(const Move& m);
49 virtual void captureOn(const Point& p);
50 virtual bool promotionZone(typename Piece::Color player, const Point& p) const;
51 virtual bool canPromote(const Piece& p) const;
53 virtual void setTurn(typename Piece::Color color);
54 virtual typename Piece::Color previousTurn() const;
55 virtual void switchTurn();
56 virtual typename Piece::Color turn() const;
58 virtual int startingRank(typename Piece::Color color) const;
59 virtual int promotionRank(typename Piece::Color color) const;
60 virtual Point kingStartingPosition(typename Piece::Color color) const;
61 virtual Point direction(typename Piece::Color color) const;
64 // IMPLEMENTATION
66 template <typename Board, typename Move>
67 GameState<Board, Move>::GameState()
68 : m_turn(Piece::BLACK) { }
70 template <typename Board, typename Move>
71 GameState<Board, Move>::~GameState() { }
73 template <typename Board, typename Move>
74 Board& GameState<Board, Move>::board() { return m_board; }
76 template <typename Board, typename Move>
77 const Board& GameState<Board, Move>::board() const { return m_board; }
79 template <typename Board, typename Move>
80 typename GameState<Board, Move>::Pools& GameState<Board, Move>::pools() { return m_pools; }
82 template <typename Board, typename Move>
83 const typename GameState<Board, Move>::Pools& GameState<Board, Move>::pools() const { return m_pools; }
85 #define COL(i, c) c == Piece::BLACK ? (i) : (m_board.size().x - i - 1)
86 template <typename Board, typename Move>
87 void GameState<Board, Move>::setup() {
88 for (int c = 0; c < 2; c++) {
89 typename Piece::Color color = static_cast<typename Piece::Color>(c);
90 int rank = startingRank(color);
91 for (int i = 0; i < m_board.size().x; i++) {
92 m_board.set(Point(i, rank + direction(color).y * 2),
93 Piece(color, Piece::PAWN));
95 m_board.set(Point(0, rank), Piece(color, Piece::LANCE));
96 m_board.set(Point(1, rank), Piece(color, Piece::KNIGHT));
97 m_board.set(Point(2, rank), Piece(color, Piece::SILVER));
98 m_board.set(Point(3, rank), Piece(color, Piece::GOLD));
99 m_board.set(Point(4, rank), Piece(color, Piece::KING));
100 m_board.set(Point(5, rank), Piece(color, Piece::GOLD));
101 m_board.set(Point(6, rank), Piece(color, Piece::SILVER));
102 m_board.set(Point(7, rank), Piece(color, Piece::KNIGHT));
103 m_board.set(Point(8, rank), Piece(color, Piece::LANCE));
105 m_board.set(Point(COL(1, c), rank + direction(color).y),
106 Piece(color, Piece::BISHOP));
107 m_board.set(Point(COL(7, c), rank + direction(color).y),
108 Piece(color, Piece::ROOK));
111 #undef COL
113 template <typename Board, typename Move>
114 bool GameState<Board, Move>::promotionZone(typename Piece::Color player, const Point& p) const {
115 return player == Piece::WHITE ? p.y >= 6 : p.y <= 2;
118 template <typename Board, typename Move>
119 bool GameState<Board, Move>::canPromote(const Piece& p) const {
120 if (p.promoted())
121 return false;
123 if ((p.type() == Piece::KING) || (p.type() == Piece::GOLD))
124 return false;
125 else
126 return true;
129 template <typename Board, typename Move>
130 bool GameState<Board, Move>::operator==(const GameState<Board, Move>& other) const {
131 return m_turn == other.m_turn &&
132 m_board == other.m_board;
135 template <typename Board, typename Move>
136 void GameState<Board, Move>::move(const Move& m) {
137 if (m.drop() == Piece()) {
138 captureOn(m.to());
139 basicMove(m);
141 if (m.promoteTo() != -1) {
142 Piece piece = m_board.get(m.to());
143 piece.setPromoted();
144 m_board.set(m.to(), piece);
147 else {
148 m_board.set(m.to(), m.drop());
149 m_pools.pool(m.drop().color()).remove(m.drop().type());
152 switchTurn();
155 template <typename Board, typename Move>
156 void GameState<Board, Move>::captureOn(const Point& p) {
157 Piece captured = m_board.get(p);
158 m_board.set(p, Piece());
159 m_pools.pool(Piece::oppositeColor(captured.color())).add(captured.type());
162 template <typename Board, typename Move>
163 void GameState<Board, Move>::basicMove(const Move& m) {
164 if (m.from() != m.to()) {
165 m_board.set(m.to(), m_board.get(m.from()));
166 m_board.set(m.from(), Piece());
170 template <typename Board, typename Move>
171 void GameState<Board, Move>::switchTurn() {
172 m_turn = Piece::oppositeColor(m_turn);
175 template <typename Board, typename Move>
176 typename Board::Piece::Color GameState<Board, Move>::turn() const {
177 return m_turn;
180 template <typename Board, typename Move>
181 typename Board::Piece::Color GameState<Board, Move>::previousTurn() const {
182 return Piece::oppositeColor(m_turn);
185 template <typename Board, typename Move>
186 void GameState<Board, Move>::setTurn(typename Piece::Color color) {
187 m_turn = color;
190 template <typename Board, typename Move>
191 int GameState<Board, Move>::startingRank(typename Piece::Color color) const {
192 return color == Piece::BLACK ? m_board.size().y - 1 : 0;
195 template <typename Board, typename Move>
196 int GameState<Board, Move>::promotionRank(typename Piece::Color color) const {
197 return startingRank(Piece::oppositeColor(color));
200 template <typename Board, typename Move>
201 Point GameState<Board, Move>::kingStartingPosition(typename Piece::Color color) const {
202 return Point(4, startingRank(color));
205 template <typename Board, typename Move>
206 Point GameState<Board, Move>::direction(typename Piece::Color color) const {
207 return Point(0, color == Piece::BLACK ? -1 : 1);
211 } // namespace Shogi
212 } // namespace HLVariant
214 #endif // HLVARIANT__SHOGI__GAMESTATE_H