Removed 'image' test (superseeded by 'luaimage' test)
[tagua/yd.git] / src / variants / chess.cpp
blobc92afdaa817aefdb0eb7068bf87a309730c3d326
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 "kboard_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;
30 //BEGIN Dream code
32 typedef UnwrappedGraphicalAPI<ChessVariant> ChessGraphicalAPI;
34 class ChessAnimator {
35 ChessGraphicalAPI::Ptr m_cinterface;
36 public:
37 ChessAnimator(ChessGraphicalAPI::Ptr cinterface)
38 : m_cinterface(cinterface) {
41 AnimationGroupPtr warp(const ChessPosition& final) {
42 const ChessPosition* current = m_cinterface->position();
43 AnimationGroupPtr res(new AnimationGroup);
45 for (Point i = current->first(); i <= current->last(); i = current->next(i)) {
46 ChessPiece c = current->get(i);
47 ChessPiece f = final.get(i);
49 if( !c && f ) {
50 //current->set(i, f);
51 NamedSprite sprite = m_cinterface->setPiece(i, f, false, false);
52 res->addPreAnimation(m_cinterface->appearAnimation(sprite, GraphicalAPI::Instant));
54 else if (c && !f) {
55 //current->set(i, NULL);
56 NamedSprite old_sprite = m_cinterface->takeSprite(i);
57 res->addPreAnimation(m_cinterface->disappearAnimation(old_sprite, GraphicalAPI::Instant));
59 else if(c && f && !(c == f) ) {
60 //current->set(i, f);
61 NamedSprite old_sprite = m_cinterface->takeSprite(i);
62 NamedSprite sprite = m_cinterface->setPiece(i, f, false, false);
63 res->addPreAnimation(m_cinterface->morphAnimation(old_sprite, sprite, GraphicalAPI::Instant));
67 //BROKEN: implement pool update
70 return res;
73 boost::shared_ptr<AnimationGroup> forward(const ChessPosition& final, const ChessMove& move) {
74 AnimationGroupPtr res(new AnimationGroup);
75 //ChessPiece piece = current->get(move.from);
77 NamedSprite piece = m_cinterface->takeSprite(move.from);
78 NamedSprite captured = m_cinterface->takeSprite(move.to);
79 m_cinterface->setSprite(move.to, piece);
81 if (piece)
82 res->addPreAnimation(m_cinterface->moveAnimation(piece, move.to));
83 else
84 std::cout << "Bug!!!!" << std::endl;
85 if (captured)
86 res->addPostAnimation(m_cinterface->destroyAnimation(captured));
88 if (move.type() == ChessMove::EnPassantCapture) {
89 Point phantom(move.to.x, move.from.y);
90 NamedSprite capturedPawn = m_cinterface->takeSprite(phantom);
92 if (capturedPawn) {
93 QPoint real = m_cinterface->converter()->toReal(phantom);
94 res->addPostAnimation(m_cinterface->disappearAnimation(capturedPawn));
96 else
97 std::cout << "Bug!!!!" << std::endl;
99 else if (move.type() == ChessMove::Promotion) {
100 ChessPiece promoted = final.get(move.to);
102 if (promoted) {
103 QPoint real = m_cinterface->converter()->toReal(move.to);
104 NamedSprite old_sprite = m_cinterface->getSprite(move.to);
105 NamedSprite new_sprite = m_cinterface->setPiece(move.to, promoted, false, false);
107 res->addPostAnimation(m_cinterface->morphAnimation(old_sprite, new_sprite));
109 else
110 std::cout << "Bug!!!!" << std::endl;
112 else if (move.type() == ChessMove::KingSideCastling) {
113 Point rookSquare = move.to + Point(1,0);
114 Point rookDestination = move.from + Point(1,0);
116 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
117 m_cinterface->setSprite(rookDestination, rook);
118 res->addPreAnimation(m_cinterface->moveAnimation(rook, rookDestination));
120 else if (move.type() == ChessMove::QueenSideCastling) {
121 Point rookSquare = move.to + Point(-2,0);
122 Point rookDestination = move.from + Point(-1,0);
124 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
125 m_cinterface->setSprite(rookDestination, rook);
126 res->addPreAnimation(m_cinterface->moveAnimation(rook, rookDestination));
129 return res;
132 boost::shared_ptr<AnimationGroup> back(const ChessPosition& final, const ChessMove& move) {
133 AnimationGroupPtr res(new AnimationGroup);
135 NamedSprite piece = m_cinterface->takeSprite(move.to);
136 NamedSprite captured;
137 if (ChessPiece captured_piece = final.get(move.to)) {
138 captured = m_cinterface->setPiece(move.to, captured_piece, false, false);
139 res->addPreAnimation(m_cinterface->appearAnimation(captured));
142 if (!piece) {
143 piece = m_cinterface->createPiece(move.to, final.get(move.from), false, false);
144 res->addPreAnimation(m_cinterface->appearAnimation(piece));
145 res->addPreAnimation(FadeAnimationPtr(new FadeAnimation(piece.sprite(),
146 m_cinterface->converter()->toReal(move.to), 0, 255)));
149 m_cinterface->setSprite(move.from, piece);
152 if (move.type() == ChessMove::EnPassantCapture) {
153 Point phantom(move.to.x, move.from.y);
155 if (ChessPiece pawn_piece = final.get(phantom)) {
156 NamedSprite captured_pawn = m_cinterface->setPiece(phantom, pawn_piece, false, false);
157 res->addPreAnimation(m_cinterface->appearAnimation(captured_pawn));
160 else if (move.type() == ChessMove::Promotion) {
161 ChessPiece pawn_piece = final.get(move.from);
162 if (pawn_piece) {
163 NamedSprite pawn = m_cinterface->createPiece(move.to, pawn_piece, false, false);
164 res->addPreAnimation(m_cinterface->morphAnimation(piece, pawn));
166 // replace piece with pawn
167 m_cinterface->setSprite(move.from, pawn);
168 piece = pawn;
171 else if (move.type() == ChessMove::KingSideCastling) {
172 Point rookSquare = move.to + Point(1,0);
173 Point rookDestination = move.from + Point(1,0);
175 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
176 m_cinterface->setSprite(rookSquare, rook);
178 res->addPreAnimation(m_cinterface->moveAnimation(rook, rookSquare));
180 else if (move.type() == ChessMove::QueenSideCastling) {
181 Point rookSquare = move.to + Point(-2,0);
182 Point rookDestination = move.from + Point(-1,0);
184 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
185 m_cinterface->setSprite(rookSquare, rook);
187 res->addPreAnimation(m_cinterface->moveAnimation(rook, rookSquare));
190 res->addPreAnimation(m_cinterface->moveAnimation(piece, move.from));
191 return res;
196 //END Dream code
199 void ChessVariant::forallPieces(PieceFunction& f) {
200 f(WHITE, KING);
201 f(WHITE, QUEEN);
202 f(WHITE, ROOK);
203 f(WHITE, BISHOP);
204 f(WHITE, KNIGHT);
205 f(WHITE, PAWN);
206 f(BLACK, KING);
207 f(BLACK, QUEEN);
208 f(BLACK, ROOK);
209 f(BLACK, BISHOP);
210 f(BLACK, KNIGHT);
211 f(BLACK, PAWN);
214 VariantInfo* ChessVariant::info() {
215 if (!static_chess_variant)
216 static_chess_variant = new WrappedVariantInfo<ChessVariant>;
217 return static_chess_variant;