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.
12 #include <boost/shared_ptr.hpp>
13 #include "variants/chess.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;
30 ChessGraphicalAPI::Ptr m_cinterface
;
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
);
46 NamedSprite sprite
= m_cinterface
->setPiece(i
, f
, false);
47 res
.addPreAnimation(Animate::appear(sprite
), Animate::Instant
);
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
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
);
74 bool knight
= m_cinterface
->position()->get(move
.from
).type() == KNIGHT
;
76 ? Animate::move::LShaped
| Animate::move::Rotating
77 : Animate::move::Straight
;
78 res
.addPreAnimation(Animate::move(piece
, move
.to
, mtype
));
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
);
91 QPoint real
= m_cinterface
->converter()->toReal(phantom
);
92 res
.addPostAnimation(Animate::disappear(capturedPawn
));
97 else if (move
.type() == ChessMove::Promotion
) {
98 ChessPiece promoted
= final
.get(move
.to
);
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
));
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
));
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
));
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
);
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
);
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
;
188 ? Animate::move::LShaped
| Animate::move::Rotating
189 : Animate::move::Straight
;
190 res
.addPreAnimation(Animate::move(piece
, move
.from
, mtype
));
197 void ChessVariant::forallPieces(PieceFunction
& f
) {
212 VariantInfo
* ChessVariant::info() {
213 if (!static_chess_variant
)
214 static_chess_variant
= new WrappedVariantInfo
<ChessVariant
>;
215 return static_chess_variant
;
220 class PieceFactory
<ChessVariant
> {
222 static ChessPiece
createPiece(const QString
& description
) {
223 return ChessPiece::fromDescription(description
);