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.
19 #include "movefactory.h"
20 #include "piecefactory.h"
21 #include "moveserializer.h"
24 template <typename V
> class WrappedPiece
;
25 template <typename V
> class WrappedMove
;
26 template <typename V
> class WrappedPosition
;
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);
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
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>.
67 #define __FUNC__ __PRETTY_FUNCTION__
69 #define __FUNC__ __FUNCTION__
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 { }
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
;
105 const Piece
& inner() const { return m_piece
; }
107 WrappedPiece(const 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());
115 return m_piece
== other
->inner();
117 MISMATCH(*_other
.get(),WrappedPiece
<Variant
>);
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
;
143 const Move
& inner() const { return m_move
; }
145 WrappedMove(const Move
& move
)
148 virtual QString
SAN(const PositionPtr
& _pos
) const {
149 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
152 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
153 return serializer
.SAN();
156 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
161 virtual DecoratedMove
toDecoratedMove(const PositionPtr
& _pos
) const {
162 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
165 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
166 return serializer
.toDecoratedMove();
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());
178 return m_move
.toString(pos
->inner().size().x
, pos
->inner().size().y
);
180 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
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());
193 return m_move
== other
->inner();
195 MISMATCH(*_other
.get(),WrappedMove
<Variant
>);
201 template <typename Variant
, typename Pool
>
202 class WrappedPoolBase
: public AbstractPool
{
203 typedef typename
Variant::Piece Piece
;
207 WrappedPoolBase(Pool pool
)
211 return m_pool
.size();
214 virtual int insert(int pref_index
, const PiecePtr
& _piece
) {
216 return m_pool
.insert(pref_index
, Piece());
219 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
222 return m_pool
.insert(pref_index
, Piece(piece
->inner()) );
224 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
230 virtual PiecePtr
get(int index
) {
231 Piece piece
= m_pool
.get(index
);
233 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
238 virtual PiecePtr
take(int index
) {
239 Piece piece
= m_pool
.take(index
);
241 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
247 // simple special case for NoPool
248 template <typename Variant
>
249 class WrappedPoolBase
<Variant
, NoPool
> : public AbstractPool
{
251 WrappedPoolBase(NoPool
) { }
254 template <typename Variant
>
255 class WrappedPool
: public WrappedPoolBase
<Variant
, typename
Variant::Pool
> {
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
>
267 static PoolPtr
apply(typename
Variant::Position
& position
, int player
) {
269 new WrappedPool
<Variant
>(position
.pool(player
)));
273 template <typename Variant
>
274 struct ReturnPool
<Variant
, NoPool
> {
275 static PoolPtr
apply(typename
Variant::Position
&, int) {
281 * Metafunction to assign pools of a position to another.
283 template <typename Variant
, typename Pool
>
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
;
304 const Position
& inner() const { return m_pos
; }
305 Position
& inner() { return m_pos
; }
307 WrappedPosition(const Position
& pos
)
310 virtual Point
size() const {
311 return inner().size();
314 virtual QStringList
borderCoords() const {
315 return inner().borderCoords();
318 virtual void setup() {
322 virtual PiecePtr
get(const Point
& p
) const {
323 Piece piece
= m_pos
.get(p
);
325 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
330 virtual void set(const Point
& p
, const PiecePtr
& _piece
) {
332 m_pos
.set(p
, Piece());
335 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
338 m_pos
.set(p
, piece
->inner() );
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());
351 AssignPool
<Variant
, Pool
>::apply(m_pos
, pos
->inner());
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() {
382 virtual bool testMove(const MovePtr
& _move
) const {
383 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
386 return m_pos
.testMove( const_cast<Move
&>(move
->inner()) );
388 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
393 virtual void move(const MovePtr
& _move
) {
394 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
397 m_pos
.move(move
->inner());
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());
412 MISMATCH(*_p
.get(),WrappedPosition
);
415 virtual bool equals(const PositionPtr
& _other
) const {
416 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
419 return m_pos
== other
->inner();
421 MISMATCH(*_other
.get(),WrappedPosition
<Variant
>);
426 virtual MovePtr
getMove(const AlgebraicNotation
& san
) const {
428 Move res
= m_pos
.getMove(san
, ok
);
430 return MovePtr(new WrappedMove
<Variant
>(res
));
435 virtual MovePtr
getMove(const QString
& san
) const {
436 AlgebraicNotation
move(san
, size().y
); //FIXME
439 return getMove(move
);
442 virtual QString
state() const {
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());
454 if(boost::shared_ptr
<Piece
> hint
= m_pos
.moveHint(move
->inner()))
456 new WrappedPiece
<Variant
>(Piece(*hint
)));
459 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
465 virtual QString
variant() const {
466 return Variant::m_name
;
469 virtual void dump() const {
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
;
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());
491 return m_animator
.warp(pos
->inner());
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());
503 return m_animator
.forward(pos
->inner(), move
->inner());
506 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
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());
518 return m_animator
.back(pos
->inner(), move
->inner());
521 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
523 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
524 return AnimationPtr();
529 #include "graphicalapi_unwrapped.h"
531 template <typename Variant
>
532 class WrappedVariantInfo
: public VariantInfo
{
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() {
542 new WrappedPosition
<Variant
>(Position()));
545 virtual PositionPtr
createCustomPosition(const OptList
& l
) {
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()));
554 res
->inner().fromFEN(fen
, 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
) {
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