De-constify piece types.
[tagua/yd.git] / src / variants / chess / state.cpp
blob648316e7a026e80afd9e3b83a204981e9d703382
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 : Component()
36 , IState()
37 , m_board(other.m_board)
38 , m_flags(other.m_flags)
39 , m_turn(other.m_turn)
40 , m_behaviour(other.m_behaviour)
41 , m_castling_rules(other.m_castling_rules)
42 , m_delegator(this) { }
44 IState* State::clone() const {
45 return new State(*this);
48 void State::setup() {
49 for (int c = 0; c < 2; c++) {
50 IColor* color = COLORS[c];
51 int r0 = rank(0, color);
52 int r1 = rank(1, color);
54 for (int i = 0; i < m_board.size().x; i++) {
55 m_board.set(Point(i, r1), Piece(color, Pawn::self()));
57 m_board.set(Point(0, r0), Piece(color, Rook::self()));
58 m_board.set(Point(1, r0), Piece(color, Knight::self()));
59 m_board.set(Point(2, r0), Piece(color, Bishop::self()));
60 m_board.set(Point(3, r0), Piece(color, Queen::self()));
61 m_board.set(Point(4, r0), Piece(color, King::self()));
62 m_board.set(Point(5, r0), Piece(color, Bishop::self()));
63 m_board.set(Point(6, r0), Piece(color, Knight::self()));
64 m_board.set(Point(7, r0), Piece(color, Rook::self()));
67 m_turn = White::self();
70 const Board* State::board() const {
71 return &m_board;
74 Board* State::board() {
75 return &m_board;
78 const IColor* State::turn() const {
79 return m_turn;
82 void State::setTurn(const IColor* turn) {
83 m_turn = turn;
86 bool State::equals(IState* other) const {
87 return m_board.equals(other->board()) &&
88 m_turn == other->turn() &&
89 m_flags == *other->flags();
92 void State::assign(const IState* other) {
93 m_board = *other->board();
94 m_turn = other->turn();
95 m_flags = *other->flags();
98 void State::move(const Move& m) {
99 const Piece* piece = m_board.get(m.src());
100 if (piece == NULL || *piece == Piece()) return;
102 Point captureSquare = behaviour()->captureSquare(this, m);
103 behaviour()->captureOn(m_delegator, captureSquare);
104 behaviour()->move(m_delegator, m);
106 m_flags.set("en_passant_square", QVariant(enPassantTrigger(m)));
107 IType* promotion_type = m.promotion();
109 if (promotion_type != 0) {
110 m_board.set(m.dst(), Piece(piece->color(), promotion_type));
113 if (m_castling_rules)
114 m_castling_rules->handleCastling(*piece, m, m_delegator);
115 behaviour()->advanceTurn(m_delegator);
118 const TaguaObject* State::flags() const { return &m_flags; }
119 TaguaObject* State::flags() { return &m_flags; }
121 int State::rank(int n, const IColor* turn) const {
122 if (turn == White::self())
123 return m_board.size().y - n - 1;
124 else
125 return n;
128 IPoolCollection* State::pools() { return 0; }
129 const IPoolCollection* State::pools() const { return 0; }
131 const IBehaviour* State::behaviour() const { return m_behaviour; }
133 Point State::enPassantTrigger(const Move& move) const {
134 if (move.type() == "en_passant_trigger")
135 return (move.dst() + move.src()) / 2;
136 else
137 return Point::invalid();
140 void State::setDelegator(IState* delegator) { m_delegator = delegator; }
142 Component* State::clone(const IBehaviour* behaviour,
143 Component* castling,
144 const Point& size) const {
145 const ICastlingRules* rules = dynamic_cast<const ICastlingRules*>(castling);
146 if (!rules) rules = new CastlingRulesAdaptor(castling, false);
147 return new State(behaviour, rules, size);
150 } // namespace Chess