Moved HLVariant prototype inside Tagua.
[tagua/yd.git] / src / variants / xchess / animator.impl.h
blob7472f050e5c3e4c60cc779e9cb89ac2d2a50a1f8
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 #ifndef XCHESS__ANIMATOR_IMPL_H
12 #define XCHESS__ANIMATOR_IMPL_H
14 #include "animator.h"
15 #include "animationfactory.h"
16 #include "namedsprite.h"
19 template <typename Variant>
20 AnimationGroupPtr BaseAnimator<Variant>::warp(const Position& final) {
21 const Position* current = m_cinterface->position();
22 AnimationFactory res(m_cinterface->inner());
24 for (Point i = current->first(); i <= current->last(); i = current->next(i)) {
25 Piece c = current->get(i);
26 Piece f = final.get(i);
28 if( !c && f ) {
29 //current->set(i, f);
30 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
31 res.addPreAnimation(Animate::appear(sprite), Animate::Instant);
33 else if (c && !f) {
34 NamedSprite old_sprite = m_cinterface->takeSprite(i);
35 res.addPreAnimation(Animate::disappear(old_sprite), Animate::Instant);
37 else if(c && f && !(c == f) ) {
38 NamedSprite old_sprite = m_cinterface->takeSprite(i);
39 NamedSprite sprite = m_cinterface->setPiece(i, f, false);
40 res.addPreAnimation(Animate::morph(old_sprite, sprite), Animate::Instant);
44 return res;
47 template <typename Variant>
48 AnimationGroupPtr BaseAnimator<Variant>::forward(const Position& final, const Move&) {
49 return warp(final);
53 template <typename Variant>
54 AnimationGroupPtr BaseAnimator<Variant>::back(const Position& final, const Move&) {
55 return warp(final);
58 template <typename Variant>
59 AnimationGroupPtr SimpleAnimator<Variant>::warp(const Position& final) {
60 AnimationFactory res(m_cinterface->inner());
62 res.setGroup(Base::warp(final));
64 return res;
67 template <typename Variant>
68 SchemePtr SimpleAnimator<Variant>::movement(const NamedSprite& sprite, const Point& from, const Point& to) {
69 bool knight = m_cinterface->position()->get(from).type() == KNIGHT;
70 int mtype = knight
71 ? Animate::move::LShaped | Animate::move::Rotating
72 : Animate::move::Straight;
73 return SchemePtr(new Animate::move(sprite, to, mtype));
76 template <typename Variant>
77 AnimationGroupPtr SimpleAnimator<Variant>::forward(const Position& final, const Move& move) {
78 AnimationFactory res(m_cinterface->inner());
80 NamedSprite piece = m_cinterface->takeSprite(move.from);
81 NamedSprite captured = m_cinterface->takeSprite(move.to);
82 m_cinterface->setSprite(move.to, piece);
84 if (piece)
85 res.addPreAnimation(*movement(piece, move.from, move.to));
86 else
87 ERROR("Bug!!!");
89 if (captured)
90 res.addPostAnimation(Animate::destroy(captured));
92 if (move.type() == Move::EnPassantCapture) {
93 Point phantom(move.to.x, move.from.y);
94 NamedSprite capturedPawn = m_cinterface->takeSprite(phantom);
96 if (capturedPawn) {
97 QPoint real = m_cinterface->converter()->toReal(phantom);
98 res.addPostAnimation(Animate::disappear(capturedPawn));
100 else
101 ERROR("Bug!!!");
103 else if (move.type() == Move::Promotion) {
104 Piece promoted = final.get(move.to);
106 if (promoted) {
107 QPoint real = m_cinterface->converter()->toReal(move.to);
108 NamedSprite old_sprite = m_cinterface->getSprite(move.to);
109 NamedSprite new_sprite = m_cinterface->setPiece(move.to, promoted, /*false,*/ false);
111 res.addPostAnimation(Animate::morph(old_sprite, new_sprite));
113 else
114 ERROR("Bug!!!");
116 else if (move.type() == Move::KingSideCastling) {
117 Point rookSquare = move.to + Point(1,0);
118 Point rookDestination = move.from + Point(1,0);
120 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
121 m_cinterface->setSprite(rookDestination, rook);
122 res.addPreAnimation(Animate::move(rook, rookDestination));
124 else if (move.type() == Move::QueenSideCastling) {
125 Point rookSquare = move.to + Point(-2,0);
126 Point rookDestination = move.from + Point(-1,0);
128 NamedSprite rook = m_cinterface->takeSprite(rookSquare);
129 m_cinterface->setSprite(rookDestination, rook);
130 res.addPreAnimation(Animate::move(rook, rookDestination));
133 return res;
136 template <typename Variant>
137 AnimationGroupPtr SimpleAnimator<Variant>::back(const Position& final, const Move& move) {
138 AnimationFactory res(m_cinterface->inner());
140 NamedSprite piece = m_cinterface->takeSprite(move.to);
141 NamedSprite captured;
142 if (Piece captured_piece = final.get(move.to)) {
143 captured = m_cinterface->setPiece(move.to, captured_piece, false);
144 res.addPreAnimation(Animate::appear(captured));
147 if (!piece) {
148 piece = m_cinterface->createPiece(move.to, final.get(move.from), false);
149 res.addPreAnimation(Animate::appear(piece));
152 m_cinterface->setSprite(move.from, piece);
155 if (move.type() == Move::EnPassantCapture) {
156 Point phantom(move.to.x, move.from.y);
158 if (Piece pawn_piece = final.get(phantom)) {
159 NamedSprite captured_pawn = m_cinterface->setPiece(phantom, pawn_piece, false);
160 res.addPreAnimation(Animate::appear(captured_pawn));
163 else if (move.type() == Move::Promotion) {
164 Piece pawn_piece = final.get(move.from);
165 if (pawn_piece) {
166 NamedSprite pawn = m_cinterface->createPiece(move.to, pawn_piece, false);
167 res.addPreAnimation(Animate::morph(piece, pawn));
169 // replace piece with pawn
170 m_cinterface->setSprite(move.from, pawn);
171 piece = pawn;
174 else if (move.type() == Move::KingSideCastling) {
175 Point rookSquare = move.to + Point(1,0);
176 Point rookDestination = move.from + Point(1,0);
178 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
179 m_cinterface->setSprite(rookSquare, rook);
181 res.addPreAnimation(Animate::move(rook, rookSquare));
183 else if (move.type() == Move::QueenSideCastling) {
184 Point rookSquare = move.to + Point(-2,0);
185 Point rookDestination = move.from + Point(-1,0);
187 NamedSprite rook = m_cinterface->takeSprite(rookDestination);
188 m_cinterface->setSprite(rookSquare, rook);
190 res.addPreAnimation(Animate::move(rook, rookSquare));
193 res.addPreAnimation(*movement(piece, move.to, move.from));
195 return res;
199 #endif // XCHESS__ANIMATOR_IMPL_H