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"
23 #include "algebraicnotation.h"
25 template <typename V
> class WrappedPiece
;
26 template <typename V
> class WrappedMove
;
27 template <typename V
> class WrappedPosition
;
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);
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
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>.
68 #define __FUNC__ __PRETTY_FUNCTION__
70 #define __FUNC__ __FUNCTION__
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 { }
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
;
106 const Piece
& inner() const { return m_piece
; }
108 WrappedPiece(const 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());
116 return m_piece
== other
->inner();
118 MISMATCH(*_other
.get(),WrappedPiece
<Variant
>);
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
;
144 const Move
& inner() const { return m_move
; }
146 WrappedMove(const Move
& move
)
149 virtual QString
SAN(const PositionPtr
& _pos
) const {
150 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
153 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
154 return serializer
.SAN();
157 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
162 virtual DecoratedMove
toDecoratedMove(const PositionPtr
& _pos
) const {
163 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
166 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
167 return serializer
.toDecoratedMove();
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());
179 return m_move
.toString(pos
->inner().size().y
);
181 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
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());
194 return m_move
== other
->inner();
196 MISMATCH(*_other
.get(),WrappedMove
<Variant
>);
202 template <typename Variant
, typename Pool
>
203 class WrappedPoolBase
: public AbstractPool
{
204 typedef typename
Variant::Piece Piece
;
208 WrappedPoolBase(Pool pool
)
212 return m_pool
.size();
215 virtual int insert(int pref_index
, const PiecePtr
& _piece
) {
217 return m_pool
.insert(pref_index
, Piece());
220 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
223 return m_pool
.insert(pref_index
, Piece(piece
->inner()) );
225 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
231 virtual PiecePtr
get(int index
) {
232 Piece piece
= m_pool
.get(index
);
234 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
239 virtual PiecePtr
take(int index
) {
240 Piece piece
= m_pool
.take(index
);
242 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
248 // simple special case for NoPool
249 template <typename Variant
>
250 class WrappedPoolBase
<Variant
, NoPool
> : public AbstractPool
{
252 WrappedPoolBase(NoPool
) { }
255 template <typename Variant
>
256 class WrappedPool
: public WrappedPoolBase
<Variant
, typename
Variant::Pool
> {
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
>
268 static PoolPtr
apply(typename
Variant::Position
& position
, int player
) {
270 new WrappedPool
<Variant
>(position
.pool(player
)));
274 template <typename Variant
>
275 struct ReturnPool
<Variant
, NoPool
> {
276 static PoolPtr
apply(typename
Variant::Position
&, int) {
282 * Metafunction to assign pools of a position to another.
284 template <typename Variant
, typename Pool
>
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
;
305 const Position
& inner() const { return m_pos
; }
306 Position
& inner() { return m_pos
; }
308 WrappedPosition(const Position
& pos
)
311 virtual Point
size() const {
312 return inner().size();
315 virtual QStringList
borderCoords() const {
316 return inner().borderCoords();
319 virtual void setup() {
323 virtual PiecePtr
get(const Point
& p
) const {
324 Piece piece
= m_pos
.get(p
);
326 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
331 virtual void set(const Point
& p
, const PiecePtr
& _piece
) {
333 m_pos
.set(p
, Piece());
336 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
339 m_pos
.set(p
, piece
->inner() );
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());
352 AssignPool
<Variant
, Pool
>::apply(m_pos
, pos
->inner());
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() {
383 virtual bool testMove(const MovePtr
& _move
) const {
384 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
387 return m_pos
.testMove( const_cast<Move
&>(move
->inner()) );
389 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
394 virtual void move(const MovePtr
& _move
) {
395 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
398 m_pos
.move(move
->inner());
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());
413 MISMATCH(*_p
.get(),WrappedPosition
);
416 virtual bool equals(const PositionPtr
& _other
) const {
417 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
420 return m_pos
== other
->inner();
422 MISMATCH(*_other
.get(),WrappedPosition
<Variant
>);
427 virtual MovePtr
getMove(const AlgebraicNotation
& san
) const {
429 Move res
= m_pos
.getMove(san
, ok
);
431 return MovePtr(new WrappedMove
<Variant
>(res
));
436 virtual MovePtr
getMove(const QString
& san
) const {
437 AlgebraicNotation
move(san
, size().y
); //FIXME
440 return getMove(move
);
443 virtual QString
state() const {
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());
455 if(boost::shared_ptr
<Piece
> hint
= m_pos
.moveHint(move
->inner()))
457 new WrappedPiece
<Variant
>(Piece(*hint
)));
460 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
466 virtual QString
variant() const {
467 return Variant::m_name
;
470 virtual void dump() const {
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
;
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());
492 return m_animator
.warp(pos
->inner());
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());
504 return m_animator
.forward(pos
->inner(), move
->inner());
507 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
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());
519 return m_animator
.back(pos
->inner(), move
->inner());
522 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
524 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
525 return AnimationPtr();
530 #include "graphicalapi_unwrapped.h"
532 template <typename Variant
>
533 class WrappedVariantInfo
: public VariantInfo
{
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() {
543 new WrappedPosition
<Variant
>(Position()));
546 virtual PositionPtr
createCustomPosition(const OptList
& l
) {
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()));
555 res
->inner().fromFEN(fen
, 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
) {
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