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)) == Piece() &&
35 state
->board()->get(move
.dst()) == Piece() &&
36 state
->flags()->get(piece
.color()->name() + "_king_castling").toBool()) {
37 move
.setType("king_castling");
41 else if (move
.delta() == Point(-2,0)) {
42 if (state
->board()->get(move
.src() - Point(1, 0)) == Piece() &&
43 state
->board()->get(move
.dst() + Point(1, 0)) == Piece() &&
44 state
->board()->get(move
.dst()) == Piece() &&
45 state
->flags()->get(piece
.color()->name() + "_queen_castling").toBool()) {
46 move
.setType("queen_castling");
54 bool CastlingRules::handleCastling(const Piece
& piece
, const Move
& move
, IState
* state
) const {
55 const IBehaviour
* behaviour
= state
->behaviour();
58 if (behaviour
&& move
.type() == "king_castling") {
59 Point rookSquare
= move
.dst() + Point(1,0);
60 Point rookDestination
= move
.src() + Point(1,0);
62 behaviour
->move(state
, Move(rookSquare
, rookDestination
));
64 else if (behaviour
&& move
.type() == "queen_castling") {
65 Point rookSquare
= move
.dst() - Point(2,0);
66 Point rookDestination
= move
.src() - Point(1,0);
68 behaviour
->move(state
, Move(rookSquare
, rookDestination
));
74 const IType
* type
= piece
.type();
75 TaguaObject
* flags
= state
->flags();
77 if (type
== King::self()) {
78 flags
->set(piece
.color()->name() + "_king_castling", false);
79 flags
->set(piece
.color()->name() + "_queen_castling", false);
82 if (move
.src() == Point(0,0) || move
.dst() == Point(0,0))
83 flags
->set("black_queen_castling", false);
84 if (move
.src() == Point(7,0) || move
.dst() == Point(7,0))
85 flags
->set("black_king_castling", false);
86 if (move
.src() == Point(0,7) || move
.dst() == Point(0,7))
87 flags
->set("white_queen_castling", false);
88 if (move
.src() == Point(7,7) || move
.dst() == Point(7,7))
89 flags
->set("white_king_castling", false);
94 Point
CastlingRules::kingStartingPosition(const IState
* state
, const IColor
* player
) const {
95 int x
= state
->board()->size().x
/ 2;
96 int y
= state
->rank(0, player
);
100 void CastlingRules::setDelegator(Component
* delegator
) {
101 m_delegator
= dynamic_cast<ICastlingRules
*>(delegator
);
102 if (!m_delegator
) m_delegator
= new CastlingRulesAdaptor(delegator
, false);
106 CastlingRulesAdaptor::CastlingRulesAdaptor(Component
* component
, bool own
)
107 : m_component(component
)
110 CastlingRulesAdaptor::~CastlingRulesAdaptor() {
111 if (m_own
) delete m_component
;
114 bool CastlingRulesAdaptor::canCastle(const Piece
& piece
, Move
& move
, const IState
* state
) const {
116 QMetaObject::invokeMethod(m_component
, "canCastle",
117 Q_RETURN_ARG(bool, result
),
120 Q_ARG(const IState
*, state
));
124 bool CastlingRulesAdaptor::handleCastling(const Piece
& piece
, const Move
& move
, IState
* state
) const {
126 QMetaObject::invokeMethod(m_component
, "handleCastling",
127 Q_RETURN_ARG(bool, result
),
130 Q_ARG(IState
*, state
));
134 void CastlingRulesAdaptor::setDelegator(Component
* component
) {
135 QMetaObject::invokeMethod(m_component
, "setDelegator", Q_ARG(Component
*, component
));
138 Point
CastlingRulesAdaptor::kingStartingPosition(const IState
* state
, const IColor
* player
) const {
140 QMetaObject::invokeMethod(m_component
, "kingStartingPosition",
141 Q_RETURN_ARG(Point
, res
),
142 Q_ARG(const IState
*, state
),
143 Q_ARG(const IColor
*, player
));