Merge branch 'pool_rebirth'
[tagua/yd.git] / src / kboard_wrapped.h
blobe3a474cbe9a28569245eb46ae95f9ef1802b63c6
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)));
283 virtual InteractionType movable(const Point& p) const {
284 return m_pos.movable(p);
287 virtual InteractionType droppable(int p) const {
288 return m_pos.droppable(p);
291 virtual int turn() const {
292 return static_cast<int>(m_pos.turn());
295 virtual void setTurn(int turn) {
296 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
299 virtual int previousTurn() const {
300 return static_cast<int>(m_pos.previousTurn());
303 virtual void switchTurn() {
304 m_pos.switchTurn();
307 virtual bool testMove(AbstractMove::Ptr _move) const {
308 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
310 if (move)
311 return m_pos.testMove( const_cast<Move&>(move->inner()) );
312 else {
313 MISMATCH(*_move.get(),WrappedMove<Variant>);
314 return false;
318 virtual void move(AbstractMove::Ptr _move) {
319 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
321 if (move)
322 m_pos.move(move->inner());
323 else
324 MISMATCH(*_move.get(),WrappedMove<Variant>);
327 virtual AbstractPosition::Ptr clone() const {
328 return AbstractPosition::Ptr(new WrappedPosition<Variant>(m_pos));
331 virtual void copyFrom(const AbstractPosition::Ptr& _p) {
332 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
334 if (p)
335 m_pos = p->inner();
336 else
337 MISMATCH(*_p.get(),WrappedPosition);
340 virtual bool equals(AbstractPosition::Ptr _other) const {
341 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
343 if(other)
344 return m_pos == other->inner();
345 else {
346 MISMATCH(*_other.get(),WrappedPosition<Variant>);
347 return false;
351 virtual AbstractMove::Ptr getMove(const AlgebraicNotation& san) const {
352 bool ok;
353 Move res = m_pos.getMove(san, ok);
354 if (ok)
355 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
356 else
357 return AbstractMove::Ptr();
360 virtual AbstractMove::Ptr getMove(const QString& san) const {
361 AlgebraicNotation move(san, size().y); //FIXME
362 if(!move.valid())
363 return AbstractMove::Ptr();
364 return getMove(move);
367 virtual QString state() const {
368 return ""; // TODO
371 virtual QString fen(int halfmove, int fullmove) const {
372 return m_pos.fen(halfmove, fullmove);
375 virtual AbstractPiece::Ptr moveHint(AbstractMove::Ptr _move) const {
376 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
378 if (move) {
379 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
380 return AbstractPiece::Ptr(
381 new WrappedPiece<Variant>(Piece(*hint)));
383 else {
384 MISMATCH(*_move.get(),WrappedMove<Variant>);
387 return AbstractPiece::Ptr();
390 virtual QString variant() const {
391 return Variant::m_name;
394 virtual void dump() const {
395 m_pos.dump();
400 template <typename Variant>
401 class WrappedAnimator : public AbstractAnimator {
402 typedef typename Variant::Position Position;
403 typedef typename Variant::Animator Animator;
404 typedef typename Variant::Move Move;
406 Animator m_animator;
407 public:
408 const Animator& inner() const { return m_animator; }
410 WrappedAnimator(const Animator& animator)
411 : m_animator(animator) { }
413 virtual AnimationPtr warp(AbstractPosition::Ptr _pos) {
414 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
415 if (pos)
416 return m_animator.warp(pos->inner());
417 else {
418 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
419 return AnimationPtr();
423 virtual AnimationPtr forward(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
424 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
425 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
427 if (move && pos)
428 return m_animator.forward(pos->inner(), move->inner());
429 else {
430 if (!move)
431 MISMATCH(*_move.get(), WrappedMove<Variant>);
432 if (!pos)
433 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
434 return AnimationPtr();
438 virtual AnimationPtr back(AbstractPosition::Ptr _pos, AbstractMove::Ptr _move) {
439 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
440 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
442 if (move && pos)
443 return m_animator.back(pos->inner(), move->inner());
444 else {
445 if (!move)
446 MISMATCH(*_move.get(), WrappedMove<Variant>);
447 if (!pos)
448 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
449 return AnimationPtr();
454 #include "graphicalapi_unwrapped.h"
456 template <typename Variant>
457 class WrappedVariantInfo : public VariantInfo {
458 public:
459 typedef typename Variant::Animator Animator;
460 typedef typename Variant::Position Position;
461 typedef typename Variant::Piece Piece;
462 typedef typename Variant::Move Move;
463 typedef typename Variant::Pool Pool;
465 virtual AbstractPosition::Ptr createPosition() {
466 return AbstractPosition::Ptr(
467 new WrappedPosition<Variant>(Position()));
470 virtual AbstractPosition::Ptr createCustomPosition(const OptList& l) {
471 return AbstractPosition::Ptr(
472 new WrappedPosition<Variant>(Position(l)));
475 virtual AbstractPosition::Ptr createPositionFromFEN(const QString& fen) {
476 std::auto_ptr<WrappedPosition<Variant> > res(
477 new WrappedPosition<Variant>(Position()));
478 bool ok;
479 res->inner().fromFEN(fen, ok);
480 if (ok) {
481 return AbstractPosition::Ptr(res.release());
483 else return AbstractPosition::Ptr();
486 virtual AbstractPosition::Ptr createChessboard(int turn,
487 bool wk, bool wq, bool bk, bool bq,
488 const Point& ep) {
489 return AbstractPosition::Ptr(
490 new WrappedPosition<Variant>(Position(
491 static_cast<typename Piece::Color>(turn),
492 wk, wq, bk, bq, ep)));
494 virtual AbstractPiece::Ptr createPiece(int color, int type) {
495 return AbstractPiece::Ptr(
496 new WrappedPiece<Variant>(Piece(
497 static_cast<typename Piece::Color>(color),
498 static_cast<typename Piece::Type>(type))));
500 virtual void forallPieces(class PieceFunction& f) {
501 Variant::forallPieces(f);
503 virtual int moveListLayout() const {
504 return Variant::moveListLayout();
506 virtual AbstractAnimator::Ptr createAnimator(GraphicalAPI* graphical_api) {
507 return AbstractAnimator::Ptr(
508 new WrappedAnimator<Variant>(
509 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
510 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
512 virtual AbstractMove::Ptr createNormalMove(const NormalUserMove& move) {
513 return AbstractMove::Ptr(new WrappedMove<Variant>(
514 MoveFactory<Variant>::createNormalMove(move)));
516 virtual AbstractMove::Ptr createDropMove(const DropUserMove& move) {
517 return AbstractMove::Ptr(new WrappedMove<Variant>(
518 MoveFactory<Variant>::createDropMove(move)));
521 virtual AbstractMove::Ptr getVerboseMove(int turn, const VerboseNotation& m) const {
522 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
523 return AbstractMove::Ptr(new WrappedMove<Variant>(res));
525 virtual int type(const QString& str) {
526 return Piece::getType(str);
528 virtual QString typeSymbol(int type) {
529 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
531 virtual bool simpleMoves() {
532 return Variant::m_simple_moves;
534 virtual QString name() const {
535 return Variant::m_name;
537 virtual QString themeProxy() const {
538 return Variant::m_theme_proxy;
540 virtual OptList positionOptions() const {
541 return Variant::positionOptions();
545 #endif // HIGHLEVEL_H