Added real animations to the Shogi animator.
[tagua.git] / src / kboard_wrapped.h
blob1c69a9a3a426e376d0ecd7ac6e05140ec104d005
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 HIGHLEVEL_H
12 #define HIGHLEVEL_H
14 #include <memory>
15 #include <iostream>
16 #include "common.h"
17 #include "kboard.h"
18 #include "movefactory.h"
19 #include "moveserializer.h"
20 #include "nopool.h"
21 #include "algebraicnotation.h"
23 template <typename V> class WrappedPiece;
24 template <typename V> class WrappedMove;
25 template <typename V> class WrappedPosition;
27 /**
28 * @brief Wrap an high level position definition
29 * in a low level AbstractPosition implementation.
31 * Use this class to wrap an high level position definition
32 * in an AbstractPosition implementation suitable for communicating
33 * with the kboard infrastructure.
34 * Variant should be a structure with inner types Position, Move and Piece.
36 * @section Requirements on Position
38 * Position should define the following functions:
39 * - static Point size();
40 * - Piece* operator[](const Point& p) const;
41 * - Piece::Color turn() const;
42 * - void switchTurn();
43 * - bool testMove(Move& m) const;
44 * - void move(const Move& m);
45 * - void setup();
47 * @section Requirements on Piece
49 * Piece should have inner types Color and Type, each
50 * convertible to int via static_cast.
51 * Furthermore, it should implement the following
52 * functions:
53 * - Piece::Type type() const;
54 * - Piece::Color color() const;
55 * - QString name() const;
56 * - static QString typeSymbol(Piece::Type type);
58 * @section Move serialization
60 * To customize move serialization, one should specialize
61 * the template MoveSerializer<Pos>.
65 #ifdef Q_CC_GNU
66 #define __FUNC__ __PRETTY_FUNCTION__
67 #else
68 #define __FUNC__ __FUNCTION__
69 #endif
71 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
72 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
73 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
74 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
76 #define TYPECHECK(x,y) if (typeid(x) != typeid(y)) MISMATCH(x,y); else { }
80 template <typename Variant>
81 class WrappedPiece : public AbstractPiece {
82 typedef typename Variant::Piece Piece;
84 Piece m_piece;
85 public:
86 const Piece& inner() const { return m_piece; }
88 WrappedPiece(const Piece& piece)
89 : m_piece(piece) { }
91 virtual bool equals(AbstractPiece::Ptr _other) const {
92 if (!_other) return false;
93 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
95 if (other)
96 return m_piece == other->inner();
97 else {
98 MISMATCH(*_other.get(),WrappedPiece<Variant>);
99 return false;
103 virtual QString name() const {
104 return m_piece.name();
107 virtual QString typeSymbol() const {
108 return Piece::typeSymbol(m_piece.type());
111 virtual AbstractPiece::Ptr clone() const {
112 return AbstractPiece::Ptr(new WrappedPiece<Variant>(m_piece));
117 template <typename Variant>
118 class WrappedMove : public AbstractMove {
119 typedef typename Variant::Move Move;
120 typedef typename Variant::Position Position;
122 Move m_move;
123 public:
124 const Move& inner() const { return m_move; }
126 WrappedMove(const Move& move)
127 : m_move(move) { }
129 virtual QString SAN(AbstractPosition::Ptr _pos) const {
130 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
132 if (pos) {
133 MoveSerializer<Position> serializer(m_move, pos->inner());
134 return serializer.SAN();
136 else {
137 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
138 return "$@%";
142 virtual DecoratedMove toDecoratedMove(boost::shared_ptr<AbstractPosition> _pos) const {
143 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
145 if (pos) {
146 MoveSerializer<Position> serializer(m_move, pos->inner());
147 return serializer.toDecoratedMove();
149 else {
150 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
151 return DecoratedMove();
155 virtual QString toString(AbstractPosition::Ptr _pos) const {
156 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
158 if (pos)
159 return m_move.toString(pos->inner().size().y);
160 else {
161 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
162 return "$@%";
166 virtual NormalUserMove toUserMove() const {
167 return MoveFactory<Variant>::toNormal(m_move);
170 virtual bool equals(AbstractMove::Ptr _other) const {
171 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
173 if (other)
174 return m_move == other->inner();
175 else {
176 MISMATCH(*_other.get(),WrappedMove<Variant>);
177 return false;
182 template <typename Variant, typename Pool>
183 class WrappedPoolBase : public AbstractPool {
184 typedef typename Variant::Piece Piece;
186 Pool m_pool;
187 public:
188 WrappedPoolBase(Pool pool)
189 : m_pool(pool) { }
191 virtual int size() {
192 return m_pool.size();
195 virtual int insert(int pref_index, AbstractPiece::Ptr _piece) {
196 if (!_piece) {
197 return m_pool.insert(pref_index, Piece());
199 else {
200 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
202 if (piece)
203 return m_pool.insert(pref_index, Piece(piece->inner()) );
204 else {
205 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
206 return -1;
211 virtual AbstractPiece::Ptr get(int index) {
212 Piece piece = m_pool.get(index);
213 if (piece)
214 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
215 else
216 return AbstractPiece::Ptr();
219 virtual AbstractPiece::Ptr take(int index) {
220 Piece piece = m_pool.take(index);
221 if (piece)
222 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
223 else
224 return AbstractPiece::Ptr();
228 // simple special case for NoPool
229 template <typename Variant>
230 class WrappedPoolBase<Variant, NoPool> : public AbstractPool {
231 public:
232 WrappedPoolBase(NoPool) { }
235 template <typename Variant>
236 class WrappedPool : public WrappedPoolBase<Variant, typename Variant::Pool> {
237 public:
238 WrappedPool(typename Variant::Pool pool)
239 : WrappedPoolBase<Variant, typename Variant::Pool>(pool) { }
242 /**
243 * Metafunction that returns a null pointer when
244 * its template argument is NoPool.
246 template <typename Variant, typename Pool>
247 struct ReturnPool {
248 static AbstractPool::Ptr apply(typename Variant::Position& position, int player) {
249 return AbstractPool::Ptr(
250 new WrappedPool<Variant>(position.pool(player)));
254 template <typename Variant>
255 struct ReturnPool<Variant, NoPool> {
256 static AbstractPool::Ptr apply(typename Variant::Position&, int) {
257 return AbstractPool::Ptr();
261 template <typename Variant>
262 class WrappedPosition : public AbstractPosition {
263 typedef typename Variant::Position Position;
264 typedef typename Variant::Move Move;
265 typedef typename Variant::Piece Piece;
266 typedef typename Variant::Pool Pool;
268 Position m_pos;
269 public:
270 const Position& inner() const { return m_pos; }
271 Position& inner() { return m_pos; }
273 WrappedPosition(const Position& pos)
274 : m_pos(pos) { }
276 virtual Point size() const {
277 return inner().size();
280 virtual QStringList borderCoords() const {
281 return inner().borderCoords();
284 virtual void setup() {
285 m_pos.setup();
288 virtual AbstractPiece::Ptr get(const Point& p) const {
289 Piece piece = m_pos.get(p);
290 if (piece)
291 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
292 else
293 return AbstractPiece::Ptr();
296 virtual void set(const Point& p, AbstractPiece::Ptr _piece) {
297 if (!_piece) {
298 m_pos.set(p, Piece());
300 else {
301 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
303 if (piece)
304 m_pos.set(p, piece->inner() );
305 else
306 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
310 virtual AbstractPool::Ptr pool(int player) {
311 return ReturnPool<Variant, Pool>::apply(m_pos, player);
314 virtual InteractionType movable(const Point& p) const {
315 return m_pos.movable(p);
318 virtual InteractionType droppable(int p) const {
319 return m_pos.droppable(p);
322 virtual int turn() const {
323 return static_cast<int>(m_pos.turn());
326 virtual void setTurn(int turn) {
327 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
330 virtual int previousTurn() const {
331 return static_cast<int>(m_pos.previousTurn());
334 virtual void switchTurn() {
335 m_pos.switchTurn();
338 virtual bool testMove(AbstractMove::Ptr _move) const {
339 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
341 if (move)
342 return m_pos.testMove( const_cast<Move&>(move->inner()) );
343 else {
344 MISMATCH(*_move.get(),WrappedMove<Variant>);
345 return false;
349 virtual void move(AbstractMove::Ptr _move) {
350 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
352 if (move)
353 m_pos.move(move->inner());
354 else
355 MISMATCH(*_move.get(),WrappedMove<Variant>);
358 virtual AbstractPosition::Ptr clone() const {
359 return AbstractPosition::Ptr(new WrappedPosition<Variant>(m_pos));
362 virtual void copyFrom(const AbstractPosition::Ptr& _p) {
363 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
365 if (p)
366 m_pos = p->inner();
367 else
368 MISMATCH(*_p.get(),WrappedPosition);
371 virtual bool equals(AbstractPosition::Ptr _other) const {
372 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
374 if(other)
375 return m_pos == other->inner();
376 else {
377 MISMATCH(*_other.get(),WrappedPosition<Variant>);
378 return false;
382 virtual AbstractMove::Ptr getMove(const AlgebraicNotation& san) const {
383 bool ok;
384 Move res = m_pos.getMove(san, ok);
385 if (ok)
386 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
387 else
388 return AbstractMove::Ptr();
391 virtual AbstractMove::Ptr getMove(const QString& san) const {
392 AlgebraicNotation move(san, size().y); //FIXME
393 if(!move.valid())
394 return AbstractMove::Ptr();
395 return getMove(move);
398 virtual QString state() const {
399 return ""; // TODO
402 virtual QString fen(int halfmove, int fullmove) const {
403 return m_pos.fen(halfmove, fullmove);
406 virtual AbstractPiece::Ptr moveHint(AbstractMove::Ptr _move) const {
407 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
409 if (move) {
410 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
411 return AbstractPiece::Ptr(
412 new WrappedPiece<Variant>(Piece(*hint)));
414 else {
415 MISMATCH(*_move.get(),WrappedMove<Variant>);
418 return AbstractPiece::Ptr();
421 virtual QString variant() const {
422 return Variant::m_name;
425 virtual void dump() const {
426 m_pos.dump();
431 template <typename Variant>
432 class WrappedAnimator : public AbstractAnimator {
433 typedef typename Variant::Position Position;
434 typedef typename Variant::Animator Animator;
435 typedef typename Variant::Move Move;
437 Animator m_animator;
438 public:
439 const Animator& inner() const { return m_animator; }
441 WrappedAnimator(const Animator& animator)
442 : m_animator(animator) { }
444 virtual AnimationPtr warp(AbstractPosition::Ptr _pos) {
445 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
446 if (pos)
447 return m_animator.warp(pos->inner());
448 else {
449 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
450 return AnimationPtr();
454 virtual AnimationPtr forward(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
455 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
456 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
458 if (move && pos)
459 return m_animator.forward(pos->inner(), move->inner());
460 else {
461 if (!move)
462 MISMATCH(*_move.get(), WrappedMove<Variant>);
463 if (!pos)
464 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
465 return AnimationPtr();
469 virtual AnimationPtr back(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
470 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
471 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
473 if (move && pos)
474 return m_animator.back(pos->inner(), move->inner());
475 else {
476 if (!move)
477 MISMATCH(*_move.get(), WrappedMove<Variant>);
478 if (!pos)
479 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
480 return AnimationPtr();
485 #include "graphicalapi_unwrapped.h"
487 template <typename Variant>
488 class WrappedVariantInfo : public VariantInfo {
489 public:
490 typedef typename Variant::Animator Animator;
491 typedef typename Variant::Position Position;
492 typedef typename Variant::Piece Piece;
493 typedef typename Variant::Move Move;
494 typedef typename Variant::Pool Pool;
496 virtual AbstractPosition::Ptr createPosition() {
497 return AbstractPosition::Ptr(
498 new WrappedPosition<Variant>(Position()));
501 virtual AbstractPosition::Ptr createCustomPosition(const OptList& l) {
502 return AbstractPosition::Ptr(
503 new WrappedPosition<Variant>(Position(l)));
506 virtual AbstractPosition::Ptr createPositionFromFEN(const QString& fen) {
507 std::auto_ptr<WrappedPosition<Variant> > res(
508 new WrappedPosition<Variant>(Position()));
509 bool ok;
510 res->inner().fromFEN(fen, ok);
511 if (ok) {
512 return AbstractPosition::Ptr(res.release());
514 else return AbstractPosition::Ptr();
517 virtual AbstractPosition::Ptr createChessboard(int turn,
518 bool wk, bool wq, bool bk, bool bq,
519 const Point& ep) {
520 return AbstractPosition::Ptr(
521 new WrappedPosition<Variant>(Position(
522 static_cast<typename Piece::Color>(turn),
523 wk, wq, bk, bq, ep)));
525 virtual AbstractPiece::Ptr createPiece(int color, int type) {
526 return AbstractPiece::Ptr(
527 new WrappedPiece<Variant>(Piece(
528 static_cast<typename Piece::Color>(color),
529 static_cast<typename Piece::Type>(type))));
531 virtual void forallPieces(class PieceFunction& f) {
532 Variant::forallPieces(f);
534 virtual int moveListLayout() const {
535 return Variant::moveListLayout();
537 virtual AbstractAnimator::Ptr createAnimator(GraphicalAPI* graphical_api) {
538 return AbstractAnimator::Ptr(
539 new WrappedAnimator<Variant>(
540 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
541 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
543 virtual AbstractMove::Ptr createNormalMove(const NormalUserMove& move) {
544 return AbstractMove::Ptr(new WrappedMove<Variant>(
545 MoveFactory<Variant>::createNormalMove(move)));
547 virtual AbstractMove::Ptr createDropMove(const DropUserMove& move) {
548 return AbstractMove::Ptr(new WrappedMove<Variant>(
549 MoveFactory<Variant>::createDropMove(move)));
552 virtual AbstractMove::Ptr getVerboseMove(int turn, const VerboseNotation& m) const {
553 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
554 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
556 virtual int type(const QString& str) {
557 return Piece::getType(str);
559 virtual QString typeSymbol(int type) {
560 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
562 virtual bool simpleMoves() {
563 return Variant::m_simple_moves;
565 virtual QString name() const {
566 return Variant::m_name;
568 virtual QString themeProxy() const {
569 return Variant::m_theme_proxy;
571 virtual OptList positionOptions() const {
572 return Variant::positionOptions();
576 #endif // HIGHLEVEL_H