Tentative Randomless-Entropy variant.
[tagua/yd.git] / src / variants / chess / castlingrules.cpp
blobc13a1924848cffa0d85b986331b1b1b831c20f90
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)) == Piece() &&
35 state->board()->get(move.dst()) == Piece() &&
36 state->flags()->get(piece.color()->name() + "_king_castling").toBool()) {
37 move.setType("king_castling");
38 return true;
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");
47 return true;
51 return false;
54 bool CastlingRules::handleCastling(const Piece& piece, const Move& move, IState* state) const {
55 const IBehaviour* behaviour = state->behaviour();
56 bool res = true;
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));
70 else {
71 res = false;
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);
91 return res;
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);
97 return Point(x, y);
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)
108 , m_own(own) { }
110 CastlingRulesAdaptor::~CastlingRulesAdaptor() {
111 if (m_own) delete m_component;
114 bool CastlingRulesAdaptor::canCastle(const Piece& piece, Move& move, const IState* state) const {
115 bool result;
116 QMetaObject::invokeMethod(m_component, "canCastle",
117 Q_RETURN_ARG(bool, result),
118 Q_ARG(Piece, piece),
119 Q_ARG(Move, move),
120 Q_ARG(const IState*, state));
121 return result;
124 bool CastlingRulesAdaptor::handleCastling(const Piece& piece, const Move& move, IState* state) const {
125 bool result;
126 QMetaObject::invokeMethod(m_component, "handleCastling",
127 Q_RETURN_ARG(bool, result),
128 Q_ARG(Piece, piece),
129 Q_ARG(Move, move),
130 Q_ARG(IState*, state));
131 return result;
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 {
139 Point res;
140 QMetaObject::invokeMethod(m_component, "kingStartingPosition",
141 Q_RETURN_ARG(Point, res),
142 Q_ARG(const IState*, state),
143 Q_ARG(const IColor*, player));
144 return res;
148 } // namespace Chess