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 "moveserializer.h"
20 #include "algebraicnotation.h"
22 template <typename V
> class WrappedPiece
;
23 template <typename V
> class WrappedMove
;
24 template <typename V
> class WrappedPosition
;
27 * @brief Wrap an high level position definition
28 * in a low level AbstractPosition implementation.
30 * Use this class to wrap an high level position definition
31 * in an AbstractPosition implementation suitable for communicating
32 * with the kboard infrastructure.
33 * Variant should be a structure with inner types Position, Move and Piece.
35 * @section Requirements on Position
37 * Position should define the following functions:
38 * - static Point size();
39 * - Piece* operator[](const Point& p) const;
40 * - Piece::Color turn() const;
41 * - void switchTurn();
42 * - bool testMove(Move& m) const;
43 * - void move(const Move& m);
46 * @section Requirements on Piece
48 * Piece should have inner types Color and Type, each
49 * convertible to int via static_cast.
50 * Furthermore, it should implement the following
52 * - Piece::Type type() const;
53 * - Piece::Color color() const;
54 * - QString name() const;
55 * - static QString typeSymbol(Piece::Type type);
57 * @section Move serialization
59 * To customize move serialization, one should specialize
60 * the template MoveSerializer<Pos>.
65 #define __FUNC__ __PRETTY_FUNCTION__
67 #define __FUNC__ __FUNCTION__
70 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
71 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
72 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
73 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
75 #define TYPECHECK(x,y) if (typeid(x) != typeid(y)) MISMATCH(x,y); else { }
79 template <typename Variant
>
80 class WrappedPiece
: public AbstractPiece
{
81 typedef typename
Variant::Piece Piece
;
85 const Piece
& inner() const { return m_piece
; }
87 WrappedPiece(const Piece
& piece
)
90 virtual bool equals(AbstractPiece::Ptr _other
) const {
91 if (!_other
) return false;
92 WrappedPiece
<Variant
>* other
= dynamic_cast<WrappedPiece
<Variant
>*>(_other
.get());
95 return m_piece
== other
->inner();
97 MISMATCH(*_other
.get(),WrappedPiece
<Variant
>);
102 virtual QString
name() const {
103 return m_piece
.name();
106 virtual QString
typeSymbol() const {
107 return Piece::typeSymbol(m_piece
.type());
110 virtual AbstractPiece::Ptr
clone() const {
111 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(m_piece
));
116 template <typename Variant
>
117 class WrappedMove
: public AbstractMove
{
118 typedef typename
Variant::Move Move
;
119 typedef typename
Variant::Position Position
;
123 const Move
& inner() const { return m_move
; }
125 WrappedMove(const Move
& move
)
128 virtual QString
SAN(AbstractPosition::Ptr _pos
) const {
129 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
132 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
133 return serializer
.SAN();
136 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
141 virtual DecoratedMove
toDecoratedMove(boost::shared_ptr
<AbstractPosition
> _pos
) const {
142 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
145 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
146 return serializer
.toDecoratedMove();
149 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
150 return DecoratedMove();
154 virtual QString
toString(AbstractPosition::Ptr _pos
) const {
155 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
158 return m_move
.toString(pos
->inner().size().y
);
160 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
165 virtual NormalUserMove
toUserMove() const {
166 return MoveFactory
<Variant
>::toNormal(m_move
);
169 virtual bool equals(AbstractMove::Ptr _other
) const {
170 WrappedMove
<Variant
>* other
= dynamic_cast<WrappedMove
<Variant
>*>(_other
.get());
173 return m_move
== other
->inner();
175 MISMATCH(*_other
.get(),WrappedMove
<Variant
>);
182 template <typename Variant
>
183 class WrappedPool
: public AbstractPool
{
184 typedef typename
Variant::Pool Pool
;
185 typedef typename
Variant::Piece Piece
;
189 WrappedPool(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();
230 template <typename Variant
>
231 class WrappedPosition
: public AbstractPosition
{
232 typedef typename
Variant::Position Position
;
233 typedef typename
Variant::Move Move
;
234 typedef typename
Variant::Piece Piece
;
235 typedef typename
Variant::Pool Pool
;
239 const Position
& inner() const { return m_pos
; }
240 Position
& inner() { return m_pos
; }
242 WrappedPosition(const Position
& pos
)
245 virtual Point
size() const {
246 return inner().size();
249 virtual QStringList
borderCoords() const {
250 return inner().borderCoords();
253 virtual void setup() {
257 virtual AbstractPiece::Ptr
get(const Point
& p
) const {
258 Piece piece
= m_pos
.get(p
);
260 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
262 return AbstractPiece::Ptr();
265 virtual void set(const Point
& p
, AbstractPiece::Ptr _piece
) {
267 m_pos
.set(p
, Piece());
270 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
273 m_pos
.set(p
, piece
->inner() );
275 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
279 virtual AbstractPool::Ptr
pool(int player
) {
280 return AbstractPool::Ptr(new WrappedPool
<Variant
>(m_pos
.pool(player
)));
283 virtual InteractionType
movable(const Point
& p
) const {
284 return m_pos
.movable(p
);
287 virtual InteractionType
droppable(int p
) const {
288 return m_pos
.droppable(p
);
291 virtual int turn() const {
292 return static_cast<int>(m_pos
.turn());
295 virtual void setTurn(int turn
) {
296 m_pos
.setTurn(static_cast<typename
Piece::Color
>(turn
));
299 virtual int previousTurn() const {
300 return static_cast<int>(m_pos
.previousTurn());
303 virtual void switchTurn() {
307 virtual bool testMove(AbstractMove::Ptr _move
) const {
308 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
311 return m_pos
.testMove( const_cast<Move
&>(move
->inner()) );
313 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
318 virtual void move(AbstractMove::Ptr _move
) {
319 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
322 m_pos
.move(move
->inner());
324 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
327 virtual AbstractPosition::Ptr
clone() const {
328 return AbstractPosition::Ptr(new WrappedPosition
<Variant
>(m_pos
));
331 virtual void copyFrom(const AbstractPosition::Ptr
& _p
) {
332 WrappedPosition
* p
= dynamic_cast<WrappedPosition
*>(_p
.get());
337 MISMATCH(*_p
.get(),WrappedPosition
);
340 virtual bool equals(AbstractPosition::Ptr _other
) const {
341 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
344 return m_pos
== other
->inner();
346 MISMATCH(*_other
.get(),WrappedPosition
<Variant
>);
351 virtual AbstractMove::Ptr
getMove(const AlgebraicNotation
& san
) const {
353 Move res
= m_pos
.getMove(san
, ok
);
355 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
357 return AbstractMove::Ptr();
360 virtual AbstractMove::Ptr
getMove(const QString
& san
) const {
361 AlgebraicNotation
move(san
, size().y
); //FIXME
363 return AbstractMove::Ptr();
364 return getMove(move
);
367 virtual QString
state() const {
371 virtual QString
fen(int halfmove
, int fullmove
) const {
372 return m_pos
.fen(halfmove
, fullmove
);
375 virtual AbstractPiece::Ptr
moveHint(AbstractMove::Ptr _move
) const {
376 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
379 if(boost::shared_ptr
<Piece
> hint
= m_pos
.moveHint(move
->inner()))
380 return AbstractPiece::Ptr(
381 new WrappedPiece
<Variant
>(Piece(*hint
)));
384 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
387 return AbstractPiece::Ptr();
390 virtual QString
variant() const {
391 return Variant::m_name
;
394 virtual void dump() const {
400 template <typename Variant
>
401 class WrappedAnimator
: public AbstractAnimator
{
402 typedef typename
Variant::Position Position
;
403 typedef typename
Variant::Animator Animator
;
404 typedef typename
Variant::Move Move
;
408 const Animator
& inner() const { return m_animator
; }
410 WrappedAnimator(const Animator
& animator
)
411 : m_animator(animator
) { }
413 virtual AnimationPtr
warp(AbstractPosition::Ptr _pos
) {
414 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
416 return m_animator
.warp(pos
->inner());
418 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
419 return AnimationPtr();
423 virtual AnimationPtr
forward(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
424 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
425 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
428 return m_animator
.forward(pos
->inner(), move
->inner());
431 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
433 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
434 return AnimationPtr();
438 virtual AnimationPtr
back(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
439 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
440 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
443 return m_animator
.back(pos
->inner(), move
->inner());
446 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
448 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
449 return AnimationPtr();
454 #include "graphicalapi_unwrapped.h"
456 template <typename Variant
>
457 class WrappedVariantInfo
: public VariantInfo
{
459 typedef typename
Variant::Animator Animator
;
460 typedef typename
Variant::Position Position
;
461 typedef typename
Variant::Piece Piece
;
462 typedef typename
Variant::Move Move
;
463 typedef typename
Variant::Pool Pool
;
465 virtual AbstractPosition::Ptr
createPosition() {
466 return AbstractPosition::Ptr(
467 new WrappedPosition
<Variant
>(Position()));
470 virtual AbstractPosition::Ptr
createCustomPosition(const OptList
& l
) {
471 return AbstractPosition::Ptr(
472 new WrappedPosition
<Variant
>(Position(l
)));
475 virtual AbstractPosition::Ptr
createPositionFromFEN(const QString
& fen
) {
476 std::auto_ptr
<WrappedPosition
<Variant
> > res(
477 new WrappedPosition
<Variant
>(Position()));
479 res
->inner().fromFEN(fen
, ok
);
481 return AbstractPosition::Ptr(res
.release());
483 else return AbstractPosition::Ptr();
486 virtual AbstractPosition::Ptr
createChessboard(int turn
,
487 bool wk
, bool wq
, bool bk
, bool bq
,
489 return AbstractPosition::Ptr(
490 new WrappedPosition
<Variant
>(Position(
491 static_cast<typename
Piece::Color
>(turn
),
492 wk
, wq
, bk
, bq
, ep
)));
494 virtual AbstractPiece::Ptr
createPiece(int color
, int type
) {
495 return AbstractPiece::Ptr(
496 new WrappedPiece
<Variant
>(Piece(
497 static_cast<typename
Piece::Color
>(color
),
498 static_cast<typename
Piece::Type
>(type
))));
500 virtual void forallPieces(class PieceFunction
& f
) {
501 Variant::forallPieces(f
);
503 virtual int moveListLayout() const {
504 return Variant::moveListLayout();
506 virtual AbstractAnimator::Ptr
createAnimator(GraphicalAPI
* graphical_api
) {
507 return AbstractAnimator::Ptr(
508 new WrappedAnimator
<Variant
>(
509 Animator(typename UnwrappedGraphicalAPI
<Variant
>::Ptr(
510 new UnwrappedGraphicalAPI
<Variant
>(graphical_api
)))));
512 virtual AbstractMove::Ptr
createNormalMove(const NormalUserMove
& move
) {
513 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
514 MoveFactory
<Variant
>::createNormalMove(move
)));
516 virtual AbstractMove::Ptr
createDropMove(const DropUserMove
& move
) {
517 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
518 MoveFactory
<Variant
>::createDropMove(move
)));
521 virtual AbstractMove::Ptr
getVerboseMove(int turn
, const VerboseNotation
& m
) const {
522 Move res
= Position::getVerboseMove(static_cast<typename
Piece::Color
>(turn
), m
);
523 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
525 virtual int type(const QString
& str
) {
526 return Piece::getType(str
);
528 virtual QString
typeSymbol(int type
) {
529 return Piece::typeSymbol(static_cast<typename
Piece::Type
>(type
));
531 virtual bool simpleMoves() {
532 return Variant::m_simple_moves
;
534 virtual QString
name() const {
535 return Variant::m_name
;
537 virtual QString
themeProxy() const {
538 return Variant::m_theme_proxy
;
540 virtual OptList
positionOptions() const {
541 return Variant::positionOptions();
545 #endif // HIGHLEVEL_H