Make component interfaces inherit Component.
[tagua/yd.git] / src / variants / chess / state.cpp
blob27ee75b309942948681b23ef9fc3312bc0262a34
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "state.h"
13 #include <core/behaviour.h>
14 #include <core/move.h>
15 #include "castlingrules.h"
16 #include "colors.h"
17 #include "types.h"
19 namespace Chess {
21 State::State(const IBehaviour* behaviour,
22 const ICastlingRules* castling,
23 const Point& size)
24 : m_board(size)
25 , m_behaviour(behaviour)
26 , m_castling_rules(castling)
27 , m_delegator(this) {
28 m_flags.set("white_king_castling", true);
29 m_flags.set("white_queen_castling", true);
30 m_flags.set("black_king_castling", true);
31 m_flags.set("black_queen_castling", true);
34 State::State(const State& other)
35 : IState()
36 , m_board(other.m_board)
37 , m_flags(other.m_flags)
38 , m_turn(other.m_turn)
39 , m_behaviour(other.m_behaviour)
40 , m_castling_rules(other.m_castling_rules)
41 , m_delegator(this) { }
43 IState* State::clone() const {
44 return new State(*this);
47 void State::setup() {
48 for (int c = 0; c < 2; c++) {
49 IColor* color = COLORS[c];
50 int r0 = rank(0, color);
51 int r1 = rank(1, color);
53 for (int i = 0; i < m_board.size().x; i++) {
54 m_board.set(Point(i, r1), Piece(color, Pawn::self()));
56 m_board.set(Point(0, r0), Piece(color, Rook::self()));
57 m_board.set(Point(1, r0), Piece(color, Knight::self()));
58 m_board.set(Point(2, r0), Piece(color, Bishop::self()));
59 m_board.set(Point(3, r0), Piece(color, Queen::self()));
60 m_board.set(Point(4, r0), Piece(color, King::self()));
61 m_board.set(Point(5, r0), Piece(color, Bishop::self()));
62 m_board.set(Point(6, r0), Piece(color, Knight::self()));
63 m_board.set(Point(7, r0), Piece(color, Rook::self()));
66 m_turn = White::self();
69 const Board* State::board() const {
70 return &m_board;
73 Board* State::board() {
74 return &m_board;
77 const IColor* State::turn() const {
78 return m_turn;
81 void State::setTurn(const IColor* turn) {
82 m_turn = turn;
85 bool State::equals(IState* other) const {
86 return m_board.equals(other->board()) &&
87 m_turn == other->turn() &&
88 m_flags == *other->flags();
91 void State::assign(const IState* other) {
92 m_board = *other->board();
93 m_turn = other->turn();
94 m_flags = *other->flags();
97 void State::move(const Move& m) {
98 Piece piece = m_board.get(m.src());
99 if (piece == Piece()) return;
101 Point captureSquare = behaviour()->captureSquare(this, m);
102 behaviour()->captureOn(m_delegator, captureSquare);
103 behaviour()->move(m_delegator, m);
105 m_flags.set("en_passant_square", QVariant(enPassantTrigger(m)));
106 const IType* promotion_type = m.promotion();
108 if (promotion_type != 0) {
109 m_board.set(m.dst(), Piece(piece.color(), promotion_type));
112 if (m_castling_rules)
113 m_castling_rules->handleCastling(piece, m, m_delegator);
114 behaviour()->advanceTurn(m_delegator);
117 const TaguaObject* State::flags() const { return &m_flags; }
118 TaguaObject* State::flags() { return &m_flags; }
120 int State::rank(int n, const IColor* turn) const {
121 if (turn == White::self())
122 return m_board.size().y - n - 1;
123 else
124 return n;
127 IPoolCollection* State::pools() { return 0; }
128 const IPoolCollection* State::pools() const { return 0; }
130 const IBehaviour* State::behaviour() const { return m_behaviour; }
132 Point State::enPassantTrigger(const Move& move) const {
133 if (move.type() == "en_passant_trigger")
134 return (move.dst() + move.src()) / 2;
135 else
136 return Point::invalid();
139 void State::setDelegator(IState* delegator) { m_delegator = delegator; }
141 Component* State::clone(const IBehaviour* behaviour,
142 Component* castling,
143 const Point& size) const {
144 const ICastlingRules* rules = dynamic_cast<const ICastlingRules*>(castling);
145 if (!rules) rules = new CastlingRulesAdaptor(castling, false);
146 return new State(behaviour, rules, size);
149 } // namespace Chess