Replaced all std::cout with kDebug.
[tagua/yd.git] / src / hlvariant / tori-shogi / legalitycheck.h
blob79692ab0ec47035c32fcc22a2986cd53ab53dbaa
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
4 (c) 2007 Yann Dirson <ydirson@altern.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
12 #ifndef HLVARIANT__TORISHOGI__LEGALITYCHECK_H
13 #define HLVARIANT__TORISHOGI__LEGALITYCHECK_H
15 #include "interactiontype.h"
16 #include "../shogi/legalitycheck.h"
18 namespace HLVariant {
19 namespace ToriShogi {
21 template <typename _GameState>
22 class LegalityCheck: public Shogi::LegalityCheck<_GameState> {
23 typedef Shogi::LegalityCheck<_GameState> Base;
24 public:
25 typedef _GameState GameState;
26 typedef typename GameState::Board Board;
27 typedef typename Board::Piece Piece;
28 typedef typename GameState::Move Move;
30 LegalityCheck(const GameState& state);
32 virtual bool getMoveType(const Piece& piece, const Move& move) const;
33 bool legal(Move& move) const;
34 bool pseudolegal(Move& move) const;
35 protected:
36 virtual bool stuckPiece(const Piece& piece, const Point& p) const;
39 // IMPLEMENTATION
41 template <typename GameState>
42 LegalityCheck<GameState>::LegalityCheck(const GameState& state)
43 : Base(state) { }
45 template <typename GameState>
46 bool LegalityCheck<GameState>::getMoveType(const Piece& piece, const Move& move) const {
47 if (!move.valid())
48 return false;
50 if (move.from() == move.to())
51 return false;
53 if (Base::m_state.board().get(move.to()).color() == piece.color())
54 return false;
55 Point delta = move.to() - move.from();
57 if (!piece.promoted()) {
58 switch (piece.type()) {
59 case Piece::PHOENIX:
60 return abs(delta.x) <= 1 && abs(delta.y) <= 1;
61 case Piece::FALCON:
62 return (abs(delta.x) == 1 && abs(delta.y) <= 1)
63 || (delta.x == 0 && delta.y == Base::m_state.direction(piece.color()).y);
64 case Piece::CRANE:
65 return (abs(delta.y) == 1 && abs(delta.x) <= 1);
66 case Piece::PHEASANT:
67 return (delta.x == 0 && delta.y == 2 * Base::m_state.direction(piece.color()).y)
68 || (abs(delta.x) == 1 && delta.y == -Base::m_state.direction(piece.color()).y);
70 case Piece::SWALLOW:
71 return delta == Base::m_state.direction(piece.color());
73 case Piece::RIGHT_QUAIL:
75 if (delta.x == 1 && delta.y == -Base::m_state.direction(piece.color()).y)
76 return true;
77 PathInfo path = Base::m_state.board().path(move.from(), move.to());
78 return ((path.parallel() && delta.y * Base::m_state.direction(piece.color()).y > 0) ||
79 (path.diagonal() && delta.y * Base::m_state.direction(piece.color()).y < 0
80 && delta.x < 0)) && path.clear();
82 case Piece::LEFT_QUAIL:
84 if (delta.x == -1 && delta.y == -Base::m_state.direction(piece.color()).y)
85 return true;
86 PathInfo path = Base::m_state.board().path(move.from(), move.to());
87 return ((path.parallel() && delta.y * Base::m_state.direction(piece.color()).y > 0) ||
88 (path.diagonal() && delta.y * Base::m_state.direction(piece.color()).y < 0
89 && delta.x > 0)) && path.clear();
92 default:
93 return false;
96 else {
97 switch (piece.type()) {
98 case Piece::SWALLOW: // Goose
99 return (delta.x == 0 && delta.y == -2 * Base::m_state.direction(piece.color()).y)
100 || (abs(delta.x) == 2 && delta.y == 2 * Base::m_state.direction(piece.color()).y);
102 case Piece::FALCON: // Eagle
104 if (abs(delta.x) <= 1 && abs(delta.y) <= 1)
105 return true;
106 PathInfo path = Base::m_state.board().path(move.from(), move.to());
107 return ((path.parallel() && delta.y * Base::m_state.direction(piece.color()).y < 0) ||
108 (path.diagonal() && delta.y * Base::m_state.direction(piece.color()).y > 0) ||
109 (path.diagonal() && delta.y * Base::m_state.direction(piece.color()).y == -2)) &&
110 path.clear();
112 default:
113 return false;
118 template <typename GameState>
119 bool LegalityCheck<GameState>::pseudolegal(Move& move) const {
120 if (move.drop() == Piece() &&
121 move.pool() != -1 &&
122 move.index() != -1) {
123 move.setDrop(Base::m_state.pools().pool(move.pool()).get(move.index()));
126 Piece dropped = move.drop();
127 if (dropped != Piece()) {
128 if (Base::m_state.board().get(move.to()) != Piece())
129 return false;
131 if (stuckPiece(dropped, move.to()))
132 return false;
134 if (dropped.type() == Piece::SWALLOW) {
135 int otherswallows = 0;
136 for (int i = 0; i < Base::m_state.board().size().y; i++) {
137 Piece other = Base::m_state.board().get(Point(move.to().x, i));
138 if (other.type() == Piece::SWALLOW &&
139 other.color() == Base::m_state.turn() &&
140 !other.promoted()) {
141 otherswallows++;
142 if (otherswallows >= 2)
143 return false;
148 return true;
150 else {
151 Piece piece = Base::m_state.board().get(move.from());
152 if (piece != Piece() && getMoveType(piece, move)) {
153 if (Base::m_state.canPromote(piece) &&
154 (Base::m_state.promotionZone(piece.color(), move.to()) ||
155 Base::m_state.promotionZone(piece.color(), move.from())))
156 move.setType(Move::PROMOTION);
157 return true;
159 else {
160 //std::cerr << "CANNOT MOVE: piece type cannot go there";
161 return false;
167 template <typename GameState>
168 bool LegalityCheck<GameState>::legal(Move& move) const {
169 if (!pseudolegal(move))
170 return false;
172 GameState tmp(Base::m_state);
173 tmp.move(move);
175 // find king and prince positions
176 Point king_pos = tmp.board().find(Piece(Base::m_state.turn(), Piece::PHOENIX));
178 if (!king_pos.valid())
179 return false;
181 // check if the king can be captured
182 if (Base::canBeCaptured(tmp, king_pos))
183 return false;
185 return true;
188 template <typename GameState>
189 bool LegalityCheck<GameState>::stuckPiece(const Piece& piece, const Point& p) const {
190 if (piece.type() == Piece::SWALLOW) {
191 return p.y == Base::m_state.startingRank(Piece::oppositeColor(piece.color()));
193 else {
194 return false;
198 } // namespace ToriShogi
199 } // namespace HLVariant
201 #endif // HLVARIANT__TORISHOGI__LEGALITYCHECK_H