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 "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;
32 typedef UnwrappedGraphicalAPI
<ChessVariant
> ChessGraphicalAPI
;
35 ChessGraphicalAPI::Ptr m_cinterface
;
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
);
51 NamedSprite sprite
= m_cinterface
->setPiece(i
, f
, false, false);
52 res
->addPreAnimation(m_cinterface
->appearAnimation(sprite
, GraphicalAPI::Instant
));
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
) ) {
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
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
);
82 res
->addPreAnimation(m_cinterface
->moveAnimation(piece
, move
.to
));
84 std::cout
<< "Bug!!!!" << std::endl
;
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
);
93 QPoint real
= m_cinterface
->converter()->toReal(phantom
);
94 res
->addPostAnimation(m_cinterface
->disappearAnimation(capturedPawn
));
97 std::cout
<< "Bug!!!!" << std::endl
;
99 else if (move
.type() == ChessMove::Promotion
) {
100 ChessPiece promoted
= final
.get(move
.to
);
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
));
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
));
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
));
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
);
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
);
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
));
199 void ChessVariant::forallPieces(PieceFunction
& f
) {
214 VariantInfo
* ChessVariant::info() {
215 if (!static_chess_variant
)
216 static_chess_variant
= new WrappedVariantInfo
<ChessVariant
>;
217 return static_chess_variant
;