No more pool method in AbstractPosition...
[tagua/yd.git] / src / kboard_wrapped.h
blob5fd8ee21bb5ff8862b01490d5d1f28b559d29221
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 "algebraicnotation.h"
22 template <typename V> class WrappedPiece;
23 template <typename V> class WrappedMove;
24 template <typename V> class WrappedPosition;
26 /**
27 * @brief Wrap an high level position definition
28 * in a low level AbstractPosition implementation.
30 * Use this class to wrap an high level position definition
31 * in an AbstractPosition implementation suitable for communicating
32 * with the kboard infrastructure.
33 * Variant should be a structure with inner types Position, Move and Piece.
35 * @section Requirements on Position
37 * Position should define the following functions:
38 * - static Point size();
39 * - Piece* operator[](const Point& p) const;
40 * - Piece::Color turn() const;
41 * - void switchTurn();
42 * - bool testMove(Move& m) const;
43 * - void move(const Move& m);
44 * - void setup();
46 * @section Requirements on Piece
48 * Piece should have inner types Color and Type, each
49 * convertible to int via static_cast.
50 * Furthermore, it should implement the following
51 * functions:
52 * - Piece::Type type() const;
53 * - Piece::Color color() const;
54 * - QString name() const;
55 * - static QString typeSymbol(Piece::Type type);
57 * @section Move serialization
59 * To customize move serialization, one should specialize
60 * the template MoveSerializer<Pos>.
64 #ifdef Q_CC_GNU
65 #define __FUNC__ __PRETTY_FUNCTION__
66 #else
67 #define __FUNC__ __FUNCTION__
68 #endif
70 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
71 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
72 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
73 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
75 #define TYPECHECK(x,y) if (typeid(x) != typeid(y)) MISMATCH(x,y); else { }
79 template <typename Variant>
80 class WrappedPiece : public AbstractPiece {
81 typedef typename Variant::Piece Piece;
83 Piece m_piece;
84 public:
85 const Piece& inner() const { return m_piece; }
87 WrappedPiece(const Piece& piece)
88 : m_piece(piece) { }
90 virtual bool equals(AbstractPiece::Ptr _other) const {
91 if (!_other) return false;
92 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
94 if (other)
95 return m_piece == other->inner();
96 else {
97 MISMATCH(*_other.get(),WrappedPiece<Variant>);
98 return false;
102 virtual QString name() const {
103 return m_piece.name();
106 virtual QString typeSymbol() const {
107 return Piece::typeSymbol(m_piece.type());
110 virtual AbstractPiece::Ptr clone() const {
111 return AbstractPiece::Ptr(new WrappedPiece<Variant>(m_piece));
116 template <typename Variant>
117 class WrappedMove : public AbstractMove {
118 typedef typename Variant::Move Move;
119 typedef typename Variant::Position Position;
121 Move m_move;
122 public:
123 const Move& inner() const { return m_move; }
125 WrappedMove(const Move& move)
126 : m_move(move) { }
128 virtual QString SAN(AbstractPosition::Ptr _pos) const {
129 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
131 if (pos) {
132 MoveSerializer<Position> serializer(m_move, pos->inner());
133 return serializer.SAN();
135 else {
136 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
137 return "$@%";
141 virtual DecoratedMove toDecoratedMove(boost::shared_ptr<AbstractPosition> _pos) const {
142 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
144 if (pos) {
145 MoveSerializer<Position> serializer(m_move, pos->inner());
146 return serializer.toDecoratedMove();
148 else {
149 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
150 return DecoratedMove();
154 virtual QString toString(AbstractPosition::Ptr _pos) const {
155 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
157 if (pos)
158 return m_move.toString(pos->inner().size().y);
159 else {
160 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
161 return "$@%";
165 virtual NormalUserMove toUserMove() const {
166 return MoveFactory<Variant>::toNormal(m_move);
169 virtual bool equals(AbstractMove::Ptr _other) const {
170 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
172 if (other)
173 return m_move == other->inner();
174 else {
175 MISMATCH(*_other.get(),WrappedMove<Variant>);
176 return false;
182 template <typename Variant>
183 class WrappedPool : public AbstractPool {
184 typedef typename Variant::Pool Pool;
185 typedef typename Variant::Piece Piece;
187 Pool m_pool;
188 public:
189 WrappedPool(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();
230 template <typename Variant>
231 class WrappedPosition : public AbstractPosition {
232 typedef typename Variant::Position Position;
233 typedef typename Variant::Move Move;
234 typedef typename Variant::Piece Piece;
235 typedef typename Variant::Pool Pool;
237 Position m_pos;
238 public:
239 const Position& inner() const { return m_pos; }
240 Position& inner() { return m_pos; }
242 WrappedPosition(const Position& pos)
243 : m_pos(pos) { }
245 virtual Point size() const {
246 return inner().size();
249 virtual QStringList borderCoords() const {
250 return inner().borderCoords();
253 virtual void setup() {
254 m_pos.setup();
257 virtual AbstractPiece::Ptr get(const Point& p) const {
258 Piece piece = m_pos.get(p);
259 if (piece)
260 return AbstractPiece::Ptr(new WrappedPiece<Variant>(piece));
261 else
262 return AbstractPiece::Ptr();
265 virtual void set(const Point& p, AbstractPiece::Ptr _piece) {
266 if (!_piece) {
267 m_pos.set(p, Piece());
269 else {
270 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
272 if (piece)
273 m_pos.set(p, piece->inner() );
274 else
275 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
279 // virtual AbstractPool::Ptr pool(int player) {
280 // // return AbstractPool::Ptr(new WrappedPool<Variant>(m_pos.pool(player)));
281 // return AbstractPool::Ptr();
282 // }
284 virtual InteractionType movable(const Point& p) const {
285 return m_pos.movable(p);
288 virtual InteractionType droppable(int p) const {
289 return m_pos.droppable(p);
292 virtual int turn() const {
293 return static_cast<int>(m_pos.turn());
296 virtual void setTurn(int turn) {
297 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
300 virtual int previousTurn() const {
301 return static_cast<int>(m_pos.previousTurn());
304 virtual void switchTurn() {
305 m_pos.switchTurn();
308 virtual bool testMove(AbstractMove::Ptr _move) const {
309 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
311 if (move)
312 return m_pos.testMove( const_cast<Move&>(move->inner()) );
313 else {
314 MISMATCH(*_move.get(),WrappedMove<Variant>);
315 return false;
319 virtual void move(AbstractMove::Ptr _move) {
320 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
322 if (move)
323 m_pos.move(move->inner());
324 else
325 MISMATCH(*_move.get(),WrappedMove<Variant>);
328 virtual AbstractPosition::Ptr clone() const {
329 return AbstractPosition::Ptr(new WrappedPosition<Variant>(m_pos));
332 virtual void copyFrom(const AbstractPosition::Ptr& _p) {
333 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
335 if (p)
336 m_pos = p->inner();
337 else
338 MISMATCH(*_p.get(),WrappedPosition);
341 virtual bool equals(AbstractPosition::Ptr _other) const {
342 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
344 if(other)
345 return m_pos == other->inner();
346 else {
347 MISMATCH(*_other.get(),WrappedPosition<Variant>);
348 return false;
352 virtual AbstractMove::Ptr getMove(const AlgebraicNotation& san) const {
353 bool ok;
354 Move res = m_pos.getMove(san, ok);
355 if (ok)
356 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
357 else
358 return AbstractMove::Ptr();
361 virtual AbstractMove::Ptr getMove(const QString& san) const {
362 AlgebraicNotation move(san, size().y); //FIXME
363 if(!move.valid())
364 return AbstractMove::Ptr();
365 return getMove(move);
368 virtual QString state() const {
369 return ""; // TODO
372 virtual QString fen(int halfmove, int fullmove) const {
373 return m_pos.fen(halfmove, fullmove);
376 virtual AbstractPiece::Ptr moveHint(AbstractMove::Ptr _move) const {
377 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
379 if (move) {
380 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
381 return AbstractPiece::Ptr(
382 new WrappedPiece<Variant>(Piece(*hint)));
384 else {
385 MISMATCH(*_move.get(),WrappedMove<Variant>);
388 return AbstractPiece::Ptr();
391 virtual QString variant() const {
392 return Variant::m_name;
395 virtual void dump() const {
396 m_pos.dump();
401 template <typename Variant>
402 class WrappedAnimator : public AbstractAnimator {
403 typedef typename Variant::Position Position;
404 typedef typename Variant::Animator Animator;
405 typedef typename Variant::Move Move;
407 Animator m_animator;
408 public:
409 const Animator& inner() const { return m_animator; }
411 WrappedAnimator(const Animator& animator)
412 : m_animator(animator) { }
414 virtual AnimationPtr warp(AbstractPosition::Ptr _pos) {
415 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
416 if (pos)
417 return m_animator.warp(pos->inner());
418 else {
419 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
420 return AnimationPtr();
424 virtual AnimationPtr forward(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
425 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
426 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
428 if (move && pos)
429 return m_animator.forward(pos->inner(), move->inner());
430 else {
431 if (!move)
432 MISMATCH(*_move.get(), WrappedMove<Variant>);
433 if (!pos)
434 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
435 return AnimationPtr();
439 virtual AnimationPtr back(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
440 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
441 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
443 if (move && pos)
444 return m_animator.back(pos->inner(), move->inner());
445 else {
446 if (!move)
447 MISMATCH(*_move.get(), WrappedMove<Variant>);
448 if (!pos)
449 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
450 return AnimationPtr();
455 #include "graphicalapi_unwrapped.h"
457 template <typename Variant>
458 class WrappedVariantInfo : public VariantInfo {
459 public:
460 typedef typename Variant::Animator Animator;
461 typedef typename Variant::Position Position;
462 typedef typename Variant::Piece Piece;
463 typedef typename Variant::Move Move;
464 typedef typename Variant::Pool Pool;
466 virtual AbstractPosition::Ptr createPosition() {
467 return AbstractPosition::Ptr(
468 new WrappedPosition<Variant>(Position()));
471 virtual AbstractPosition::Ptr createCustomPosition(const OptList& l) {
472 return AbstractPosition::Ptr(
473 new WrappedPosition<Variant>(Position(l)));
476 virtual AbstractPosition::Ptr createPositionFromFEN(const QString& fen) {
477 std::auto_ptr<WrappedPosition<Variant> > res(
478 new WrappedPosition<Variant>(Position()));
479 bool ok;
480 res->inner().fromFEN(fen, ok);
481 if (ok) {
482 return AbstractPosition::Ptr(res.release());
484 else return AbstractPosition::Ptr();
487 virtual AbstractPosition::Ptr createChessboard(int turn,
488 bool wk, bool wq, bool bk, bool bq,
489 const Point& ep) {
490 return AbstractPosition::Ptr(
491 new WrappedPosition<Variant>(Position(
492 static_cast<typename Piece::Color>(turn),
493 wk, wq, bk, bq, ep)));
495 virtual AbstractPiece::Ptr createPiece(int color, int type) {
496 return AbstractPiece::Ptr(
497 new WrappedPiece<Variant>(Piece(
498 static_cast<typename Piece::Color>(color),
499 static_cast<typename Piece::Type>(type))));
501 virtual void forallPieces(class PieceFunction& f) {
502 Variant::forallPieces(f);
504 virtual int moveListLayout() const {
505 return Variant::moveListLayout();
507 virtual AbstractAnimator::Ptr createAnimator(GraphicalAPI* graphical_api) {
508 return AbstractAnimator::Ptr(
509 new WrappedAnimator<Variant>(
510 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
511 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
513 virtual AbstractMove::Ptr createNormalMove(const NormalUserMove& move) {
514 return AbstractMove::Ptr(new WrappedMove<Variant>(
515 MoveFactory<Variant>::createNormalMove(move)));
517 virtual AbstractMove::Ptr createDropMove(const DropUserMove& move) {
518 return AbstractMove::Ptr(new WrappedMove<Variant>(
519 MoveFactory<Variant>::createDropMove(move)));
522 virtual AbstractMove::Ptr getVerboseMove(int turn, const VerboseNotation& m) const {
523 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
524 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
526 virtual int type(const QString& str) {
527 return Piece::getType(str);
529 virtual QString typeSymbol(int type) {
530 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
532 virtual bool simpleMoves() {
533 return Variant::m_simple_moves;
535 virtual QString name() const {
536 return Variant::m_name;
538 virtual QString themeProxy() const {
539 return Variant::m_theme_proxy;
541 virtual OptList positionOptions() const {
542 return Variant::positionOptions();
546 #endif // HIGHLEVEL_H