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.
18 #include "movefactory.h"
19 #include "piecefactory.h"
20 #include "moveserializer.h"
22 #include "algebraicnotation.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 kboard 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 { }
81 template <typename Variant
>
82 class WrappedPiece
: public AbstractPiece
{
83 typedef typename
Variant::Piece Piece
;
87 const Piece
& inner() const { return m_piece
; }
89 WrappedPiece(const Piece
& piece
)
92 virtual bool equals(AbstractPiece::Ptr _other
) const {
93 if (!_other
) return false;
94 WrappedPiece
<Variant
>* other
= dynamic_cast<WrappedPiece
<Variant
>*>(_other
.get());
97 return m_piece
== other
->inner();
99 MISMATCH(*_other
.get(),WrappedPiece
<Variant
>);
104 virtual QString
name() const {
105 return m_piece
.name();
108 virtual QString
typeSymbol() const {
109 return Piece::typeSymbol(m_piece
.type());
112 virtual AbstractPiece::Ptr
clone() const {
113 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(m_piece
));
118 template <typename Variant
>
119 class WrappedMove
: public AbstractMove
{
120 typedef typename
Variant::Move Move
;
121 typedef typename
Variant::Position Position
;
125 const Move
& inner() const { return m_move
; }
127 WrappedMove(const Move
& move
)
130 virtual QString
SAN(AbstractPosition::Ptr _pos
) const {
131 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
134 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
135 return serializer
.SAN();
138 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
143 virtual DecoratedMove
toDecoratedMove(boost::shared_ptr
<AbstractPosition
> _pos
) const {
144 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
147 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
148 return serializer
.toDecoratedMove();
151 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
152 return DecoratedMove();
156 virtual QString
toString(AbstractPosition::Ptr _pos
) const {
157 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
160 return m_move
.toString(pos
->inner().size().y
);
162 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
167 virtual NormalUserMove
toUserMove() const {
168 return MoveFactory
<Variant
>::toNormal(m_move
);
171 virtual bool equals(AbstractMove::Ptr _other
) const {
172 WrappedMove
<Variant
>* other
= dynamic_cast<WrappedMove
<Variant
>*>(_other
.get());
175 return m_move
== other
->inner();
177 MISMATCH(*_other
.get(),WrappedMove
<Variant
>);
183 template <typename Variant
, typename Pool
>
184 class WrappedPoolBase
: public AbstractPool
{
185 typedef typename
Variant::Piece Piece
;
189 WrappedPoolBase(Pool pool
)
193 return m_pool
.size();
196 virtual int insert(int pref_index
, AbstractPiece::Ptr _piece
) {
198 return m_pool
.insert(pref_index
, Piece());
201 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
204 return m_pool
.insert(pref_index
, Piece(piece
->inner()) );
206 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
212 virtual AbstractPiece::Ptr
get(int index
) {
213 Piece piece
= m_pool
.get(index
);
215 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
217 return AbstractPiece::Ptr();
220 virtual AbstractPiece::Ptr
take(int index
) {
221 Piece piece
= m_pool
.take(index
);
223 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
225 return AbstractPiece::Ptr();
229 // simple special case for NoPool
230 template <typename Variant
>
231 class WrappedPoolBase
<Variant
, NoPool
> : public AbstractPool
{
233 WrappedPoolBase(NoPool
) { }
236 template <typename Variant
>
237 class WrappedPool
: public WrappedPoolBase
<Variant
, typename
Variant::Pool
> {
239 WrappedPool(typename
Variant::Pool pool
)
240 : WrappedPoolBase
<Variant
, typename
Variant::Pool
>(pool
) { }
244 * Metafunction that returns a null pointer when
245 * its template argument is NoPool.
247 template <typename Variant
, typename Pool
>
249 static AbstractPool::Ptr
apply(typename
Variant::Position
& position
, int player
) {
250 return AbstractPool::Ptr(
251 new WrappedPool
<Variant
>(position
.pool(player
)));
255 template <typename Variant
>
256 struct ReturnPool
<Variant
, NoPool
> {
257 static AbstractPool::Ptr
apply(typename
Variant::Position
&, int) {
258 return AbstractPool::Ptr();
262 template <typename Variant
>
263 class WrappedPosition
: public AbstractPosition
{
264 typedef typename
Variant::Position Position
;
265 typedef typename
Variant::Move Move
;
266 typedef typename
Variant::Piece Piece
;
267 typedef typename
Variant::Pool Pool
;
271 const Position
& inner() const { return m_pos
; }
272 Position
& inner() { return m_pos
; }
274 WrappedPosition(const Position
& pos
)
277 virtual Point
size() const {
278 return inner().size();
281 virtual QStringList
borderCoords() const {
282 return inner().borderCoords();
285 virtual void setup() {
289 virtual AbstractPiece::Ptr
get(const Point
& p
) const {
290 Piece piece
= m_pos
.get(p
);
292 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
294 return AbstractPiece::Ptr();
297 virtual void set(const Point
& p
, AbstractPiece::Ptr _piece
) {
299 m_pos
.set(p
, Piece());
302 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
305 m_pos
.set(p
, piece
->inner() );
307 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
311 virtual AbstractPool::Ptr
pool(int player
) {
312 return ReturnPool
<Variant
, Pool
>::apply(m_pos
, player
);
315 virtual InteractionType
movable(const Point
& p
) const {
316 return m_pos
.movable(p
);
319 virtual InteractionType
droppable(int p
) const {
320 return m_pos
.droppable(p
);
323 virtual int turn() const {
324 return static_cast<int>(m_pos
.turn());
327 virtual void setTurn(int turn
) {
328 m_pos
.setTurn(static_cast<typename
Piece::Color
>(turn
));
331 virtual int previousTurn() const {
332 return static_cast<int>(m_pos
.previousTurn());
335 virtual void switchTurn() {
339 virtual bool testMove(AbstractMove::Ptr _move
) const {
340 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
343 return m_pos
.testMove( const_cast<Move
&>(move
->inner()) );
345 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
350 virtual void move(AbstractMove::Ptr _move
) {
351 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
354 m_pos
.move(move
->inner());
356 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
359 virtual AbstractPosition::Ptr
clone() const {
360 return AbstractPosition::Ptr(new WrappedPosition
<Variant
>(m_pos
));
363 virtual void copyFrom(const AbstractPosition::Ptr
& _p
) {
364 WrappedPosition
* p
= dynamic_cast<WrappedPosition
*>(_p
.get());
369 MISMATCH(*_p
.get(),WrappedPosition
);
372 virtual bool equals(AbstractPosition::Ptr _other
) const {
373 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
376 return m_pos
== other
->inner();
378 MISMATCH(*_other
.get(),WrappedPosition
<Variant
>);
383 virtual AbstractMove::Ptr
getMove(const AlgebraicNotation
& san
) const {
385 Move res
= m_pos
.getMove(san
, ok
);
387 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
389 return AbstractMove::Ptr();
392 virtual AbstractMove::Ptr
getMove(const QString
& san
) const {
393 AlgebraicNotation
move(san
, size().y
); //FIXME
395 return AbstractMove::Ptr();
396 return getMove(move
);
399 virtual QString
state() const {
403 virtual QString
fen(int halfmove
, int fullmove
) const {
404 return m_pos
.fen(halfmove
, fullmove
);
407 virtual AbstractPiece::Ptr
moveHint(AbstractMove::Ptr _move
) const {
408 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
411 if(boost::shared_ptr
<Piece
> hint
= m_pos
.moveHint(move
->inner()))
412 return AbstractPiece::Ptr(
413 new WrappedPiece
<Variant
>(Piece(*hint
)));
416 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
419 return AbstractPiece::Ptr();
422 virtual QString
variant() const {
423 return Variant::m_name
;
426 virtual void dump() const {
432 template <typename Variant
>
433 class WrappedAnimator
: public AbstractAnimator
{
434 typedef typename
Variant::Position Position
;
435 typedef typename
Variant::Animator Animator
;
436 typedef typename
Variant::Move Move
;
440 const Animator
& inner() const { return m_animator
; }
442 WrappedAnimator(const Animator
& animator
)
443 : m_animator(animator
) { }
445 virtual AnimationPtr
warp(AbstractPosition::Ptr _pos
) {
446 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
448 return m_animator
.warp(pos
->inner());
450 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
451 return AnimationPtr();
455 virtual AnimationPtr
forward(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
456 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
457 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
460 return m_animator
.forward(pos
->inner(), move
->inner());
463 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
465 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
466 return AnimationPtr();
470 virtual AnimationPtr
back(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
471 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
472 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
475 return m_animator
.back(pos
->inner(), move
->inner());
478 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
480 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
481 return AnimationPtr();
486 #include "graphicalapi_unwrapped.h"
488 template <typename Variant
>
489 class WrappedVariantInfo
: public VariantInfo
{
491 typedef typename
Variant::Animator Animator
;
492 typedef typename
Variant::Position Position
;
493 typedef typename
Variant::Piece Piece
;
494 typedef typename
Variant::Move Move
;
495 typedef typename
Variant::Pool Pool
;
497 virtual AbstractPosition::Ptr
createPosition() {
498 return AbstractPosition::Ptr(
499 new WrappedPosition
<Variant
>(Position()));
502 virtual AbstractPosition::Ptr
createCustomPosition(const OptList
& l
) {
503 return AbstractPosition::Ptr(
504 new WrappedPosition
<Variant
>(Position(l
)));
507 virtual AbstractPosition::Ptr
createPositionFromFEN(const QString
& fen
) {
508 std::auto_ptr
<WrappedPosition
<Variant
> > res(
509 new WrappedPosition
<Variant
>(Position()));
511 res
->inner().fromFEN(fen
, ok
);
513 return AbstractPosition::Ptr(res
.release());
515 else return AbstractPosition::Ptr();
518 virtual AbstractPosition::Ptr
createChessboard(int turn
,
519 bool wk
, bool wq
, bool bk
, bool bq
,
521 return AbstractPosition::Ptr(
522 new WrappedPosition
<Variant
>(Position(
523 static_cast<typename
Piece::Color
>(turn
),
524 wk
, wq
, bk
, bq
, ep
)));
526 virtual AbstractPiece::Ptr
createPiece(int color
, int type
) {
527 return AbstractPiece::Ptr(
528 new WrappedPiece
<Variant
>(Piece(
529 static_cast<typename
Piece::Color
>(color
),
530 static_cast<typename
Piece::Type
>(type
))));
532 virtual void forallPieces(class PieceFunction
& f
) {
533 Variant::forallPieces(f
);
535 virtual int moveListLayout() const {
536 return Variant::moveListLayout();
538 virtual AbstractAnimator::Ptr
createAnimator(GraphicalAPI
* graphical_api
) {
539 return AbstractAnimator::Ptr(
540 new WrappedAnimator
<Variant
>(
541 Animator(typename UnwrappedGraphicalAPI
<Variant
>::Ptr(
542 new UnwrappedGraphicalAPI
<Variant
>(graphical_api
)))));
544 virtual AbstractMove::Ptr
createNormalMove(const NormalUserMove
& move
) {
545 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
546 MoveFactory
<Variant
>::createNormalMove(move
)));
548 virtual AbstractMove::Ptr
createDropMove(const DropUserMove
& move
) {
549 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
550 MoveFactory
<Variant
>::createDropMove(move
)));
553 virtual AbstractMove::Ptr
getVerboseMove(int turn
, const VerboseNotation
& m
) const {
554 Move res
= Position::getVerboseMove(static_cast<typename
Piece::Color
>(turn
), m
);
555 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
558 virtual AbstractPiece::Ptr
createPiece(const QString
& description
) {
559 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(
560 PieceFactory
<Variant
>::createPiece(description
)));
563 virtual int type(const QString
& str
) {
564 return Piece::getType(str
);
566 virtual QString
typeSymbol(int type
) {
567 return Piece::typeSymbol(static_cast<typename
Piece::Type
>(type
));
569 virtual bool simpleMoves() {
570 return Variant::m_simple_moves
;
572 virtual QString
name() const {
573 return Variant::m_name
;
575 virtual QString
themeProxy() const {
576 return Variant::m_theme_proxy
;
578 virtual OptList
positionOptions() const {
579 return Variant::positionOptions();
583 #endif // HIGHLEVEL_H