Fixed pool update.
[tagua/yd.git] / src / kboard_wrapped.h
blob8b370495ad061ff9b9b06c8ae7ae5c75b7e2e781
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 "piecefactory.h"
20 #include "moveserializer.h"
21 #include "nopool.h"
22 #include "algebraicnotation.h"
24 template <typename V> class WrappedPiece;
25 template <typename V> class WrappedMove;
26 template <typename V> class WrappedPosition;
28 /**
29 * @brief Wrap an high level position definition
30 * in a low level AbstractPosition implementation.
32 * Use this class to wrap an high level position definition
33 * in an AbstractPosition implementation suitable for communicating
34 * with the kboard infrastructure.
35 * Variant should be a structure with inner types Position, Move and Piece.
37 * @section Requirements on Position
39 * Position should define the following functions:
40 * - static Point size();
41 * - Piece* operator[](const Point& p) const;
42 * - Piece::Color turn() const;
43 * - void switchTurn();
44 * - bool testMove(Move& m) const;
45 * - void move(const Move& m);
46 * - void setup();
48 * @section Requirements on Piece
50 * Piece should have inner types Color and Type, each
51 * convertible to int via static_cast.
52 * Furthermore, it should implement the following
53 * functions:
54 * - Piece::Type type() const;
55 * - Piece::Color color() const;
56 * - QString name() const;
57 * - static QString typeSymbol(Piece::Type type);
59 * @section Move serialization
61 * To customize move serialization, one should specialize
62 * the template MoveSerializer<Pos>.
66 #ifdef Q_CC_GNU
67 #define __FUNC__ __PRETTY_FUNCTION__
68 #else
69 #define __FUNC__ __FUNCTION__
70 #endif
72 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
73 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
74 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
75 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
77 #define TYPECHECK(x,y) if (typeid(x) != typeid(y)) MISMATCH(x,y); else { }
81 template <typename Variant>
82 class WrappedPiece : public AbstractPiece {
83 typedef typename Variant::Piece Piece;
85 Piece m_piece;
86 public:
87 const Piece& inner() const { return m_piece; }
89 WrappedPiece(const Piece& piece)
90 : m_piece(piece) { }
92 virtual bool equals(AbstractPiece::Ptr _other) const {
93 if (!_other) return false;
94 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
96 if (other)
97 return m_piece == other->inner();
98 else {
99 MISMATCH(*_other.get(),WrappedPiece<Variant>);
100 return false;
104 virtual QString name() const {
105 return m_piece.name();
108 virtual QString typeSymbol() const {
109 return Piece::typeSymbol(m_piece.type());
112 virtual AbstractPiece::Ptr clone() const {
113 return AbstractPiece::Ptr(new WrappedPiece<Variant>(m_piece));
118 template <typename Variant>
119 class WrappedMove : public AbstractMove {
120 typedef typename Variant::Move Move;
121 typedef typename Variant::Position Position;
123 Move m_move;
124 public:
125 const Move& inner() const { return m_move; }
127 WrappedMove(const Move& move)
128 : m_move(move) { }
130 virtual QString SAN(AbstractPosition::Ptr _pos) const {
131 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
133 if (pos) {
134 MoveSerializer<Position> serializer(m_move, pos->inner());
135 return serializer.SAN();
137 else {
138 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
139 return "$@%";
143 virtual DecoratedMove toDecoratedMove(boost::shared_ptr<AbstractPosition> _pos) const {
144 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
146 if (pos) {
147 MoveSerializer<Position> serializer(m_move, pos->inner());
148 return serializer.toDecoratedMove();
150 else {
151 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
152 return DecoratedMove();
156 virtual QString toString(AbstractPosition::Ptr _pos) const {
157 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
159 if (pos)
160 return m_move.toString(pos->inner().size().y);
161 else {
162 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
163 return "$@%";
167 virtual NormalUserMove toUserMove() const {
168 return MoveFactory<Variant>::toNormal(m_move);
171 virtual bool equals(AbstractMove::Ptr _other) const {
172 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
174 if (other)
175 return m_move == other->inner();
176 else {
177 MISMATCH(*_other.get(),WrappedMove<Variant>);
178 return false;
183 template <typename Variant, typename Pool>
184 class WrappedPoolBase : public AbstractPool {
185 typedef typename Variant::Piece Piece;
187 Pool m_pool;
188 public:
189 WrappedPoolBase(Pool pool)
190 : m_pool(pool) { }
192 virtual int size() {
193 return m_pool.size();
196 virtual int insert(int pref_index, AbstractPiece::Ptr _piece) {
197 if (!_piece) {
198 return m_pool.insert(pref_index, Piece());
200 else {
201 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
203 if (piece)
204 return m_pool.insert(pref_index, Piece(piece->inner()) );
205 else {
206 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
207 return -1;
212 virtual AbstractPiece::Ptr get(int index) {
213 Piece piece = m_pool.get(index);
214 if (piece)
215 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
216 else
217 return AbstractPiece::Ptr();
220 virtual AbstractPiece::Ptr take(int index) {
221 Piece piece = m_pool.take(index);
222 if (piece)
223 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
224 else
225 return AbstractPiece::Ptr();
229 // simple special case for NoPool
230 template <typename Variant>
231 class WrappedPoolBase<Variant, NoPool> : public AbstractPool {
232 public:
233 WrappedPoolBase(NoPool) { }
236 template <typename Variant>
237 class WrappedPool : public WrappedPoolBase<Variant, typename Variant::Pool> {
238 public:
239 WrappedPool(typename Variant::Pool pool)
240 : WrappedPoolBase<Variant, typename Variant::Pool>(pool) { }
243 /**
244 * Metafunction that returns a null pointer when
245 * its template argument is NoPool.
247 template <typename Variant, typename Pool>
248 struct ReturnPool {
249 static AbstractPool::Ptr apply(typename Variant::Position& position, int player) {
250 return AbstractPool::Ptr(
251 new WrappedPool<Variant>(position.pool(player)));
255 template <typename Variant>
256 struct ReturnPool<Variant, NoPool> {
257 static AbstractPool::Ptr apply(typename Variant::Position&, int) {
258 return AbstractPool::Ptr();
262 template <typename Variant>
263 class WrappedPosition : public AbstractPosition {
264 typedef typename Variant::Position Position;
265 typedef typename Variant::Move Move;
266 typedef typename Variant::Piece Piece;
267 typedef typename Variant::Pool Pool;
269 Position m_pos;
270 public:
271 const Position& inner() const { return m_pos; }
272 Position& inner() { return m_pos; }
274 WrappedPosition(const Position& pos)
275 : m_pos(pos) { }
277 virtual Point size() const {
278 return inner().size();
281 virtual QStringList borderCoords() const {
282 return inner().borderCoords();
285 virtual void setup() {
286 m_pos.setup();
289 virtual AbstractPiece::Ptr get(const Point& p) const {
290 Piece piece = m_pos.get(p);
291 if (piece)
292 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
293 else
294 return AbstractPiece::Ptr();
297 virtual void set(const Point& p, AbstractPiece::Ptr _piece) {
298 if (!_piece) {
299 m_pos.set(p, Piece());
301 else {
302 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
304 if (piece)
305 m_pos.set(p, piece->inner() );
306 else
307 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
311 virtual AbstractPool::Ptr pool(int player) {
312 return ReturnPool<Variant, Pool>::apply(m_pos, player);
315 virtual InteractionType movable(const Point& p) const {
316 return m_pos.movable(p);
319 virtual InteractionType droppable(int p) const {
320 return m_pos.droppable(p);
323 virtual int turn() const {
324 return static_cast<int>(m_pos.turn());
327 virtual void setTurn(int turn) {
328 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
331 virtual int previousTurn() const {
332 return static_cast<int>(m_pos.previousTurn());
335 virtual void switchTurn() {
336 m_pos.switchTurn();
339 virtual bool testMove(AbstractMove::Ptr _move) const {
340 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
342 if (move)
343 return m_pos.testMove( const_cast<Move&>(move->inner()) );
344 else {
345 MISMATCH(*_move.get(),WrappedMove<Variant>);
346 return false;
350 virtual void move(AbstractMove::Ptr _move) {
351 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
353 if (move)
354 m_pos.move(move->inner());
355 else
356 MISMATCH(*_move.get(),WrappedMove<Variant>);
359 virtual AbstractPosition::Ptr clone() const {
360 return AbstractPosition::Ptr(new WrappedPosition<Variant>(m_pos));
363 virtual void copyFrom(const AbstractPosition::Ptr& _p) {
364 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
366 if (p)
367 m_pos = p->inner();
368 else
369 MISMATCH(*_p.get(),WrappedPosition);
372 virtual bool equals(AbstractPosition::Ptr _other) const {
373 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
375 if(other)
376 return m_pos == other->inner();
377 else {
378 MISMATCH(*_other.get(),WrappedPosition<Variant>);
379 return false;
383 virtual AbstractMove::Ptr getMove(const AlgebraicNotation& san) const {
384 bool ok;
385 Move res = m_pos.getMove(san, ok);
386 if (ok)
387 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
388 else
389 return AbstractMove::Ptr();
392 virtual AbstractMove::Ptr getMove(const QString& san) const {
393 AlgebraicNotation move(san, size().y); //FIXME
394 if(!move.valid())
395 return AbstractMove::Ptr();
396 return getMove(move);
399 virtual QString state() const {
400 return ""; // TODO
403 virtual QString fen(int halfmove, int fullmove) const {
404 return m_pos.fen(halfmove, fullmove);
407 virtual AbstractPiece::Ptr moveHint(AbstractMove::Ptr _move) const {
408 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
410 if (move) {
411 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
412 return AbstractPiece::Ptr(
413 new WrappedPiece<Variant>(Piece(*hint)));
415 else {
416 MISMATCH(*_move.get(),WrappedMove<Variant>);
419 return AbstractPiece::Ptr();
422 virtual QString variant() const {
423 return Variant::m_name;
426 virtual void dump() const {
427 m_pos.dump();
432 template <typename Variant>
433 class WrappedAnimator : public AbstractAnimator {
434 typedef typename Variant::Position Position;
435 typedef typename Variant::Animator Animator;
436 typedef typename Variant::Move Move;
438 Animator m_animator;
439 public:
440 const Animator& inner() const { return m_animator; }
442 WrappedAnimator(const Animator& animator)
443 : m_animator(animator) { }
445 virtual AnimationPtr warp(AbstractPosition::Ptr _pos) {
446 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
447 if (pos)
448 return m_animator.warp(pos->inner());
449 else {
450 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
451 return AnimationPtr();
455 virtual AnimationPtr forward(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
456 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
457 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
459 if (move && pos)
460 return m_animator.forward(pos->inner(), move->inner());
461 else {
462 if (!move)
463 MISMATCH(*_move.get(), WrappedMove<Variant>);
464 if (!pos)
465 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
466 return AnimationPtr();
470 virtual AnimationPtr back(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
471 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
472 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
474 if (move && pos)
475 return m_animator.back(pos->inner(), move->inner());
476 else {
477 if (!move)
478 MISMATCH(*_move.get(), WrappedMove<Variant>);
479 if (!pos)
480 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
481 return AnimationPtr();
486 #include "graphicalapi_unwrapped.h"
488 template <typename Variant>
489 class WrappedVariantInfo : public VariantInfo {
490 public:
491 typedef typename Variant::Animator Animator;
492 typedef typename Variant::Position Position;
493 typedef typename Variant::Piece Piece;
494 typedef typename Variant::Move Move;
495 typedef typename Variant::Pool Pool;
497 virtual AbstractPosition::Ptr createPosition() {
498 return AbstractPosition::Ptr(
499 new WrappedPosition<Variant>(Position()));
502 virtual AbstractPosition::Ptr createCustomPosition(const OptList& l) {
503 return AbstractPosition::Ptr(
504 new WrappedPosition<Variant>(Position(l)));
507 virtual AbstractPosition::Ptr createPositionFromFEN(const QString& fen) {
508 std::auto_ptr<WrappedPosition<Variant> > res(
509 new WrappedPosition<Variant>(Position()));
510 bool ok;
511 res->inner().fromFEN(fen, ok);
512 if (ok) {
513 return AbstractPosition::Ptr(res.release());
515 else return AbstractPosition::Ptr();
518 virtual AbstractPosition::Ptr createChessboard(int turn,
519 bool wk, bool wq, bool bk, bool bq,
520 const Point& ep) {
521 return AbstractPosition::Ptr(
522 new WrappedPosition<Variant>(Position(
523 static_cast<typename Piece::Color>(turn),
524 wk, wq, bk, bq, ep)));
526 virtual AbstractPiece::Ptr createPiece(int color, int type) {
527 return AbstractPiece::Ptr(
528 new WrappedPiece<Variant>(Piece(
529 static_cast<typename Piece::Color>(color),
530 static_cast<typename Piece::Type>(type))));
532 virtual void forallPieces(class PieceFunction& f) {
533 Variant::forallPieces(f);
535 virtual int moveListLayout() const {
536 return Variant::moveListLayout();
538 virtual AbstractAnimator::Ptr createAnimator(GraphicalAPI* graphical_api) {
539 return AbstractAnimator::Ptr(
540 new WrappedAnimator<Variant>(
541 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
542 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
544 virtual AbstractMove::Ptr createNormalMove(const NormalUserMove& move) {
545 return AbstractMove::Ptr(new WrappedMove<Variant>(
546 MoveFactory<Variant>::createNormalMove(move)));
548 virtual AbstractMove::Ptr createDropMove(const DropUserMove& move) {
549 return AbstractMove::Ptr(new WrappedMove<Variant>(
550 MoveFactory<Variant>::createDropMove(move)));
553 virtual AbstractMove::Ptr getVerboseMove(int turn, const VerboseNotation& m) const {
554 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
555 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
558 virtual AbstractPiece::Ptr createPiece(const QString& description) {
559 return AbstractPiece::Ptr(new WrappedPiece<Variant>(
560 PieceFactory<Variant>::createPiece(description)));
563 virtual int type(const QString& str) {
564 return Piece::getType(str);
566 virtual QString typeSymbol(int type) {
567 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
569 virtual bool simpleMoves() {
570 return Variant::m_simple_moves;
572 virtual QString name() const {
573 return Variant::m_name;
575 virtual QString themeProxy() const {
576 return Variant::m_theme_proxy;
578 virtual OptList positionOptions() const {
579 return Variant::positionOptions();
583 #endif // HIGHLEVEL_H