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)));
281 // return AbstractPool::Ptr();
284 virtual InteractionType
movable(const Point
& p
) const {
285 return m_pos
.movable(p
);
288 virtual InteractionType
droppable(int p
) const {
289 return m_pos
.droppable(p
);
292 virtual int turn() const {
293 return static_cast<int>(m_pos
.turn());
296 virtual void setTurn(int turn
) {
297 m_pos
.setTurn(static_cast<typename
Piece::Color
>(turn
));
300 virtual int previousTurn() const {
301 return static_cast<int>(m_pos
.previousTurn());
304 virtual void switchTurn() {
308 virtual bool testMove(AbstractMove::Ptr _move
) const {
309 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
312 return m_pos
.testMove( const_cast<Move
&>(move
->inner()) );
314 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
319 virtual void move(AbstractMove::Ptr _move
) {
320 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
323 m_pos
.move(move
->inner());
325 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
328 virtual AbstractPosition::Ptr
clone() const {
329 return AbstractPosition::Ptr(new WrappedPosition
<Variant
>(m_pos
));
332 virtual void copyFrom(const AbstractPosition::Ptr
& _p
) {
333 WrappedPosition
* p
= dynamic_cast<WrappedPosition
*>(_p
.get());
338 MISMATCH(*_p
.get(),WrappedPosition
);
341 virtual bool equals(AbstractPosition::Ptr _other
) const {
342 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
345 return m_pos
== other
->inner();
347 MISMATCH(*_other
.get(),WrappedPosition
<Variant
>);
352 virtual AbstractMove::Ptr
getMove(const AlgebraicNotation
& san
) const {
354 Move res
= m_pos
.getMove(san
, ok
);
356 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
358 return AbstractMove::Ptr();
361 virtual AbstractMove::Ptr
getMove(const QString
& san
) const {
362 AlgebraicNotation
move(san
, size().y
); //FIXME
364 return AbstractMove::Ptr();
365 return getMove(move
);
368 virtual QString
state() const {
372 virtual QString
fen(int halfmove
, int fullmove
) const {
373 return m_pos
.fen(halfmove
, fullmove
);
376 virtual AbstractPiece::Ptr
moveHint(AbstractMove::Ptr _move
) const {
377 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
380 if(boost::shared_ptr
<Piece
> hint
= m_pos
.moveHint(move
->inner()))
381 return AbstractPiece::Ptr(
382 new WrappedPiece
<Variant
>(Piece(*hint
)));
385 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
388 return AbstractPiece::Ptr();
391 virtual QString
variant() const {
392 return Variant::m_name
;
395 virtual void dump() const {
401 template <typename Variant
>
402 class WrappedAnimator
: public AbstractAnimator
{
403 typedef typename
Variant::Position Position
;
404 typedef typename
Variant::Animator Animator
;
405 typedef typename
Variant::Move Move
;
409 const Animator
& inner() const { return m_animator
; }
411 WrappedAnimator(const Animator
& animator
)
412 : m_animator(animator
) { }
414 virtual AnimationPtr
warp(AbstractPosition::Ptr _pos
) {
415 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
417 return m_animator
.warp(pos
->inner());
419 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
420 return AnimationPtr();
424 virtual AnimationPtr
forward(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
425 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
426 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
429 return m_animator
.forward(pos
->inner(), move
->inner());
432 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
434 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
435 return AnimationPtr();
439 virtual AnimationPtr
back(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
440 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
441 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
444 return m_animator
.back(pos
->inner(), move
->inner());
447 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
449 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
450 return AnimationPtr();
455 #include "graphicalapi_unwrapped.h"
457 template <typename Variant
>
458 class WrappedVariantInfo
: public VariantInfo
{
460 typedef typename
Variant::Animator Animator
;
461 typedef typename
Variant::Position Position
;
462 typedef typename
Variant::Piece Piece
;
463 typedef typename
Variant::Move Move
;
464 typedef typename
Variant::Pool Pool
;
466 virtual AbstractPosition::Ptr
createPosition() {
467 return AbstractPosition::Ptr(
468 new WrappedPosition
<Variant
>(Position()));
471 virtual AbstractPosition::Ptr
createCustomPosition(const OptList
& l
) {
472 return AbstractPosition::Ptr(
473 new WrappedPosition
<Variant
>(Position(l
)));
476 virtual AbstractPosition::Ptr
createPositionFromFEN(const QString
& fen
) {
477 std::auto_ptr
<WrappedPosition
<Variant
> > res(
478 new WrappedPosition
<Variant
>(Position()));
480 res
->inner().fromFEN(fen
, ok
);
482 return AbstractPosition::Ptr(res
.release());
484 else return AbstractPosition::Ptr();
487 virtual AbstractPosition::Ptr
createChessboard(int turn
,
488 bool wk
, bool wq
, bool bk
, bool bq
,
490 return AbstractPosition::Ptr(
491 new WrappedPosition
<Variant
>(Position(
492 static_cast<typename
Piece::Color
>(turn
),
493 wk
, wq
, bk
, bq
, ep
)));
495 virtual AbstractPiece::Ptr
createPiece(int color
, int type
) {
496 return AbstractPiece::Ptr(
497 new WrappedPiece
<Variant
>(Piece(
498 static_cast<typename
Piece::Color
>(color
),
499 static_cast<typename
Piece::Type
>(type
))));
501 virtual void forallPieces(class PieceFunction
& f
) {
502 Variant::forallPieces(f
);
504 virtual int moveListLayout() const {
505 return Variant::moveListLayout();
507 virtual AbstractAnimator::Ptr
createAnimator(GraphicalAPI
* graphical_api
) {
508 return AbstractAnimator::Ptr(
509 new WrappedAnimator
<Variant
>(
510 Animator(typename UnwrappedGraphicalAPI
<Variant
>::Ptr(
511 new UnwrappedGraphicalAPI
<Variant
>(graphical_api
)))));
513 virtual AbstractMove::Ptr
createNormalMove(const NormalUserMove
& move
) {
514 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
515 MoveFactory
<Variant
>::createNormalMove(move
)));
517 virtual AbstractMove::Ptr
createDropMove(const DropUserMove
& move
) {
518 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
519 MoveFactory
<Variant
>::createDropMove(move
)));
522 virtual AbstractMove::Ptr
getVerboseMove(int turn
, const VerboseNotation
& m
) const {
523 Move res
= Position::getVerboseMove(static_cast<typename
Piece::Color
>(turn
), m
);
524 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
526 virtual int type(const QString
& str
) {
527 return Piece::getType(str
);
529 virtual QString
typeSymbol(int type
) {
530 return Piece::typeSymbol(static_cast<typename
Piece::Type
>(type
));
532 virtual bool simpleMoves() {
533 return Variant::m_simple_moves
;
535 virtual QString
name() const {
536 return Variant::m_name
;
538 virtual QString
themeProxy() const {
539 return Variant::m_theme_proxy
;
541 virtual OptList
positionOptions() const {
542 return Variant::positionOptions();
546 #endif // HIGHLEVEL_H