Removed all old variants.
[tagua/yd.git] / src / tagua_wrapped.h
blob9933fc54a85f5ec50e3f251f01cbaabbfac334b5
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"
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 tagua 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 { }
79 /**
80 * Helper metafunction to create a null ICSAPI object
81 * if the variant does not support ICS.
83 template <typename Variant, bool hasICS>
84 struct ReturnICSAPI { };
86 template <typename Variant>
87 struct ReturnICSAPI<Variant, true> {
88 static ICSAPI* apply() {
89 return new WrappedICSAPI<Variant>();
93 template <typename Variant>
94 struct ReturnICSAPI<Variant, false> {
95 static ICSAPI* apply() { return 0; }
99 template <typename Variant>
100 class WrappedPiece : public AbstractPiece {
101 typedef typename Variant::Piece Piece;
103 Piece m_piece;
104 public:
105 const Piece& inner() const { return m_piece; }
107 WrappedPiece(const Piece& piece)
108 : m_piece(piece) { }
110 virtual bool equals(const PiecePtr& _other) const {
111 if (!_other) return false;
112 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
114 if (other)
115 return m_piece == other->inner();
116 else {
117 MISMATCH(*_other.get(),WrappedPiece<Variant>);
118 return false;
122 virtual QString name() const {
123 return m_piece.name();
126 virtual QString typeSymbol() const {
127 return Piece::typeSymbol(m_piece.type());
130 virtual PiecePtr clone() const {
131 return PiecePtr(new WrappedPiece<Variant>(m_piece));
136 template <typename Variant>
137 class WrappedMove : public AbstractMove {
138 typedef typename Variant::Move Move;
139 typedef typename Variant::Position Position;
141 Move m_move;
142 public:
143 const Move& inner() const { return m_move; }
145 WrappedMove(const Move& move)
146 : m_move(move) { }
148 virtual QString SAN(const PositionPtr& _pos) const {
149 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
151 if (pos) {
152 MoveSerializer<Position> serializer(m_move, pos->inner());
153 return serializer.SAN();
155 else {
156 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
157 return "$@%";
161 virtual DecoratedMove toDecoratedMove(const PositionPtr& _pos) const {
162 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
164 if (pos) {
165 MoveSerializer<Position> serializer(m_move, pos->inner());
166 return serializer.toDecoratedMove();
168 else {
169 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
170 return DecoratedMove();
174 virtual QString toString(const PositionPtr& _pos) const {
175 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
177 if (pos)
178 return m_move.toString(pos->inner().size().x, pos->inner().size().y);
179 else {
180 MISMATCH(*_pos.get(),WrappedPosition<Variant>);
181 return "$@%";
185 virtual NormalUserMove toUserMove() const {
186 return MoveFactory<Variant>::toNormal(m_move);
189 virtual bool equals(const MovePtr& _other) const {
190 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
192 if (other)
193 return m_move == other->inner();
194 else {
195 MISMATCH(*_other.get(),WrappedMove<Variant>);
196 return false;
201 template <typename Variant, typename Pool>
202 class WrappedPoolBase : public AbstractPool {
203 typedef typename Variant::Piece Piece;
205 Pool m_pool;
206 public:
207 WrappedPoolBase(Pool pool)
208 : m_pool(pool) { }
210 virtual int size() {
211 return m_pool.size();
214 virtual int insert(int pref_index, const PiecePtr& _piece) {
215 if (!_piece) {
216 return m_pool.insert(pref_index, Piece());
218 else {
219 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
221 if (piece)
222 return m_pool.insert(pref_index, Piece(piece->inner()) );
223 else {
224 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
225 return -1;
230 virtual PiecePtr get(int index) {
231 Piece piece = m_pool.get(index);
232 if (piece)
233 return PiecePtr(new WrappedPiece<Variant>(piece));
234 else
235 return PiecePtr();
238 virtual PiecePtr take(int index) {
239 Piece piece = m_pool.take(index);
240 if (piece)
241 return PiecePtr(new WrappedPiece<Variant>(piece));
242 else
243 return PiecePtr();
247 // simple special case for NoPool
248 template <typename Variant>
249 class WrappedPoolBase<Variant, NoPool> : public AbstractPool {
250 public:
251 WrappedPoolBase(NoPool) { }
254 template <typename Variant>
255 class WrappedPool : public WrappedPoolBase<Variant, typename Variant::Pool> {
256 public:
257 WrappedPool(typename Variant::Pool pool)
258 : WrappedPoolBase<Variant, typename Variant::Pool>(pool) { }
262 * Metafunction that returns a null pointer when
263 * its template argument is NoPool.
265 template <typename Variant, typename Pool>
266 struct ReturnPool {
267 static PoolPtr apply(typename Variant::Position& position, int player) {
268 return PoolPtr(
269 new WrappedPool<Variant>(position.pool(player)));
273 template <typename Variant>
274 struct ReturnPool<Variant, NoPool> {
275 static PoolPtr apply(typename Variant::Position&, int) {
276 return PoolPtr();
281 * Metafunction to assign pools of a position to another.
283 template <typename Variant, typename Pool>
284 struct AssignPool {
285 static void apply(typename Variant::Position& pos1, const typename Variant::Position& pos2) {
286 pos1.setRawPool(pos2.rawPool());
290 template <typename Variant>
291 struct AssignPool<Variant, NoPool> {
292 static void apply(typename Variant::Position&, const typename Variant::Position&) { }
295 template <typename Variant>
296 class WrappedPosition : public AbstractPosition {
297 typedef typename Variant::Position Position;
298 typedef typename Variant::Move Move;
299 typedef typename Variant::Piece Piece;
300 typedef typename Variant::Pool Pool;
302 Position m_pos;
303 public:
304 const Position& inner() const { return m_pos; }
305 Position& inner() { return m_pos; }
307 WrappedPosition(const Position& pos)
308 : m_pos(pos) { }
310 virtual Point size() const {
311 return inner().size();
314 virtual QStringList borderCoords() const {
315 return inner().borderCoords();
318 virtual void setup() {
319 m_pos.setup();
322 virtual PiecePtr get(const Point& p) const {
323 Piece piece = m_pos.get(p);
324 if (piece)
325 return PiecePtr(new WrappedPiece<Variant>(piece));
326 else
327 return PiecePtr();
330 virtual void set(const Point& p, const PiecePtr& _piece) {
331 if (!_piece) {
332 m_pos.set(p, Piece());
334 else {
335 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
337 if (piece)
338 m_pos.set(p, piece->inner() );
339 else
340 MISMATCH(*_piece.get(),WrappedPiece<Variant>);
344 virtual PoolPtr pool(int player) {
345 return ReturnPool<Variant, Pool>::apply(m_pos, player);
348 virtual void copyPoolFrom(const PositionPtr& _pos) {
349 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
350 if (pos) {
351 AssignPool<Variant, Pool>::apply(m_pos, pos->inner());
353 else {
354 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
358 virtual InteractionType movable(const TurnTest& test, const Point& p) const {
359 return m_pos.movable(test, p);
362 virtual InteractionType droppable(const TurnTest& test, int p) const {
363 return m_pos.droppable(test, p);
366 virtual int turn() const {
367 return static_cast<int>(m_pos.turn());
370 virtual void setTurn(int turn) {
371 m_pos.setTurn(static_cast<typename Piece::Color>(turn));
374 virtual int previousTurn() const {
375 return static_cast<int>(m_pos.previousTurn());
378 virtual void switchTurn() {
379 m_pos.switchTurn();
382 virtual bool testMove(const MovePtr& _move) const {
383 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
385 if (move)
386 return m_pos.testMove( const_cast<Move&>(move->inner()) );
387 else {
388 MISMATCH(*_move.get(),WrappedMove<Variant>);
389 return false;
393 virtual void move(const MovePtr& _move) {
394 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
396 if (move)
397 m_pos.move(move->inner());
398 else
399 MISMATCH(*_move.get(),WrappedMove<Variant>);
402 virtual PositionPtr clone() const {
403 return PositionPtr(new WrappedPosition<Variant>(m_pos));
406 virtual void copyFrom(const PositionPtr& _p) {
407 WrappedPosition* p = dynamic_cast<WrappedPosition*>(_p.get());
409 if (p)
410 m_pos = p->inner();
411 else
412 MISMATCH(*_p.get(),WrappedPosition);
415 virtual bool equals(const PositionPtr& _other) const {
416 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
418 if(other)
419 return m_pos == other->inner();
420 else {
421 MISMATCH(*_other.get(),WrappedPosition<Variant>);
422 return false;
426 virtual MovePtr getMove(const AlgebraicNotation& san) const {
427 bool ok;
428 Move res = m_pos.getMove(san, ok);
429 if (ok)
430 return MovePtr(new WrappedMove<Variant>(res));
431 else
432 return MovePtr();
435 virtual MovePtr getMove(const QString& san) const {
436 AlgebraicNotation move(san, size().y); //FIXME
437 if(!move.valid())
438 return MovePtr();
439 return getMove(move);
442 virtual QString state() const {
443 return ""; // TODO
446 virtual QString fen(int halfmove, int fullmove) const {
447 return m_pos.fen(halfmove, fullmove);
450 virtual PiecePtr moveHint(const MovePtr& _move) const {
451 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
453 if (move) {
454 if(boost::shared_ptr<Piece> hint = m_pos.moveHint(move->inner()))
455 return PiecePtr(
456 new WrappedPiece<Variant>(Piece(*hint)));
458 else {
459 MISMATCH(*_move.get(),WrappedMove<Variant>);
462 return PiecePtr();
465 virtual QString variant() const {
466 return Variant::m_name;
469 virtual void dump() const {
470 m_pos.dump();
475 template <typename Variant>
476 class WrappedAnimator : public AbstractAnimator {
477 typedef typename Variant::Position Position;
478 typedef typename Variant::Animator Animator;
479 typedef typename Variant::Move Move;
481 Animator m_animator;
482 public:
483 const Animator& inner() const { return m_animator; }
485 WrappedAnimator(const Animator& animator)
486 : m_animator(animator) { }
488 virtual AnimationPtr warp(const PositionPtr& _pos) {
489 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
490 if (pos)
491 return m_animator.warp(pos->inner());
492 else {
493 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
494 return AnimationPtr();
498 virtual AnimationPtr forward(const PositionPtr& _pos, const MovePtr& _move) {
499 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
500 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
502 if (move && pos)
503 return m_animator.forward(pos->inner(), move->inner());
504 else {
505 if (!move)
506 MISMATCH(*_move.get(), WrappedMove<Variant>);
507 if (!pos)
508 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
509 return AnimationPtr();
513 virtual AnimationPtr back(const PositionPtr& _pos, const MovePtr& _move) {
514 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
515 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
517 if (move && pos)
518 return m_animator.back(pos->inner(), move->inner());
519 else {
520 if (!move)
521 MISMATCH(*_move.get(), WrappedMove<Variant>);
522 if (!pos)
523 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
524 return AnimationPtr();
529 #include "graphicalapi_unwrapped.h"
531 template <typename Variant>
532 class WrappedVariantInfo : public VariantInfo {
533 public:
534 typedef typename Variant::Animator Animator;
535 typedef typename Variant::Position Position;
536 typedef typename Variant::Piece Piece;
537 typedef typename Variant::Move Move;
538 typedef typename Variant::Pool Pool;
540 virtual PositionPtr createPosition() {
541 return PositionPtr(
542 new WrappedPosition<Variant>(Position()));
545 virtual PositionPtr createCustomPosition(const OptList& l) {
546 return PositionPtr(
547 new WrappedPosition<Variant>(Position(l)));
550 virtual PositionPtr createPositionFromFEN(const QString& fen) {
551 std::auto_ptr<WrappedPosition<Variant> > res(
552 new WrappedPosition<Variant>(Position()));
553 bool ok;
554 res->inner().fromFEN(fen, ok);
555 if (ok) {
556 return PositionPtr(res.release());
558 else return PositionPtr();
560 virtual void forallPieces(class PieceFunction& f) {
561 Variant::forallPieces(f);
563 virtual int moveListLayout() const {
564 return Variant::moveListLayout();
566 virtual AnimatorPtr createAnimator(GraphicalAPI* graphical_api) {
567 return AnimatorPtr(
568 new WrappedAnimator<Variant>(
569 Animator(typename UnwrappedGraphicalAPI<Variant>::Ptr(
570 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
572 virtual MovePtr createNormalMove(const NormalUserMove& move) {
573 return MovePtr(new WrappedMove<Variant>(
574 MoveFactory<Variant>::createNormalMove(move)));
576 virtual MovePtr createDropMove(const DropUserMove& move) {
577 return MovePtr(new WrappedMove<Variant>(
578 MoveFactory<Variant>::createDropMove(move)));
581 virtual MovePtr getVerboseMove(int turn, const VerboseNotation& m) const {
582 Move res = Position::getVerboseMove(static_cast<typename Piece::Color>(turn), m);
583 return MovePtr(new WrappedMove<Variant>(res));
586 virtual int type(const QString& str) {
587 return Piece::getType(str);
589 virtual QString typeSymbol(int type) {
590 return Piece::typeSymbol(static_cast<typename Piece::Type>(type));
592 virtual bool simpleMoves() {
593 return Variant::m_simple_moves;
595 virtual QString name() const {
596 return Variant::m_name;
598 virtual QString themeProxy() const {
599 return Variant::m_theme_proxy;
601 virtual OptList positionOptions() const {
602 return Variant::positionOptions();
604 virtual ICSAPIPtr icsAPI() const {
605 return ICSAPIPtr(ReturnICSAPI<Variant, Variant::hasICS>::apply());
609 #endif // HIGHLEVEL_H