A crazyhouse game on ICS can now be started.
[tagua/yd.git] / src / variants / chess.cpp
blob24ac31b5e73b04f6b7a0afec05d432017337802e
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 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 <QPainter>
12 #include <boost/shared_ptr.hpp>
13 #include "variants/chess.h"
14 #include "common.h"
15 #include "tagua_wrapped.h"
16 #include "moveserializer.impl.h"
17 #include "xchess/animator.impl.h"
18 #include "piecefunction.h"
19 #include "animation.h"
21 using namespace boost;
22 typedef boost::shared_ptr<class Animation> AnimationPtr;
24 const char *ChessVariant::m_name = "Chess";
25 const char *ChessVariant::m_theme_proxy = "Chess";
26 VariantInfo* ChessVariant::static_chess_variant = 0;
28 #if 0
29 class ChessAnimator {
30 ChessGraphicalAPI::Ptr m_cinterface;
31 public:
32 ChessAnimator(ChessGraphicalAPI::Ptr cinterface)
33 : m_cinterface(cinterface) {
36 AnimationGroupPtr warp(const ChessPosition& final) {
37 const ChessPosition* current = m_cinterface->position();
38 AnimationFactory res(m_cinterface->inner());
40 for (Point i = current->first(); i <= current->last(); i = current->next(i)) {
41 ChessPiece c = current->get(i);
42 ChessPiece f = final.get(i);
44 if( !c && f ) {
45 //current->set(i, f);
46 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
47 res.addPreAnimation(Animate::appear(sprite), Animate::Instant);
49 else if (c && !f) {
50 NamedSprite old_sprite = m_cinterface->takeSprite(i);
51 res.addPreAnimation(Animate::disappear(old_sprite), Animate::Instant);
53 else if(c && f && !(c == f) ) {
54 NamedSprite old_sprite = m_cinterface->takeSprite(i);
55 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
56 res.addPreAnimation(Animate::morph(old_sprite, sprite), Animate::Instant);
60 //BROKEN: implement pool update
63 return res;
66 boost::shared_ptr<AnimationGroup> forward(const ChessPosition& final, const ChessMove& move) {
67 AnimationFactory res(m_cinterface->inner());
69 NamedSprite piece = m_cinterface->takeSprite(move.from);
70 NamedSprite captured = m_cinterface->takeSprite(move.to);
71 m_cinterface->setSprite(move.to, piece);
73 if (piece) {
74 bool knight = m_cinterface->position()->get(move.from).type() == KNIGHT;
75 int mtype = knight
76 ? Animate::move::LShaped | Animate::move::Rotating
77 : Animate::move::Straight;
78 res.addPreAnimation(Animate::move(piece, move.to, mtype));
80 else
81 ERROR("Bug!!!");
83 if (captured)
84 res.addPostAnimation(Animate::destroy(captured));
86 if (move.type() == ChessMove::EnPassantCapture) {
87 Point phantom(move.to.x, move.from.y);
88 NamedSprite capturedPawn = m_cinterface->takeSprite(phantom);
90 if (capturedPawn) {
91 QPoint real = m_cinterface->converter()->toReal(phantom);
92 res.addPostAnimation(Animate::disappear(capturedPawn));
94 else
95 ERROR("Bug!!!");
97 else if (move.type() == ChessMove::Promotion) {
98 ChessPiece promoted = final.get(move.to);
100 if (promoted) {
101 QPoint real = m_cinterface->converter()->toReal(move.to);
102 NamedSprite old_sprite = m_cinterface->getSprite(move.to);
103 NamedSprite new_sprite = m_cinterface->setPiece(move.to, promoted, /*false,*/ false);
105 res.addPostAnimation(Animate::morph(old_sprite, new_sprite));
107 else
108 ERROR("Bug!!!");
110 else if (move.type() == ChessMove::KingSideCastling) {
111 Point rookSquare = move.to + Point(1,0);
112 Point rookDestination = move.from + Point(1,0);
114 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
115 m_cinterface->setSprite(rookDestination, rook);
116 res.addPreAnimation(Animate::move(rook, rookDestination));
118 else if (move.type() == ChessMove::QueenSideCastling) {
119 Point rookSquare = move.to + Point(-2,0);
120 Point rookDestination = move.from + Point(-1,0);
122 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
123 m_cinterface->setSprite(rookDestination, rook);
124 res.addPreAnimation(Animate::move(rook, rookDestination));
127 return res;
130 boost::shared_ptr<AnimationGroup> back(const ChessPosition& final, const ChessMove& move) {
131 AnimationFactory res(m_cinterface->inner());
133 NamedSprite piece = m_cinterface->takeSprite(move.to);
134 NamedSprite captured;
135 if (ChessPiece captured_piece = final.get(move.to)) {
136 captured = m_cinterface->setPiece(move.to, captured_piece, false);
137 res.addPreAnimation(Animate::appear(captured));
140 if (!piece) {
141 piece = m_cinterface->createPiece(move.to, final.get(move.from), false);
142 res.addPreAnimation(Animate::appear(piece));
145 m_cinterface->setSprite(move.from, piece);
148 if (move.type() == ChessMove::EnPassantCapture) {
149 Point phantom(move.to.x, move.from.y);
151 if (ChessPiece pawn_piece = final.get(phantom)) {
152 NamedSprite captured_pawn = m_cinterface->setPiece(phantom, pawn_piece, false);
153 res.addPreAnimation(Animate::appear(captured_pawn));
156 else if (move.type() == ChessMove::Promotion) {
157 ChessPiece pawn_piece = final.get(move.from);
158 if (pawn_piece) {
159 NamedSprite pawn = m_cinterface->createPiece(move.to, pawn_piece, false);
160 res.addPreAnimation(Animate::morph(piece, pawn));
161 // replace piece with pawn
162 m_cinterface->setSprite(move.from, pawn);
163 piece = pawn;
166 else if (move.type() == ChessMove::KingSideCastling) {
167 Point rookSquare = move.to + Point(1,0);
168 Point rookDestination = move.from + Point(1,0);
170 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
171 m_cinterface->setSprite(rookSquare, rook);
173 res.addPreAnimation(Animate::move(rook, rookSquare));
175 else if (move.type() == ChessMove::QueenSideCastling) {
176 Point rookSquare = move.to + Point(-2,0);
177 Point rookDestination = move.from + Point(-1,0);
179 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
180 m_cinterface->setSprite(rookSquare, rook);
182 res.addPreAnimation(Animate::move(rook, rookSquare));
186 bool knight = m_cinterface->position()->get(move.to).type() == KNIGHT;
187 int mtype = knight
188 ? Animate::move::LShaped | Animate::move::Rotating
189 : Animate::move::Straight;
190 res.addPreAnimation(Animate::move(piece, move.from, mtype));
192 return res;
195 #endif
197 void ChessVariant::forallPieces(PieceFunction& f) {
198 f(WHITE, KING);
199 f(WHITE, QUEEN);
200 f(WHITE, ROOK);
201 f(WHITE, BISHOP);
202 f(WHITE, KNIGHT);
203 f(WHITE, PAWN);
204 f(BLACK, KING);
205 f(BLACK, QUEEN);
206 f(BLACK, ROOK);
207 f(BLACK, BISHOP);
208 f(BLACK, KNIGHT);
209 f(BLACK, PAWN);
212 VariantInfo* ChessVariant::info() {
213 if (!static_chess_variant)
214 static_chess_variant = new WrappedVariantInfo<ChessVariant>;
215 return static_chess_variant;
218 // piece factory
219 template <>
220 class PieceFactory<ChessVariant> {
221 public:
222 static ChessPiece createPiece(const QString& description) {
223 return ChessPiece::fromDescription(description);