Introduced the NoPool placeholder class.
[tagua/yd.git] / src / kboard_wrapped.h
blob4a70a202118b0b64b2426dee998468c9f155ae96
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 {
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) { }
243 template <typename Variant>
244 class WrappedPosition : public AbstractPosition {
245 typedef typename Variant::Position Position;
246 typedef typename Variant::Move Move;
247 typedef typename Variant::Piece Piece;
248 typedef typename Variant::Pool Pool;
250 Position m_pos;
251 public:
252 const Position& inner() const { return m_pos; }
253 Position& inner() { return m_pos; }
255 WrappedPosition(const Position& pos)
256 : m_pos(pos) { }
258 virtual Point size() const {
259 return inner().size();
262 virtual QStringList borderCoords() const {
263 return inner().borderCoords();
266 virtual void setup() {
267 m_pos.setup();
270 virtual AbstractPiece::Ptr get(const Point& p) const {
271 Piece piece = m_pos.get(p);
272 if (piece)
273 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
274 else
275 return AbstractPiece::Ptr();
278 virtual void set(const Point& p, AbstractPiece::Ptr _piece) {
279 if (!_piece) {
280 m_pos.set(p, Piece());
282 else {
283 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
285 if (piece)
286 m_pos.set(p, piece->inner() );
287 else
288 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
292 // virtual AbstractPool::Ptr pool(int player) {
293 // // return AbstractPool::Ptr(new WrappedPool<Variant>(m_pos.pool(player)));
294 // return AbstractPool::Ptr();
295 // }
297 virtual InteractionType movable(const Point& p) const {
298 return m_pos.movable(p);
301 virtual InteractionType droppable(int p) const {
302 return m_pos.droppable(p);
305 virtual int turn() const {
306 return static_cast<int>(m_pos.turn());
309 virtual void setTurn(int turn) {
310 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
313 virtual int previousTurn() const {
314 return static_cast<int>(m_pos.previousTurn());
317 virtual void switchTurn() {
318 m_pos.switchTurn();
321 virtual bool testMove(AbstractMove::Ptr _move) const {
322 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
324 if (move)
325 return m_pos.testMove( const_cast<Move&>(move->inner()) );
326 else {
327 MISMATCH(*_move.get(),WrappedMove<Variant>);
328 return false;
332 virtual void move(AbstractMove::Ptr _move) {
333 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
335 if (move)
336 m_pos.move(move->inner());
337 else
338 MISMATCH(*_move.get(),WrappedMove<Variant>);
341 virtual AbstractPosition::Ptr clone() const {
342 return AbstractPosition::Ptr(new WrappedPosition<Variant>(m_pos));
345 virtual void copyFrom(const AbstractPosition::Ptr& _p) {
346 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
348 if (p)
349 m_pos = p->inner();
350 else
351 MISMATCH(*_p.get(),WrappedPosition);
354 virtual bool equals(AbstractPosition::Ptr _other) const {
355 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
357 if(other)
358 return m_pos == other->inner();
359 else {
360 MISMATCH(*_other.get(),WrappedPosition<Variant>);
361 return false;
365 virtual AbstractMove::Ptr getMove(const AlgebraicNotation& san) const {
366 bool ok;
367 Move res = m_pos.getMove(san, ok);
368 if (ok)
369 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
370 else
371 return AbstractMove::Ptr();
374 virtual AbstractMove::Ptr getMove(const QString& san) const {
375 AlgebraicNotation move(san, size().y); //FIXME
376 if(!move.valid())
377 return AbstractMove::Ptr();
378 return getMove(move);
381 virtual QString state() const {
382 return ""; // TODO
385 virtual QString fen(int halfmove, int fullmove) const {
386 return m_pos.fen(halfmove, fullmove);
389 virtual AbstractPiece::Ptr moveHint(AbstractMove::Ptr _move) const {
390 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
392 if (move) {
393 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
394 return AbstractPiece::Ptr(
395 new WrappedPiece<Variant>(Piece(*hint)));
397 else {
398 MISMATCH(*_move.get(),WrappedMove<Variant>);
401 return AbstractPiece::Ptr();
404 virtual QString variant() const {
405 return Variant::m_name;
408 virtual void dump() const {
409 m_pos.dump();
414 template <typename Variant>
415 class WrappedAnimator : public AbstractAnimator {
416 typedef typename Variant::Position Position;
417 typedef typename Variant::Animator Animator;
418 typedef typename Variant::Move Move;
420 Animator m_animator;
421 public:
422 const Animator& inner() const { return m_animator; }
424 WrappedAnimator(const Animator& animator)
425 : m_animator(animator) { }
427 virtual AnimationPtr warp(AbstractPosition::Ptr _pos) {
428 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
429 if (pos)
430 return m_animator.warp(pos->inner());
431 else {
432 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
433 return AnimationPtr();
437 virtual AnimationPtr forward(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
438 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
439 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
441 if (move && pos)
442 return m_animator.forward(pos->inner(), move->inner());
443 else {
444 if (!move)
445 MISMATCH(*_move.get(), WrappedMove<Variant>);
446 if (!pos)
447 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
448 return AnimationPtr();
452 virtual AnimationPtr back(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
453 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
454 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
456 if (move && pos)
457 return m_animator.back(pos->inner(), move->inner());
458 else {
459 if (!move)
460 MISMATCH(*_move.get(), WrappedMove<Variant>);
461 if (!pos)
462 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
463 return AnimationPtr();
468 #include "graphicalapi_unwrapped.h"
470 template <typename Variant>
471 class WrappedVariantInfo : public VariantInfo {
472 public:
473 typedef typename Variant::Animator Animator;
474 typedef typename Variant::Position Position;
475 typedef typename Variant::Piece Piece;
476 typedef typename Variant::Move Move;
477 typedef typename Variant::Pool Pool;
479 virtual AbstractPosition::Ptr createPosition() {
480 return AbstractPosition::Ptr(
481 new WrappedPosition<Variant>(Position()));
484 virtual AbstractPosition::Ptr createCustomPosition(const OptList& l) {
485 return AbstractPosition::Ptr(
486 new WrappedPosition<Variant>(Position(l)));
489 virtual AbstractPosition::Ptr createPositionFromFEN(const QString& fen) {
490 std::auto_ptr<WrappedPosition<Variant> > res(
491 new WrappedPosition<Variant>(Position()));
492 bool ok;
493 res->inner().fromFEN(fen, ok);
494 if (ok) {
495 return AbstractPosition::Ptr(res.release());
497 else return AbstractPosition::Ptr();
500 virtual AbstractPosition::Ptr createChessboard(int turn,
501 bool wk, bool wq, bool bk, bool bq,
502 const Point& ep) {
503 return AbstractPosition::Ptr(
504 new WrappedPosition<Variant>(Position(
505 static_cast<typename Piece::Color>(turn),
506 wk, wq, bk, bq, ep)));
508 virtual AbstractPiece::Ptr createPiece(int color, int type) {
509 return AbstractPiece::Ptr(
510 new WrappedPiece<Variant>(Piece(
511 static_cast<typename Piece::Color>(color),
512 static_cast<typename Piece::Type>(type))));
514 virtual void forallPieces(class PieceFunction& f) {
515 Variant::forallPieces(f);
517 virtual int moveListLayout() const {
518 return Variant::moveListLayout();
520 virtual AbstractAnimator::Ptr createAnimator(GraphicalAPI* graphical_api) {
521 return AbstractAnimator::Ptr(
522 new WrappedAnimator<Variant>(
523 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
524 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
526 virtual AbstractMove::Ptr createNormalMove(const NormalUserMove& move) {
527 return AbstractMove::Ptr(new WrappedMove<Variant>(
528 MoveFactory<Variant>::createNormalMove(move)));
530 virtual AbstractMove::Ptr createDropMove(const DropUserMove& move) {
531 return AbstractMove::Ptr(new WrappedMove<Variant>(
532 MoveFactory<Variant>::createDropMove(move)));
535 virtual AbstractMove::Ptr getVerboseMove(int turn, const VerboseNotation& m) const {
536 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
537 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
539 virtual int type(const QString& str) {
540 return Piece::getType(str);
542 virtual QString typeSymbol(int type) {
543 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
545 virtual bool simpleMoves() {
546 return Variant::m_simple_moves;
548 virtual QString name() const {
549 return Variant::m_name;
551 virtual QString themeProxy() const {
552 return Variant::m_theme_proxy;
554 virtual OptList positionOptions() const {
555 return Variant::positionOptions();
559 #endif // HIGHLEVEL_H