2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
10 #include "castlingrules.h"
14 #include <core/behaviour.h>
15 #include <core/board.h>
16 #include <core/color.h>
17 #include <core/move.h>
18 #include <core/piece.h>
19 #include <core/state.h>
25 ICastlingRules::~ICastlingRules() { }
27 CastlingRules::CastlingRules()
28 : m_delegator(this) { }
30 bool CastlingRules::canCastle(const Piece
& piece
, Move
& move
, const IState
* state
) const {
31 if (move
.src() != m_delegator
->kingStartingPosition(state
, piece
.color())) return false;
33 if (move
.delta() == Point(2,0)) {
34 if ((state
->board()->get(move
.src() + Point(1,0)) == NULL
||
35 *state
->board()->get(move
.src() + Point(1,0)) == Piece()) &&
36 (state
->board()->get(move
.dst()) == NULL
||
37 *state
->board()->get(move
.dst()) == Piece()) &&
38 state
->flags()->get(piece
.color()->name() + "_king_castling").toBool()) {
39 move
.setType("king_castling");
43 else if (move
.delta() == Point(-2,0)) {
44 if ((state
->board()->get(move
.src() - Point(1, 0)) == NULL
||
45 *state
->board()->get(move
.src() - Point(1, 0)) == Piece()) &&
46 (state
->board()->get(move
.dst() + Point(1, 0)) == NULL
||
47 *state
->board()->get(move
.dst() + Point(1, 0)) == Piece()) &&
48 (state
->board()->get(move
.dst()) == NULL
||
49 *state
->board()->get(move
.dst()) == Piece()) &&
50 state
->flags()->get(piece
.color()->name() + "_queen_castling").toBool()) {
51 move
.setType("queen_castling");
59 bool CastlingRules::handleCastling(const Piece
& piece
, const Move
& move
, IState
* state
) const {
60 const IBehaviour
* behaviour
= state
->behaviour();
63 if (behaviour
&& move
.type() == "king_castling") {
64 Point rookSquare
= move
.dst() + Point(1,0);
65 Point rookDestination
= move
.src() + Point(1,0);
67 behaviour
->move(state
, Move(rookSquare
, rookDestination
));
69 else if (behaviour
&& move
.type() == "queen_castling") {
70 Point rookSquare
= move
.dst() - Point(2,0);
71 Point rookDestination
= move
.src() - Point(1,0);
73 behaviour
->move(state
, Move(rookSquare
, rookDestination
));
79 const IType
* type
= piece
.type();
80 TaguaObject
* flags
= state
->flags();
82 if (type
== King::self()) {
83 flags
->set(piece
.color()->name() + "_king_castling", false);
84 flags
->set(piece
.color()->name() + "_queen_castling", false);
87 if (move
.src() == Point(0,0) || move
.dst() == Point(0,0))
88 flags
->set("black_queen_castling", false);
89 if (move
.src() == Point(7,0) || move
.dst() == Point(7,0))
90 flags
->set("black_king_castling", false);
91 if (move
.src() == Point(0,7) || move
.dst() == Point(0,7))
92 flags
->set("white_queen_castling", false);
93 if (move
.src() == Point(7,7) || move
.dst() == Point(7,7))
94 flags
->set("white_king_castling", false);
99 Point
CastlingRules::kingStartingPosition(const IState
* state
, const IColor
* player
) const {
100 int x
= state
->board()->size().x
/ 2;
101 int y
= state
->rank(0, player
);
105 void CastlingRules::setDelegator(Component
* delegator
) {
106 m_delegator
= dynamic_cast<ICastlingRules
*>(delegator
);
107 if (!m_delegator
) m_delegator
= new CastlingRulesAdaptor(delegator
, false);
111 CastlingRulesAdaptor::CastlingRulesAdaptor(Component
* component
, bool own
)
112 : m_component(component
)
115 CastlingRulesAdaptor::~CastlingRulesAdaptor() {
116 if (m_own
) delete m_component
;
119 bool CastlingRulesAdaptor::canCastle(const Piece
& piece
, Move
& move
, const IState
* state
) const {
121 QMetaObject::invokeMethod(m_component
, "canCastle",
122 Q_RETURN_ARG(bool, result
),
125 Q_ARG(const IState
*, state
));
129 bool CastlingRulesAdaptor::handleCastling(const Piece
& piece
, const Move
& move
, IState
* state
) const {
131 QMetaObject::invokeMethod(m_component
, "handleCastling",
132 Q_RETURN_ARG(bool, result
),
135 Q_ARG(IState
*, state
));
139 void CastlingRulesAdaptor::setDelegator(Component
* component
) {
140 QMetaObject::invokeMethod(m_component
, "setDelegator", Q_ARG(Component
*, component
));
143 Point
CastlingRulesAdaptor::kingStartingPosition(const IState
* state
, const IColor
* player
) const {
145 QMetaObject::invokeMethod(m_component
, "kingStartingPosition",
146 Q_RETURN_ARG(Point
, res
),
147 Q_ARG(const IState
*, state
),
148 Q_ARG(const IColor
*, player
));