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 "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";
27 VariantInfo
* ChessVariant::static_chess_variant
= 0;
31 ChessGraphicalAPI::Ptr m_cinterface
;
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
);
47 NamedSprite sprite
= m_cinterface
->setPiece(i
, f
, false);
48 res
.addPreAnimation(Animate::appear(sprite
), Animate::Instant
);
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
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
);
75 bool knight
= m_cinterface
->position()->get(move
.from
).type() == KNIGHT
;
77 ? Animate::move::LShaped
| Animate::move::Rotating
78 : Animate::move::Straight
;
79 res
.addPreAnimation(Animate::move(piece
, move
.to
, mtype
));
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
);
92 QPoint real
= m_cinterface
->converter()->toReal(phantom
);
93 res
.addPostAnimation(Animate::disappear(capturedPawn
));
98 else if (move
.type() == ChessMove::Promotion
) {
99 ChessPiece promoted
= final
.get(move
.to
);
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
));
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
));
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
));
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
);
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
);
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
;
189 ? Animate::move::LShaped
| Animate::move::Rotating
190 : Animate::move::Straight
;
191 res
.addPreAnimation(Animate::move(piece
, move
.from
, mtype
));
198 void ChessVariant::forallPieces(PieceFunction
& f
) {
213 VariantInfo
* ChessVariant::info() {
214 if (!static_chess_variant
)
215 static_chess_variant
= new WrappedVariantInfo
<ChessVariant
>;
216 return static_chess_variant
;
221 class PieceFactory
<ChessVariant
> {
223 static ChessPiece
createPiece(const QString
& description
) {
224 return ChessPiece::fromDescription(description
);