Ported Animator, UnwrappedGraphicalApi and MoveFactory.
[tagua/yd.git] / src / variants / chess.cpp
blob089d80e86d9bf236dc35b48705aa26b63bd65338
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 "icsapi.impl.h"
17 #include "moveserializer.impl.h"
18 #include "xchess/animator.impl.h"
19 #include "piecefunction.h"
20 #include "animation.h"
22 using namespace boost;
23 typedef boost::shared_ptr<class Animation> AnimationPtr;
25 const char *ChessVariant::m_name = "Chess_OLD";
26 const char *ChessVariant::m_theme_proxy = "Chess_OLD";
27 VariantInfo* ChessVariant::static_chess_variant = 0;
29 #if 0
30 class ChessAnimator {
31 ChessGraphicalAPI::Ptr m_cinterface;
32 public:
33 ChessAnimator(ChessGraphicalAPI::Ptr cinterface)
34 : m_cinterface(cinterface) {
37 AnimationGroupPtr warp(const ChessPosition& final) {
38 const ChessPosition* current = m_cinterface->position();
39 AnimationFactory res(m_cinterface->inner());
41 for (Point i = current->first(); i <= current->last(); i = current->next(i)) {
42 ChessPiece c = current->get(i);
43 ChessPiece f = final.get(i);
45 if( !c && f ) {
46 //current->set(i, f);
47 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
48 res.addPreAnimation(Animate::appear(sprite), Animate::Instant);
50 else if (c && !f) {
51 NamedSprite old_sprite = m_cinterface->takeSprite(i);
52 res.addPreAnimation(Animate::disappear(old_sprite), Animate::Instant);
54 else if(c && f && !(c == f) ) {
55 NamedSprite old_sprite = m_cinterface->takeSprite(i);
56 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
57 res.addPreAnimation(Animate::morph(old_sprite, sprite), Animate::Instant);
61 //BROKEN: implement pool update
64 return res;
67 boost::shared_ptr<AnimationGroup> forward(const ChessPosition& final, const ChessMove& move) {
68 AnimationFactory res(m_cinterface->inner());
70 NamedSprite piece = m_cinterface->takeSprite(move.from);
71 NamedSprite captured = m_cinterface->takeSprite(move.to);
72 m_cinterface->setSprite(move.to, piece);
74 if (piece) {
75 bool knight = m_cinterface->position()->get(move.from).type() == KNIGHT;
76 int mtype = knight
77 ? Animate::move::LShaped | Animate::move::Rotating
78 : Animate::move::Straight;
79 res.addPreAnimation(Animate::move(piece, move.to, mtype));
81 else
82 ERROR("Bug!!!");
84 if (captured)
85 res.addPostAnimation(Animate::destroy(captured));
87 if (move.type() == ChessMove::EnPassantCapture) {
88 Point phantom(move.to.x, move.from.y);
89 NamedSprite capturedPawn = m_cinterface->takeSprite(phantom);
91 if (capturedPawn) {
92 QPoint real = m_cinterface->converter()->toReal(phantom);
93 res.addPostAnimation(Animate::disappear(capturedPawn));
95 else
96 ERROR("Bug!!!");
98 else if (move.type() == ChessMove::Promotion) {
99 ChessPiece promoted = final.get(move.to);
101 if (promoted) {
102 QPoint real = m_cinterface->converter()->toReal(move.to);
103 NamedSprite old_sprite = m_cinterface->getSprite(move.to);
104 NamedSprite new_sprite = m_cinterface->setPiece(move.to, promoted, /*false,*/ false);
106 res.addPostAnimation(Animate::morph(old_sprite, new_sprite));
108 else
109 ERROR("Bug!!!");
111 else if (move.type() == ChessMove::KingSideCastling) {
112 Point rookSquare = move.to + Point(1,0);
113 Point rookDestination = move.from + Point(1,0);
115 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
116 m_cinterface->setSprite(rookDestination, rook);
117 res.addPreAnimation(Animate::move(rook, rookDestination));
119 else if (move.type() == ChessMove::QueenSideCastling) {
120 Point rookSquare = move.to + Point(-2,0);
121 Point rookDestination = move.from + Point(-1,0);
123 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
124 m_cinterface->setSprite(rookDestination, rook);
125 res.addPreAnimation(Animate::move(rook, rookDestination));
128 return res;
131 boost::shared_ptr<AnimationGroup> back(const ChessPosition& final, const ChessMove& move) {
132 AnimationFactory res(m_cinterface->inner());
134 NamedSprite piece = m_cinterface->takeSprite(move.to);
135 NamedSprite captured;
136 if (ChessPiece captured_piece = final.get(move.to)) {
137 captured = m_cinterface->setPiece(move.to, captured_piece, false);
138 res.addPreAnimation(Animate::appear(captured));
141 if (!piece) {
142 piece = m_cinterface->createPiece(move.to, final.get(move.from), false);
143 res.addPreAnimation(Animate::appear(piece));
146 m_cinterface->setSprite(move.from, piece);
149 if (move.type() == ChessMove::EnPassantCapture) {
150 Point phantom(move.to.x, move.from.y);
152 if (ChessPiece pawn_piece = final.get(phantom)) {
153 NamedSprite captured_pawn = m_cinterface->setPiece(phantom, pawn_piece, false);
154 res.addPreAnimation(Animate::appear(captured_pawn));
157 else if (move.type() == ChessMove::Promotion) {
158 ChessPiece pawn_piece = final.get(move.from);
159 if (pawn_piece) {
160 NamedSprite pawn = m_cinterface->createPiece(move.to, pawn_piece, false);
161 res.addPreAnimation(Animate::morph(piece, pawn));
162 // replace piece with pawn
163 m_cinterface->setSprite(move.from, pawn);
164 piece = pawn;
167 else if (move.type() == ChessMove::KingSideCastling) {
168 Point rookSquare = move.to + Point(1,0);
169 Point rookDestination = move.from + Point(1,0);
171 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
172 m_cinterface->setSprite(rookSquare, rook);
174 res.addPreAnimation(Animate::move(rook, rookSquare));
176 else if (move.type() == ChessMove::QueenSideCastling) {
177 Point rookSquare = move.to + Point(-2,0);
178 Point rookDestination = move.from + Point(-1,0);
180 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
181 m_cinterface->setSprite(rookSquare, rook);
183 res.addPreAnimation(Animate::move(rook, rookSquare));
187 bool knight = m_cinterface->position()->get(move.to).type() == KNIGHT;
188 int mtype = knight
189 ? Animate::move::LShaped | Animate::move::Rotating
190 : Animate::move::Straight;
191 res.addPreAnimation(Animate::move(piece, move.from, mtype));
193 return res;
196 #endif
198 void ChessVariant::forallPieces(PieceFunction& f) {
199 f(WHITE, KING);
200 f(WHITE, QUEEN);
201 f(WHITE, ROOK);
202 f(WHITE, BISHOP);
203 f(WHITE, KNIGHT);
204 f(WHITE, PAWN);
205 f(BLACK, KING);
206 f(BLACK, QUEEN);
207 f(BLACK, ROOK);
208 f(BLACK, BISHOP);
209 f(BLACK, KNIGHT);
210 f(BLACK, PAWN);
213 VariantInfo* ChessVariant::info() {
214 if (!static_chess_variant)
215 static_chess_variant = new WrappedVariantInfo<ChessVariant>;
216 return static_chess_variant;
219 // piece factory
220 template <>
221 class PieceFactory<ChessVariant> {
222 public:
223 static ChessPiece createPiece(const QString& description) {
224 return ChessPiece::fromDescription(description);