new 4475edb243ed4627f4c5f2c470ca40b3def034d4
[tagua/yd.git] / src / variants / chess / castlingrules.cpp
blob03783a941cd10e3628b4dc796cb7718cfbb3d5e3
1 /*
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.
8 */
10 #include "castlingrules.h"
12 #include <KDebug>
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>
21 #include "types.h"
23 namespace Chess {
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");
40 return true;
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");
52 return true;
56 return false;
59 bool CastlingRules::handleCastling(const Piece& piece, const Move& move, IState* state) const {
60 const IBehaviour* behaviour = state->behaviour();
61 bool res = true;
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));
75 else {
76 res = false;
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);
96 return res;
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);
102 return Point(x, y);
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)
113 , m_own(own) { }
115 CastlingRulesAdaptor::~CastlingRulesAdaptor() {
116 if (m_own) delete m_component;
119 bool CastlingRulesAdaptor::canCastle(const Piece& piece, Move& move, const IState* state) const {
120 bool result;
121 QMetaObject::invokeMethod(m_component, "canCastle",
122 Q_RETURN_ARG(bool, result),
123 Q_ARG(Piece, piece),
124 Q_ARG(Move, move),
125 Q_ARG(const IState*, state));
126 return result;
129 bool CastlingRulesAdaptor::handleCastling(const Piece& piece, const Move& move, IState* state) const {
130 bool result;
131 QMetaObject::invokeMethod(m_component, "handleCastling",
132 Q_RETURN_ARG(bool, result),
133 Q_ARG(Piece, piece),
134 Q_ARG(Move, move),
135 Q_ARG(IState*, state));
136 return result;
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 {
144 Point res;
145 QMetaObject::invokeMethod(m_component, "kingStartingPosition",
146 Q_RETURN_ARG(Point, res),
147 Q_ARG(const IState*, state),
148 Q_ARG(const IColor*, player));
149 return res;
153 } // namespace Chess