Removed AlgebraicNotation from the variant API.
[tagua/yd.git] / src / tagua_wrapped.h
blob2bcc346c44ade97f12f3b8a0d836622c294d5bae
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 "icsapi.h"
18 #include "tagua.h"
19 #include "movefactory.h"
20 #include "piecefactory.h"
21 #include "moveserializer.h"
22 #include "nopool.h"
23 #include "algebraicnotation.h"
25 template <typename V> class WrappedPiece;
26 template <typename V> class WrappedMove;
27 template <typename V> class WrappedPosition;
29 /**
30 * @brief Wrap an high level position definition
31 * in a low level AbstractPosition implementation.
33 * Use this class to wrap an high level position definition
34 * in an AbstractPosition implementation suitable for communicating
35 * with the tagua infrastructure.
36 * Variant should be a structure with inner types Position, Move and Piece.
38 * @section Requirements on Position
40 * Position should define the following functions:
41 * - static Point size();
42 * - Piece* operator[](const Point& p) const;
43 * - Piece::Color turn() const;
44 * - void switchTurn();
45 * - bool testMove(Move& m) const;
46 * - void move(const Move& m);
47 * - void setup();
49 * @section Requirements on Piece
51 * Piece should have inner types Color and Type, each
52 * convertible to int via static_cast.
53 * Furthermore, it should implement the following
54 * functions:
55 * - Piece::Type type() const;
56 * - Piece::Color color() const;
57 * - QString name() const;
58 * - static QString typeSymbol(Piece::Type type);
60 * @section Move serialization
62 * To customize move serialization, one should specialize
63 * the template MoveSerializer<Pos>.
67 #ifdef Q_CC_GNU
68 #define __FUNC__ __PRETTY_FUNCTION__
69 #else
70 #define __FUNC__ __FUNCTION__
71 #endif
73 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
74 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
75 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
76 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
78 #define TYPECHECK(x,y) if (typeid(x) != typeid(y)) MISMATCH(x,y); else { }
80 /**
81 * Helper metafunction to create a null ICSAPI object
82 * if the variant does not support ICS.
84 template <typename Variant, bool hasICS>
85 struct ReturnICSAPI { };
87 template <typename Variant>
88 struct ReturnICSAPI<Variant, true> {
89 static ICSAPI* apply() {
90 return new WrappedICSAPI<Variant>();
94 template <typename Variant>
95 struct ReturnICSAPI<Variant, false> {
96 static ICSAPI* apply() { return 0; }
100 template <typename Variant>
101 class WrappedPiece : public AbstractPiece {
102 typedef typename Variant::Piece Piece;
104 Piece m_piece;
105 public:
106 const Piece& inner() const { return m_piece; }
108 WrappedPiece(const Piece& piece)
109 : m_piece(piece) { }
111 virtual bool equals(const PiecePtr& _other) const {
112 if (!_other) return false;
113 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
115 if (other)
116 return m_piece == other->inner();
117 else {
118 MISMATCH(*_other.get(),WrappedPiece<Variant>);
119 return false;
123 virtual QString name() const {
124 return m_piece.name();
127 virtual QString typeSymbol() const {
128 return Piece::typeSymbol(m_piece.type());
131 virtual PiecePtr clone() const {
132 return PiecePtr(new WrappedPiece<Variant>(m_piece));
137 template <typename Variant>
138 class WrappedMove : public AbstractMove {
139 typedef typename Variant::Move Move;
140 typedef typename Variant::Position Position;
142 Move m_move;
143 public:
144 const Move& inner() const { return m_move; }
146 WrappedMove(const Move& move)
147 : m_move(move) { }
149 virtual QString SAN(const PositionPtr& _pos) const {
150 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
152 if (pos) {
153 MoveSerializer<Position> serializer(m_move, pos->inner());
154 return serializer.SAN();
156 else {
157 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
158 return "$@%";
162 virtual DecoratedMove toDecoratedMove(const PositionPtr& _pos) const {
163 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
165 if (pos) {
166 MoveSerializer<Position> serializer(m_move, pos->inner());
167 return serializer.toDecoratedMove();
169 else {
170 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
171 return DecoratedMove();
175 virtual QString toString(const PositionPtr& _pos) const {
176 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
178 if (pos)
179 return m_move.toString(pos->inner().size().y);
180 else {
181 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
182 return "$@%";
186 virtual NormalUserMove toUserMove() const {
187 return MoveFactory<Variant>::toNormal(m_move);
190 virtual bool equals(const MovePtr& _other) const {
191 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
193 if (other)
194 return m_move == other->inner();
195 else {
196 MISMATCH(*_other.get(),WrappedMove<Variant>);
197 return false;
202 template <typename Variant, typename Pool>
203 class WrappedPoolBase : public AbstractPool {
204 typedef typename Variant::Piece Piece;
206 Pool m_pool;
207 public:
208 WrappedPoolBase(Pool pool)
209 : m_pool(pool) { }
211 virtual int size() {
212 return m_pool.size();
215 virtual int insert(int pref_index, const PiecePtr& _piece) {
216 if (!_piece) {
217 return m_pool.insert(pref_index, Piece());
219 else {
220 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
222 if (piece)
223 return m_pool.insert(pref_index, Piece(piece->inner()) );
224 else {
225 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
226 return -1;
231 virtual PiecePtr get(int index) {
232 Piece piece = m_pool.get(index);
233 if (piece)
234 return PiecePtr(new WrappedPiece<Variant>(piece));
235 else
236 return PiecePtr();
239 virtual PiecePtr take(int index) {
240 Piece piece = m_pool.take(index);
241 if (piece)
242 return PiecePtr(new WrappedPiece<Variant>(piece));
243 else
244 return PiecePtr();
248 // simple special case for NoPool
249 template <typename Variant>
250 class WrappedPoolBase<Variant, NoPool> : public AbstractPool {
251 public:
252 WrappedPoolBase(NoPool) { }
255 template <typename Variant>
256 class WrappedPool : public WrappedPoolBase<Variant, typename Variant::Pool> {
257 public:
258 WrappedPool(typename Variant::Pool pool)
259 : WrappedPoolBase<Variant, typename Variant::Pool>(pool) { }
263 * Metafunction that returns a null pointer when
264 * its template argument is NoPool.
266 template <typename Variant, typename Pool>
267 struct ReturnPool {
268 static PoolPtr apply(typename Variant::Position& position, int player) {
269 return PoolPtr(
270 new WrappedPool<Variant>(position.pool(player)));
274 template <typename Variant>
275 struct ReturnPool<Variant, NoPool> {
276 static PoolPtr apply(typename Variant::Position&, int) {
277 return PoolPtr();
282 * Metafunction to assign pools of a position to another.
284 template <typename Variant, typename Pool>
285 struct AssignPool {
286 static void apply(typename Variant::Position& pos1, const typename Variant::Position& pos2) {
287 pos1.setRawPool(pos2.rawPool());
291 template <typename Variant>
292 struct AssignPool<Variant, NoPool> {
293 static void apply(typename Variant::Position&, const typename Variant::Position&) { }
296 template <typename Variant>
297 class WrappedPosition : public AbstractPosition {
298 typedef typename Variant::Position Position;
299 typedef typename Variant::Move Move;
300 typedef typename Variant::Piece Piece;
301 typedef typename Variant::Pool Pool;
303 Position m_pos;
304 public:
305 const Position& inner() const { return m_pos; }
306 Position& inner() { return m_pos; }
308 WrappedPosition(const Position& pos)
309 : m_pos(pos) { }
311 virtual Point size() const {
312 return inner().size();
315 virtual QStringList borderCoords() const {
316 return inner().borderCoords();
319 virtual void setup() {
320 m_pos.setup();
323 virtual PiecePtr get(const Point& p) const {
324 Piece piece = m_pos.get(p);
325 if (piece)
326 return PiecePtr(new WrappedPiece<Variant>(piece));
327 else
328 return PiecePtr();
331 virtual void set(const Point& p, const PiecePtr& _piece) {
332 if (!_piece) {
333 m_pos.set(p, Piece());
335 else {
336 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
338 if (piece)
339 m_pos.set(p, piece->inner() );
340 else
341 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
345 virtual PoolPtr pool(int player) {
346 return ReturnPool<Variant, Pool>::apply(m_pos, player);
349 virtual void copyPoolFrom(const PositionPtr& _pos) {
350 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
351 if (pos) {
352 AssignPool<Variant, Pool>::apply(m_pos, pos->inner());
354 else {
355 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
359 virtual InteractionType movable(const TurnTest& test, const Point& p) const {
360 return m_pos.movable(test, p);
363 virtual InteractionType droppable(const TurnTest& test, int p) const {
364 return m_pos.droppable(test, p);
367 virtual int turn() const {
368 return static_cast<int>(m_pos.turn());
371 virtual void setTurn(int turn) {
372 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
375 virtual int previousTurn() const {
376 return static_cast<int>(m_pos.previousTurn());
379 virtual void switchTurn() {
380 m_pos.switchTurn();
383 virtual bool testMove(const MovePtr& _move) const {
384 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
386 if (move)
387 return m_pos.testMove( const_cast<Move&>(move->inner()) );
388 else {
389 MISMATCH(*_move.get(),WrappedMove<Variant>);
390 return false;
394 virtual void move(const MovePtr& _move) {
395 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
397 if (move)
398 m_pos.move(move->inner());
399 else
400 MISMATCH(*_move.get(),WrappedMove<Variant>);
403 virtual PositionPtr clone() const {
404 return PositionPtr(new WrappedPosition<Variant>(m_pos));
407 virtual void copyFrom(const PositionPtr& _p) {
408 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
410 if (p)
411 m_pos = p->inner();
412 else
413 MISMATCH(*_p.get(),WrappedPosition);
416 virtual bool equals(const PositionPtr& _other) const {
417 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
419 if(other)
420 return m_pos == other->inner();
421 else {
422 MISMATCH(*_other.get(),WrappedPosition<Variant>);
423 return false;
427 virtual MovePtr getMove(const AlgebraicNotation& san) const {
428 bool ok;
429 Move res = m_pos.getMove(san, ok);
430 if (ok)
431 return MovePtr(new WrappedMove<Variant>(res));
432 else
433 return MovePtr();
436 virtual MovePtr getMove(const QString& san) const {
437 AlgebraicNotation move(san, size().y); //FIXME
438 if(!move.valid())
439 return MovePtr();
440 return getMove(move);
443 virtual QString state() const {
444 return ""; // TODO
447 virtual QString fen(int halfmove, int fullmove) const {
448 return m_pos.fen(halfmove, fullmove);
451 virtual PiecePtr moveHint(const MovePtr& _move) const {
452 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
454 if (move) {
455 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
456 return PiecePtr(
457 new WrappedPiece<Variant>(Piece(*hint)));
459 else {
460 MISMATCH(*_move.get(),WrappedMove<Variant>);
463 return PiecePtr();
466 virtual QString variant() const {
467 return Variant::m_name;
470 virtual void dump() const {
471 m_pos.dump();
476 template <typename Variant>
477 class WrappedAnimator : public AbstractAnimator {
478 typedef typename Variant::Position Position;
479 typedef typename Variant::Animator Animator;
480 typedef typename Variant::Move Move;
482 Animator m_animator;
483 public:
484 const Animator& inner() const { return m_animator; }
486 WrappedAnimator(const Animator& animator)
487 : m_animator(animator) { }
489 virtual AnimationPtr warp(const PositionPtr& _pos) {
490 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
491 if (pos)
492 return m_animator.warp(pos->inner());
493 else {
494 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
495 return AnimationPtr();
499 virtual AnimationPtr forward(const PositionPtr& _pos, const MovePtr& _move) {
500 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
501 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
503 if (move && pos)
504 return m_animator.forward(pos->inner(), move->inner());
505 else {
506 if (!move)
507 MISMATCH(*_move.get(), WrappedMove<Variant>);
508 if (!pos)
509 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
510 return AnimationPtr();
514 virtual AnimationPtr back(const PositionPtr& _pos, const MovePtr& _move) {
515 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
516 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
518 if (move && pos)
519 return m_animator.back(pos->inner(), move->inner());
520 else {
521 if (!move)
522 MISMATCH(*_move.get(), WrappedMove<Variant>);
523 if (!pos)
524 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
525 return AnimationPtr();
530 #include "graphicalapi_unwrapped.h"
532 template <typename Variant>
533 class WrappedVariantInfo : public VariantInfo {
534 public:
535 typedef typename Variant::Animator Animator;
536 typedef typename Variant::Position Position;
537 typedef typename Variant::Piece Piece;
538 typedef typename Variant::Move Move;
539 typedef typename Variant::Pool Pool;
541 virtual PositionPtr createPosition() {
542 return PositionPtr(
543 new WrappedPosition<Variant>(Position()));
546 virtual PositionPtr createCustomPosition(const OptList& l) {
547 return PositionPtr(
548 new WrappedPosition<Variant>(Position(l)));
551 virtual PositionPtr createPositionFromFEN(const QString& fen) {
552 std::auto_ptr<WrappedPosition<Variant> > res(
553 new WrappedPosition<Variant>(Position()));
554 bool ok;
555 res->inner().fromFEN(fen, ok);
556 if (ok) {
557 return PositionPtr(res.release());
559 else return PositionPtr();
561 virtual void forallPieces(class PieceFunction& f) {
562 Variant::forallPieces(f);
564 virtual int moveListLayout() const {
565 return Variant::moveListLayout();
567 virtual AnimatorPtr createAnimator(GraphicalAPI* graphical_api) {
568 return AnimatorPtr(
569 new WrappedAnimator<Variant>(
570 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
571 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
573 virtual MovePtr createNormalMove(const NormalUserMove& move) {
574 return MovePtr(new WrappedMove<Variant>(
575 MoveFactory<Variant>::createNormalMove(move)));
577 virtual MovePtr createDropMove(const DropUserMove& move) {
578 return MovePtr(new WrappedMove<Variant>(
579 MoveFactory<Variant>::createDropMove(move)));
582 virtual MovePtr getVerboseMove(int turn, const VerboseNotation& m) const {
583 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
584 return MovePtr(new WrappedMove<Variant>(res));
587 virtual int type(const QString& str) {
588 return Piece::getType(str);
590 virtual QString typeSymbol(int type) {
591 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
593 virtual bool simpleMoves() {
594 return Variant::m_simple_moves;
596 virtual QString name() const {
597 return Variant::m_name;
599 virtual QString themeProxy() const {
600 return Variant::m_theme_proxy;
602 virtual OptList positionOptions() const {
603 return Variant::positionOptions();
605 virtual ICSAPIPtr icsAPI() const {
606 return ICSAPIPtr(ReturnICSAPI<Variant, Variant::hasICS>::apply());
610 #endif // HIGHLEVEL_H