3 #include <core/behaviour.h>
4 #include <core/board.h>
6 #include <core/state.h>
13 Validator::Validator() : m_delegator(this) { }
15 bool Validator::pseudolegal(const IState
* state
, Move
& move
) const {
16 if (!state
->board()->valid(move
.src())) return false;
17 if (!state
->board()->valid(move
.dst())) return false;
19 Piece piece
= state
->board()->get(move
.src());
20 if (piece
== Piece()) return false;
22 const IBehaviour
* behaviour
= state
->behaviour();
23 if (!behaviour
) return false;
25 const IColor
* thisTurn
= piece
.color();
26 const IColor
* otherTurn
= behaviour
->opponent(thisTurn
);
28 if (state
->turn() != thisTurn
) return false;
30 Piece target
= state
->board()->get(move
.dst());
31 if (target
.color() == piece
.color())
33 if (!piece
.type()->canMove(piece
, target
, move
, state
))
36 if (move
.type() == "promotion") {
37 const IType
* promotionType
= move
.promotion();
38 if (promotionType
!= Queen::self() &&
39 promotionType
!= Bishop::self() &&
40 promotionType
!= Rook::self() &&
41 promotionType
!= Knight::self()) return false;
44 if (move
.type() == "king_side_castling") {
45 if (m_delegator
->attacks(state
, otherTurn
, move
.src()) ||
46 m_delegator
->attacks(state
, otherTurn
, move
.src() + Point(1, 0), piece
))
49 if (move
.type() == "queen_side_castling") {
50 if (m_delegator
->attacks(state
, otherTurn
, move
.src()) ||
51 m_delegator
->attacks(state
, otherTurn
, move
.src() + Point(-1, 0), piece
))
58 bool Validator::legal(const IState
* state
, Move
& move
) const {
59 // do not check a move more than once
60 if (!move
.type().isEmpty()) return true;
62 if (!m_delegator
->pseudolegal(state
, move
))
65 const IBehaviour
* behaviour
= state
->behaviour();
66 if (!behaviour
) return false;
68 const IColor
* turn
= m_delegator
->mover(state
, move
);
70 IState
* tmp
= state
->clone();
74 Point kingPos
= tmp
->board()->find(Piece(turn
, King::self()));
76 if (kingPos
== Point::invalid()) {
81 if (m_delegator
->attacks(tmp
, behaviour
->opponent(turn
), kingPos
)) {
88 // set move type as normal, if not already set
89 if (move
.type().isEmpty()) move
.setType("normal");
93 bool Validator::attacks(const IState
* state
, const IColor
* player
,
94 const Point
& square
, const Piece
& target_
) const {
96 if (target_
!= Piece())
99 target
= state
->board()->get(square
);
101 for (int i
= 0; i
< state
->board()->size().x
; i
++) {
102 for (int j
= 0; j
< state
->board()->size().y
; j
++) {
104 const Piece piece
= state
->board()->get(p
);
105 Move
move(p
, square
);
106 if (piece
!= Piece() &&
107 piece
.color() == player
&&
108 piece
.type()->canMove(piece
, target
, move
, state
))
115 const IColor
* Validator::mover(const IState
* state
, const Move
& move
) const {
116 return state
->board()->get(move
.src()).color();
119 void Validator::setDelegator(IValidator
* delegator
) {
120 m_delegator
= delegator
;