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"
21 #include "algebraicnotation.h"
23 template <typename V
> class WrappedPiece
;
24 template <typename V
> class WrappedMove
;
25 template <typename V
> class WrappedPosition
;
28 * @brief Wrap an high level position definition
29 * in a low level AbstractPosition implementation.
31 * Use this class to wrap an high level position definition
32 * in an AbstractPosition implementation suitable for communicating
33 * with the kboard infrastructure.
34 * Variant should be a structure with inner types Position, Move and Piece.
36 * @section Requirements on Position
38 * Position should define the following functions:
39 * - static Point size();
40 * - Piece* operator[](const Point& p) const;
41 * - Piece::Color turn() const;
42 * - void switchTurn();
43 * - bool testMove(Move& m) const;
44 * - void move(const Move& m);
47 * @section Requirements on Piece
49 * Piece should have inner types Color and Type, each
50 * convertible to int via static_cast.
51 * Furthermore, it should implement the following
53 * - Piece::Type type() const;
54 * - Piece::Color color() const;
55 * - QString name() const;
56 * - static QString typeSymbol(Piece::Type type);
58 * @section Move serialization
60 * To customize move serialization, one should specialize
61 * the template MoveSerializer<Pos>.
66 #define __FUNC__ __PRETTY_FUNCTION__
68 #define __FUNC__ __FUNCTION__
71 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
72 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
73 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
74 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
76 #define TYPECHECK(x,y) if (typeid(x) != typeid(y)) MISMATCH(x,y); else { }
80 template <typename Variant
>
81 class WrappedPiece
: public AbstractPiece
{
82 typedef typename
Variant::Piece Piece
;
86 const Piece
& inner() const { return m_piece
; }
88 WrappedPiece(const Piece
& piece
)
91 virtual bool equals(AbstractPiece::Ptr _other
) const {
92 if (!_other
) return false;
93 WrappedPiece
<Variant
>* other
= dynamic_cast<WrappedPiece
<Variant
>*>(_other
.get());
96 return m_piece
== other
->inner();
98 MISMATCH(*_other
.get(),WrappedPiece
<Variant
>);
103 virtual QString
name() const {
104 return m_piece
.name();
107 virtual QString
typeSymbol() const {
108 return Piece::typeSymbol(m_piece
.type());
111 virtual AbstractPiece::Ptr
clone() const {
112 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(m_piece
));
117 template <typename Variant
>
118 class WrappedMove
: public AbstractMove
{
119 typedef typename
Variant::Move Move
;
120 typedef typename
Variant::Position Position
;
124 const Move
& inner() const { return m_move
; }
126 WrappedMove(const Move
& move
)
129 virtual QString
SAN(AbstractPosition::Ptr _pos
) const {
130 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
133 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
134 return serializer
.SAN();
137 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
142 virtual DecoratedMove
toDecoratedMove(boost::shared_ptr
<AbstractPosition
> _pos
) const {
143 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
146 MoveSerializer
<Position
> serializer(m_move
, pos
->inner());
147 return serializer
.toDecoratedMove();
150 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
151 return DecoratedMove();
155 virtual QString
toString(AbstractPosition::Ptr _pos
) const {
156 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
159 return m_move
.toString(pos
->inner().size().y
);
161 MISMATCH(*_pos
.get(),WrappedPosition
<Variant
>);
166 virtual NormalUserMove
toUserMove() const {
167 return MoveFactory
<Variant
>::toNormal(m_move
);
170 virtual bool equals(AbstractMove::Ptr _other
) const {
171 WrappedMove
<Variant
>* other
= dynamic_cast<WrappedMove
<Variant
>*>(_other
.get());
174 return m_move
== other
->inner();
176 MISMATCH(*_other
.get(),WrappedMove
<Variant
>);
182 template <typename Variant
, typename Pool
>
183 class WrappedPoolBase
: public AbstractPool
{
184 typedef typename
Variant::Piece Piece
;
188 WrappedPoolBase(Pool pool
)
192 return m_pool
.size();
195 virtual int insert(int pref_index
, AbstractPiece::Ptr _piece
) {
197 return m_pool
.insert(pref_index
, Piece());
200 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
203 return m_pool
.insert(pref_index
, Piece(piece
->inner()) );
205 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
211 virtual AbstractPiece::Ptr
get(int index
) {
212 Piece piece
= m_pool
.get(index
);
214 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
216 return AbstractPiece::Ptr();
219 virtual AbstractPiece::Ptr
take(int index
) {
220 Piece piece
= m_pool
.take(index
);
222 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
224 return AbstractPiece::Ptr();
228 // simple special case for NoPool
229 template <typename Variant
>
230 class WrappedPoolBase
<Variant
, NoPool
> : public AbstractPool
{
232 WrappedPoolBase(NoPool
) { }
235 template <typename Variant
>
236 class WrappedPool
: public WrappedPoolBase
<Variant
, typename
Variant::Pool
> {
238 WrappedPool(typename
Variant::Pool pool
)
239 : WrappedPoolBase
<Variant
, typename
Variant::Pool
>(pool
) { }
243 * Metafunction that returns a null pointer when
244 * its template argument is NoPool.
246 template <typename Variant
, typename Pool
>
248 static AbstractPool::Ptr
apply(typename
Variant::Position
& position
, int player
) {
249 return AbstractPool::Ptr(
250 new WrappedPool
<Variant
>(position
.pool(player
)));
254 template <typename Variant
>
255 struct ReturnPool
<Variant
, NoPool
> {
256 static AbstractPool::Ptr
apply(typename
Variant::Position
&, int) {
257 return AbstractPool::Ptr();
261 template <typename Variant
>
262 class WrappedPosition
: public AbstractPosition
{
263 typedef typename
Variant::Position Position
;
264 typedef typename
Variant::Move Move
;
265 typedef typename
Variant::Piece Piece
;
266 typedef typename
Variant::Pool Pool
;
270 const Position
& inner() const { return m_pos
; }
271 Position
& inner() { return m_pos
; }
273 WrappedPosition(const Position
& pos
)
276 virtual Point
size() const {
277 return inner().size();
280 virtual QStringList
borderCoords() const {
281 return inner().borderCoords();
284 virtual void setup() {
288 virtual AbstractPiece::Ptr
get(const Point
& p
) const {
289 Piece piece
= m_pos
.get(p
);
291 return AbstractPiece::Ptr(new WrappedPiece
<Variant
>(piece
));
293 return AbstractPiece::Ptr();
296 virtual void set(const Point
& p
, AbstractPiece::Ptr _piece
) {
298 m_pos
.set(p
, Piece());
301 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
304 m_pos
.set(p
, piece
->inner() );
306 MISMATCH(*_piece
.get(),WrappedPiece
<Variant
>);
310 virtual AbstractPool::Ptr
pool(int player
) {
311 return ReturnPool
<Variant
, Pool
>::apply(m_pos
, player
);
314 virtual InteractionType
movable(const Point
& p
) const {
315 return m_pos
.movable(p
);
318 virtual InteractionType
droppable(int p
) const {
319 return m_pos
.droppable(p
);
322 virtual int turn() const {
323 return static_cast<int>(m_pos
.turn());
326 virtual void setTurn(int turn
) {
327 m_pos
.setTurn(static_cast<typename
Piece::Color
>(turn
));
330 virtual int previousTurn() const {
331 return static_cast<int>(m_pos
.previousTurn());
334 virtual void switchTurn() {
338 virtual bool testMove(AbstractMove::Ptr _move
) const {
339 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
342 return m_pos
.testMove( const_cast<Move
&>(move
->inner()) );
344 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
349 virtual void move(AbstractMove::Ptr _move
) {
350 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
353 m_pos
.move(move
->inner());
355 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
358 virtual AbstractPosition::Ptr
clone() const {
359 return AbstractPosition::Ptr(new WrappedPosition
<Variant
>(m_pos
));
362 virtual void copyFrom(const AbstractPosition::Ptr
& _p
) {
363 WrappedPosition
* p
= dynamic_cast<WrappedPosition
*>(_p
.get());
368 MISMATCH(*_p
.get(),WrappedPosition
);
371 virtual bool equals(AbstractPosition::Ptr _other
) const {
372 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
375 return m_pos
== other
->inner();
377 MISMATCH(*_other
.get(),WrappedPosition
<Variant
>);
382 virtual AbstractMove::Ptr
getMove(const AlgebraicNotation
& san
) const {
384 Move res
= m_pos
.getMove(san
, ok
);
386 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
388 return AbstractMove::Ptr();
391 virtual AbstractMove::Ptr
getMove(const QString
& san
) const {
392 AlgebraicNotation
move(san
, size().y
); //FIXME
394 return AbstractMove::Ptr();
395 return getMove(move
);
398 virtual QString
state() const {
402 virtual QString
fen(int halfmove
, int fullmove
) const {
403 return m_pos
.fen(halfmove
, fullmove
);
406 virtual AbstractPiece::Ptr
moveHint(AbstractMove::Ptr _move
) const {
407 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
410 if(boost::shared_ptr
<Piece
> hint
= m_pos
.moveHint(move
->inner()))
411 return AbstractPiece::Ptr(
412 new WrappedPiece
<Variant
>(Piece(*hint
)));
415 MISMATCH(*_move
.get(),WrappedMove
<Variant
>);
418 return AbstractPiece::Ptr();
421 virtual QString
variant() const {
422 return Variant::m_name
;
425 virtual void dump() const {
431 template <typename Variant
>
432 class WrappedAnimator
: public AbstractAnimator
{
433 typedef typename
Variant::Position Position
;
434 typedef typename
Variant::Animator Animator
;
435 typedef typename
Variant::Move Move
;
439 const Animator
& inner() const { return m_animator
; }
441 WrappedAnimator(const Animator
& animator
)
442 : m_animator(animator
) { }
444 virtual AnimationPtr
warp(AbstractPosition::Ptr _pos
) {
445 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
447 return m_animator
.warp(pos
->inner());
449 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
450 return AnimationPtr();
454 virtual AnimationPtr
forward(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
455 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
456 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
459 return m_animator
.forward(pos
->inner(), move
->inner());
462 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
464 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
465 return AnimationPtr();
469 virtual AnimationPtr
back(AbstractPosition::Ptr _pos
, AbstractMove::Ptr _move
) {
470 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
471 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
474 return m_animator
.back(pos
->inner(), move
->inner());
477 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
479 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
480 return AnimationPtr();
485 #include "graphicalapi_unwrapped.h"
487 template <typename Variant
>
488 class WrappedVariantInfo
: public VariantInfo
{
490 typedef typename
Variant::Animator Animator
;
491 typedef typename
Variant::Position Position
;
492 typedef typename
Variant::Piece Piece
;
493 typedef typename
Variant::Move Move
;
494 typedef typename
Variant::Pool Pool
;
496 virtual AbstractPosition::Ptr
createPosition() {
497 return AbstractPosition::Ptr(
498 new WrappedPosition
<Variant
>(Position()));
501 virtual AbstractPosition::Ptr
createCustomPosition(const OptList
& l
) {
502 return AbstractPosition::Ptr(
503 new WrappedPosition
<Variant
>(Position(l
)));
506 virtual AbstractPosition::Ptr
createPositionFromFEN(const QString
& fen
) {
507 std::auto_ptr
<WrappedPosition
<Variant
> > res(
508 new WrappedPosition
<Variant
>(Position()));
510 res
->inner().fromFEN(fen
, ok
);
512 return AbstractPosition::Ptr(res
.release());
514 else return AbstractPosition::Ptr();
517 virtual AbstractPosition::Ptr
createChessboard(int turn
,
518 bool wk
, bool wq
, bool bk
, bool bq
,
520 return AbstractPosition::Ptr(
521 new WrappedPosition
<Variant
>(Position(
522 static_cast<typename
Piece::Color
>(turn
),
523 wk
, wq
, bk
, bq
, ep
)));
525 virtual AbstractPiece::Ptr
createPiece(int color
, int type
) {
526 return AbstractPiece::Ptr(
527 new WrappedPiece
<Variant
>(Piece(
528 static_cast<typename
Piece::Color
>(color
),
529 static_cast<typename
Piece::Type
>(type
))));
531 virtual void forallPieces(class PieceFunction
& f
) {
532 Variant::forallPieces(f
);
534 virtual int moveListLayout() const {
535 return Variant::moveListLayout();
537 virtual AbstractAnimator::Ptr
createAnimator(GraphicalAPI
* graphical_api
) {
538 return AbstractAnimator::Ptr(
539 new WrappedAnimator
<Variant
>(
540 Animator(typename UnwrappedGraphicalAPI
<Variant
>::Ptr(
541 new UnwrappedGraphicalAPI
<Variant
>(graphical_api
)))));
543 virtual AbstractMove::Ptr
createNormalMove(const NormalUserMove
& move
) {
544 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
545 MoveFactory
<Variant
>::createNormalMove(move
)));
547 virtual AbstractMove::Ptr
createDropMove(const DropUserMove
& move
) {
548 return AbstractMove::Ptr(new WrappedMove
<Variant
>(
549 MoveFactory
<Variant
>::createDropMove(move
)));
552 virtual AbstractMove::Ptr
getVerboseMove(int turn
, const VerboseNotation
& m
) const {
553 Move res
= Position::getVerboseMove(static_cast<typename
Piece::Color
>(turn
), m
);
554 return AbstractMove::Ptr(new WrappedMove
<Variant
>(res
));
556 virtual int type(const QString
& str
) {
557 return Piece::getType(str
);
559 virtual QString
typeSymbol(int type
) {
560 return Piece::typeSymbol(static_cast<typename
Piece::Type
>(type
));
562 virtual bool simpleMoves() {
563 return Variant::m_simple_moves
;
565 virtual QString
name() const {
566 return Variant::m_name
;
568 virtual QString
themeProxy() const {
569 return Variant::m_theme_proxy
;
571 virtual OptList
positionOptions() const {
572 return Variant::positionOptions();
576 #endif // HIGHLEVEL_H