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.
13 #include "xchess/animator.impl.h"
14 #include "xchess/piece.h"
15 #include "xchess/move.h"
16 #include "piecefunction.h"
17 #include "highlevel.h"
18 #include "algebraicnotation.h"
19 #include "graphicalposition.h"
20 #include "pointconverter.h"
21 #include "piecegrid.h"
23 using namespace boost;
27 typedef PieceColor Color;
32 ReversiPiece(Color color, Type)
34 ReversiPiece(Color color)
36 Color color() const { return m_color; }
37 Type type() const { return -1; }
38 int id() const { return static_cast<int>(m_color); }
39 QString name() const { return m_color == WHITE ? "white_stone"
40 : m_color == BLACK ? "black_stone" : "unknown"; }
41 static Color oppositeColor(Color color) {
42 return color == WHITE ? BLACK : WHITE;
44 static int getType(const QString&) { return -1; }
45 static QString typeSymbol(int) { return ""; }
47 bool operator==(const ReversiPiece& other) const {
48 return m_color == other.m_color;
50 bool operator<(const ReversiPiece& other) const {
51 return m_color < other.m_color;
53 bool equals(const ReversiPiece* other) const {
54 return other && *this == *other;
58 typedef Point ReversiMove;
60 class ReversiPosition {
62 typedef ReversiPiece Piece;
63 typedef ReversiMove Move;
64 typedef std::map<Piece, int> Pool;
67 PointerGrid<Piece> m_board;
70 int checkDirection(const Point& p, const Point& dir) const;
71 void flipDirection(Point p, const Point& dir);
72 void flip(const Point& p);
75 ReversiPosition(const OptList& l);
76 ReversiPosition(Piece::Color turn, bool wk, bool wq,
77 bool bk, bool bq, const Point& ep);
79 Pool& pool() { return m_pool; }
80 const Pool& pool() const { return m_pool; }
81 void addToPool(const Piece&, int) { }
82 void removeFromPool(const Piece&, int) { }
84 Piece::Color turn() const { return m_turn; }
85 void setTurn(Piece::Color turn) { m_turn = turn; }
87 Piece::Color previousTurn() const { return Piece::oppositeColor(m_turn); }
89 void fromFEN(const QString&, bool& ok) { ok = true;}
90 QString fen(int,int) const { return ""; }
92 static Move getVerboseMove(int turn, const VerboseNotation& m);
93 Move getMove(const AlgebraicNotation& m, bool& ok) const;
95 bool testMove(Move& p) const;
96 void move(const Move& p);
98 Point size() const { return m_board.getSize(); }
99 bool valid(const Point& p) const { return m_board.valid(p); }
102 const Piece* get(const Point& p) const {
103 return valid(p) ? m_board[p] : 0;
105 Piece* get(const Point& p) {
106 return valid(p) ? m_board[p] : 0;
108 const Piece* operator[](const Point& p) const { return get(p); }
109 void set(const Point& p, Piece* piece) {
115 void removePiece(const Point& p) { set(p, 0); }
117 bool operator==(const ReversiPosition& other) const;
119 shared_ptr<Piece> moveHint(const Move& m) const;
120 void dump() const { }
121 QStringList borderCoords() const;
124 ReversiPosition::ReversiPosition()
128 ReversiPosition::ReversiPosition(const OptList&)
132 ReversiPosition::ReversiPosition(Piece::Color turn, bool, bool, bool, bool, const Point&)
136 QStringList ReversiPosition::borderCoords() const
139 Point p = m_board.getSize();
140 for(int i=0; i<p.x; i++)
141 retv << QChar('a'+i);
142 for(int i=1; i<=p.y; i++)
143 retv += QString::number(i);
147 ReversiMove ReversiPosition::getMove(const AlgebraicNotation& m, bool& ok) const {
152 ReversiMove ReversiPosition::getVerboseMove(int /*turn*/, const VerboseNotation& m) {
156 void ReversiPosition::setup() {
157 for (int i = 3; i <= 4; i++)
158 for (int j = 3; j <= 4; j++) {
159 m_board[Point(i,j)] = new Piece(
160 (i+j) % 2 == 0 ? WHITE : BLACK);
164 void ReversiPosition::switchTurn() {
165 m_turn = Piece::oppositeColor(m_turn);
166 for (Point p = m_board.first(); p <= m_board.last(); p = m_board.next(p))
167 if (testMove(p)) return;
168 // no move: restore old turn
169 m_turn = Piece::oppositeColor(m_turn);
172 int ReversiPosition::checkDirection(const Point& p, const Point& dir) const {
176 while (valid(pos) && m_board[pos]) {
177 if (m_board[pos]->color() != m_turn)
186 void ReversiPosition::flipDirection(Point p, const Point& dir) {
187 const int n = checkDirection(p, dir);
188 for (int i = 0; i < n; i++)
192 void ReversiPosition::flip(const Point& p) {
193 Q_ASSERT(m_board[p]);
194 set(p, new Piece(Piece::oppositeColor(m_board[p]->color())));
197 bool ReversiPosition::testMove(Move& p) const {
198 if (!valid(p) || m_board[p]) return false;
200 for (int i = -1; i <= 1; i++)
201 for (int j = -1; j <= 1; j++) {
202 if (i == 0 && j == 0) continue;
203 if (checkDirection(p, Point(i, j)) > 0) return true;
209 void ReversiPosition::move(const Move& p) {
210 set(p, new Piece(m_turn));
212 for (int i = -1; i <= 1; i++)
213 for (int j = -1; j <= 1; j++) {
214 if (i == 0 && j == 0) continue;
215 flipDirection(p, Point(i, j));
221 bool ReversiPosition::operator==(const ReversiPosition& other) const {
222 return m_board == other.m_board
223 && m_turn == other.m_turn;
226 shared_ptr<ReversiPiece> ReversiPosition::moveHint(const ReversiMove& /*m*/) const {
227 return shared_ptr<Piece>(new Piece(m_turn));
231 //BEGIN ReversiAnimator ---------------------------------------------------------------------
235 class ReversiAnimator {
236 typedef boost::shared_ptr<AnimationGroup> AnimationPtr;
239 PointConverter* m_converter;
240 GraphicalPosition* m_position;
243 bool m_anim_movement;
248 ReversiAnimator(PointConverter* converter, GraphicalPosition* position);
249 AnimationPtr warp(AbstractPosition::Ptr);
250 AnimationPtr forward(AbstractPosition::Ptr, const ReversiMove& move);
251 AnimationPtr back(AbstractPosition::Ptr, const ReversiMove& move);
254 ReversiAnimator::ReversiAnimator(PointConverter* converter, GraphicalPosition* position)
255 : m_converter(converter)
256 , m_position(position)
257 , m_anim_movement(false)
258 , m_anim_explode(false)
260 , m_anim_rotate(false) {
261 if (position->getBoolSetting("animations", true)) {
262 m_anim_movement = (bool)position->getBoolSetting("animations.movement", true);
263 m_anim_explode = (bool)position->getBoolSetting("animations.explode", true);
264 m_anim_fade = (bool)position->getBoolSetting("animations.fading", true);
265 m_anim_rotate = (bool)position->getBoolSetting("animations.transform", true);
269 ReversiAnimator::AnimationPtr ReversiAnimator::warp(AbstractPosition::Ptr final) {
270 AnimationPtr res(new AnimationGroup);
271 for (Point i = m_position->first(); i <= m_position->last(); i = m_position->next(i)) {
272 QPoint real = m_converter->toReal(i);
273 Element p = m_position->getElement(i);
274 AbstractPiece::Ptr q = final->get(i);
275 shared_ptr<Animation> a;
278 shared_ptr<PieceSprite> sprite = p.sprite();
281 if (!p.piece()->equals(q)) {
282 shared_ptr<PieceSprite> sprite = p.sprite();
285 if((m_anim_explode||m_anim_fade) && m_anim_rotate) {
286 shared_ptr<PieceSprite> new_sprite = m_position->setPiece(i, q, false, false);
287 shared_ptr<AnimationGroup> g(new AnimationGroup);
288 g->addPreAnimation(shared_ptr<Animation>(new GrowAnimation(new_sprite)));
289 if(0)/*m_anim_explode)*/
290 g->addPreAnimation(shared_ptr<Animation>(new ExplodeAnimation(sprite, m_random)));
292 g->addPreAnimation(shared_ptr<Animation>(new FadeAnimation(sprite, real, 255, 0)));
296 a = shared_ptr<Animation>(new PromotionAnimation( sprite,
297 m_position->setPiece(i, q, false, false) ));
301 m_position->removeElement(i);
303 a = shared_ptr<Animation>(new FadeAnimation(sprite, real, 255, 0));
305 a = shared_ptr<Animation>(new CaptureAnimation(sprite));
310 a = shared_ptr<Animation>(new DropAnimation( m_position->setPiece(i, q, false, false) ));
313 if (a) res->addPreAnimation(a);
319 ReversiAnimator::AnimationPtr ReversiAnimator::forward(AbstractPosition::Ptr final, const ReversiMove&) {
323 ReversiAnimator::AnimationPtr ReversiAnimator::back(AbstractPosition::Ptr final, const ReversiMove&) {
329 //END ReversiAnimator -----------------------------------------------------------------------
331 class ReversiVariantInfo {
333 typedef ReversiPosition Position;
334 typedef Position::Move Move;
335 typedef Position::Piece Piece;
336 typedef class ReversiAnimator Animator;
338 static const bool m_simple_moves = true;
339 static const char *m_name;
340 static const char *m_theme_proxy;
342 static void forallPieces(PieceFunction& f);
343 static int moveListLayout() { return 0; }
344 static OptList positionOptions() { return OptList(); }
347 const char *ReversiVariantInfo::m_name = "Reversi";
348 const char *ReversiVariantInfo::m_theme_proxy = "Reversi";
350 void ReversiVariantInfo::forallPieces(PieceFunction& f) {
355 VariantInfo* ReversiVariant::static_reversi_variant = 0;
357 VariantInfo* ReversiVariant::info() {
358 if (!static_reversi_variant)
359 static_reversi_variant = new WrappedVariantInfo<ReversiVariantInfo>;
360 return static_reversi_variant;
364 struct MoveFactory<ReversiVariantInfo> {
365 static ReversiMove createNormalMove(const NormalUserMove& move) {
368 static ReversiMove createDropMove(const ReversiPiece& /*p*/, const Point& to) {
371 static NormalUserMove toNormal(const ReversiMove& m) {
372 return NormalUserMove(Point::invalid(), m);
377 class MoveSerializer<ReversiPosition> : public AbstractMoveSerializer {
379 const ReversiPosition& m_ref;
381 MoveSerializer(const ReversiMove& m, const ReversiPosition& ref)
382 : m_move(m), m_ref(ref) { }
384 DecoratedMove toDecoratedMove() const {
385 return DecoratedMove() << SAN();
388 virtual QString SAN() const {
389 return m_move.toString(m_ref.size().y);
393 class ReversiAnimator : public SimpleAnimator<ReversiVariantInfo> {
394 typedef SimpleAnimator<ReversiVariantInfo> Base;
395 typedef Base::Position Position;
396 typedef Base::Move Move;
397 typedef Base::GPosition GPosition;
399 ReversiAnimator(PointConverter* converter, const boost::shared_ptr<GPosition>& position)
400 : Base(converter, position) { }
402 AnimationPtr forward(const Position& final, const Move&) {
406 AnimationPtr back(const Position& final, const Move&) {