2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2007 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.
11 #ifndef HLVARIANT__TAGUA_WRAPPED_H
12 #define HLVARIANT__TAGUA_WRAPPED_H
16 #include "movefactory.h"
18 #include "variantdata.h"
21 #define __FUNC__ __PRETTY_FUNCTION__
23 #define __FUNC__ __FUNCTION__
26 #define MISMATCH(x,y) (kDebug() << " --> Error in "<<__FUNC__<<", MISMATCH!" \
27 << " got type " << prettyTypeName(typeid(x).name()) \
28 << " instead of " << prettyTypeName(typeid(y).name()) \
29 << " this is " << prettyTypeName(typeid(*this).name()) )
31 #define DEFINE_VARIANT_FACTORY() \
32 VariantFactory* createFactory() { \
33 return new WrappedVariantFactory<Variant>; \
38 template <typename Variant
> class WrappedPosition
;
40 template <typename Variant
>
41 class WrappedPiece
: public AbstractPiece
{
42 typedef typename VariantData
<Variant
>::Piece Piece
;
46 const Piece
& inner() const { return m_piece
; }
48 WrappedPiece(const Piece
& piece
)
51 virtual bool equals(const PiecePtr
& _other
) const {
52 if (!_other
) return false;
53 WrappedPiece
<Variant
>* other
= dynamic_cast<WrappedPiece
<Variant
>*>(_other
.get());
56 return m_piece
== other
->inner();
58 MISMATCH(*_other
.get(),WrappedPiece
<Variant
>);
63 virtual QString
name() const {
64 return m_piece
.name();
67 virtual PiecePtr
clone() const {
68 return PiecePtr(new WrappedPiece
<Variant
>(m_piece
));
72 template <typename Variant
>
73 class WrappedPool
: public AbstractPool
{
74 typedef typename VariantData
<Variant
>::Pool Pool
;
75 typedef typename VariantData
<Variant
>::Piece Piece
;
79 WrappedPool(Pool
& pool
)
82 WrappedPool(const Pool
& pool
)
83 : m_pool(const_cast<Pool
&>(pool
)) {
84 // FIXME: const_cast is not necessary, here, but to avoid it
85 // we would need to change the API, adding for example an
86 // AbstractConstPool with only const functions and changing the
87 // wrapper accordingly.
94 virtual int insert(int pref_index
, const PiecePtr
& _piece
) {
96 return m_pool
.insert(pref_index
, Piece());
99 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
102 return m_pool
.insert(pref_index
, Piece(piece
->inner()) );
104 MISMATCH(*_piece
.get(), WrappedPiece
<Variant
>);
110 virtual PiecePtr
get(int index
) {
111 Piece piece
= m_pool
.get(index
);
112 if (piece
!= Piece())
113 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
118 virtual PiecePtr
take(int index
) {
119 Piece piece
= m_pool
.take(index
);
120 if (piece
!= Piece())
121 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
127 template <typename Variant
>
128 class WrappedMove
: public AbstractMove
{
129 typedef typename VariantData
<Variant
>::LegalityCheck LegalityCheck
;
130 typedef typename VariantData
<Variant
>::Serializer Serializer
;
131 typedef typename VariantData
<Variant
>::Move Move
;
132 typedef typename VariantData
<Variant
>::GameState GameState
;
136 const Move
& inner() const { return m_move
; }
137 Move
& inner() { return m_move
; }
139 WrappedMove(const Move
& move
)
142 virtual QString
toString(const QString
& rep
, const PositionPtr
& _ref
) const {
143 WrappedPosition
<Variant
>* ref
= dynamic_cast<WrappedPosition
<Variant
>*>(_ref
.get());
146 Serializer
serializer(rep
);
147 return serializer
.serialize(m_move
, ref
->inner());
150 MISMATCH(*_ref
.get(), WrappedPosition
<Variant
>);
155 virtual NormalUserMove
toUserMove() const {
156 typename VariantData
<Variant
>::MoveFactory factory
;
157 return factory
.toNormal(m_move
);
160 virtual bool equals(const MovePtr
& _other
) const {
161 WrappedMove
<Variant
>* other
= dynamic_cast<WrappedMove
<Variant
>*>(_other
.get());
164 return m_move
== other
->inner();
166 MISMATCH(*_other
.get(), WrappedMove
<Variant
>);
173 * Metafunction that returns a null pointer when
174 * its template argument is NoPool.
176 template <typename Variant
, typename Pool
>
177 struct ReturnPoolAux
{
178 static PoolPtr
apply(typename VariantData
<Variant
>::GameState
& state
, int player
) {
179 return PoolPtr(new WrappedPool
<Variant
>(state
.pools().pool(
180 static_cast<typename VariantData
<Variant
>::Piece::Color
>(player
))));
184 template <typename Variant
>
185 struct ReturnPoolAux
<Variant
, NoPool
> {
186 static PoolPtr
apply(typename VariantData
<Variant
>::GameState
&, int) {
191 template <typename Variant
>
193 static PoolPtr
apply(typename VariantData
<Variant
>::GameState
& state
, int player
) {
194 return ReturnPoolAux
<Variant
, typename VariantData
<Variant
>::Pool
>::apply(state
, player
);
198 template <typename Variant
>
199 class WrappedPosition
: public AbstractPosition
{
200 typedef typename VariantData
<Variant
>::LegalityCheck LegalityCheck
;
201 typedef typename VariantData
<Variant
>::GameState GameState
;
202 typedef typename VariantData
<Variant
>::Board Board
;
203 typedef typename VariantData
<Variant
>::Piece Piece
;
204 typedef typename VariantData
<Variant
>::Move Move
;
205 typedef typename VariantData
<Variant
>::Serializer Serializer
;
209 const GameState
& inner() const { return m_state
; }
210 GameState
& inner() { return m_state
; }
212 WrappedPosition(const GameState
& state
)
215 virtual Point
size() const {
216 return m_state
.board().size();
219 virtual QStringList
borderCoords() const {
220 return m_state
.board().borderCoords();
223 virtual void setup() {
227 virtual PiecePtr
get(const Point
& p
) const {
228 Piece piece
= m_state
.board().get(p
);
229 if (piece
!= Piece())
230 return PiecePtr(new WrappedPiece
<Variant
>(piece
));
235 virtual void set(const Point
& p
, const PiecePtr
& _piece
) {
237 m_state
.board().set(p
, Piece());
240 WrappedPiece
<Variant
>* piece
= dynamic_cast<WrappedPiece
<Variant
>*>(_piece
.get());
243 m_state
.board().set(p
, piece
->inner());
245 MISMATCH(*_piece
.get(), WrappedPiece
<Variant
>);
249 virtual PoolPtr
pool(int player
) {
250 return ReturnPool
<Variant
>::apply(m_state
, player
);
253 virtual void copyPoolFrom(const PositionPtr
&) {
257 virtual InteractionType
movable(const TurnTest
& test
, const Point
& p
) const {
258 LegalityCheck
check(m_state
);
259 return check
.movable(test
, p
);
262 virtual InteractionType
droppable(const TurnTest
& test
, int index
) const {
263 LegalityCheck
check(m_state
);
264 return check
.droppable(test
, index
);
267 virtual int turn() const {
268 return static_cast<int>(m_state
.turn());
271 virtual void setTurn(int turn
) {
272 m_state
.setTurn(static_cast<typename
Piece::Color
>(turn
));
275 virtual int previousTurn() const {
276 return static_cast<int>(m_state
.previousTurn());
279 virtual void switchTurn() {
280 m_state
.switchTurn();
283 virtual bool testMove(const MovePtr
& _move
) const {
287 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
290 LegalityCheck
check(m_state
);
291 return check
.legal(move
->inner());
294 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
299 virtual void move(const MovePtr
& _move
) {
303 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
306 m_state
.move(move
->inner());
308 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
311 virtual PositionPtr
clone() const {
312 return PositionPtr(new WrappedPosition
<Variant
>(m_state
));
315 virtual void copyFrom(const PositionPtr
& _p
) {
316 // TODO: check if this is used somewhere
317 WrappedPosition
<Variant
>* p
= dynamic_cast<WrappedPosition
<Variant
>*>(_p
.get());
320 m_state
= p
->inner();
322 MISMATCH(*_p
.get(), WrappedPosition
);
325 virtual bool equals(const PositionPtr
& _other
) const {
326 WrappedPosition
<Variant
>* other
= dynamic_cast<WrappedPosition
<Variant
>*>(_other
.get());
329 return m_state
== other
->inner();
331 MISMATCH(*_other
.get(), WrappedPosition
<Variant
>);
336 virtual MovePtr
getMove(const QString
& san
) const {
337 Serializer
serializer("compact");
338 Move res
= serializer
.deserialize(san
, m_state
);
340 return MovePtr(new WrappedMove
<Variant
>(res
));
346 virtual QString
state() const {
350 virtual PiecePtr
moveHint(const MovePtr
&) const {
351 return PiecePtr(); // BROKEN
354 virtual QString
variant() const {
355 return Variant::m_name
;
358 virtual void dump() const {
365 #include "graphicalapi_unwrapped.h"
366 #include "icsapi_wrapped.h"
368 namespace HLVariant
{
370 template <typename Variant
>
371 class WrappedAnimator
: public AbstractAnimator
{
372 typedef typename VariantData
<Variant
>::GameState GameState
;
373 typedef typename VariantData
<Variant
>::Animator Animator
;
374 typedef typename VariantData
<Variant
>::Move Move
;
378 const Animator
& inner() const { return m_animator
; }
380 WrappedAnimator(const Animator
& animator
)
381 : m_animator(animator
) { }
383 virtual AnimationPtr
warp(const PositionPtr
& _pos
) {
384 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
386 return m_animator
.warp(pos
->inner());
388 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
389 return AnimationPtr();
393 virtual AnimationPtr
forward(const PositionPtr
& _pos
, const MovePtr
& _move
) {
394 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
395 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
398 return m_animator
.forward(pos
->inner(), move
->inner());
401 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
403 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
404 return AnimationPtr();
408 virtual AnimationPtr
back(const PositionPtr
& _pos
, const MovePtr
& _move
) {
409 WrappedPosition
<Variant
>* pos
= dynamic_cast<WrappedPosition
<Variant
>*>(_pos
.get());
410 WrappedMove
<Variant
>* move
= dynamic_cast<WrappedMove
<Variant
>*>(_move
.get());
413 return m_animator
.back(pos
->inner(), move
->inner());
416 MISMATCH(*_move
.get(), WrappedMove
<Variant
>);
418 MISMATCH(*_pos
.get(), WrappedPosition
<Variant
>);
419 return AnimationPtr();
426 template <typename Variant
>
427 class WrappedVariantInfo
: public VariantInfo
{
428 typedef typename VariantData
<Variant
>::Animator Animator
;
429 typedef typename VariantData
<Variant
>::GameState GameState
;
430 typedef typename VariantData
<Variant
>::Piece Piece
;
431 typedef typename VariantData
<Variant
>::Move Move
;
432 // typedef typename VariantData<Variant>::Pool Pool;
436 virtual PositionPtr
createPosition() {
438 new WrappedPosition
<Variant
>(GameState()));
441 virtual PositionPtr
createCustomPosition(const OptList
&) {
443 new WrappedPosition
<Variant
>(GameState())); // BROKEN
446 virtual void forallPieces(class PieceFunction
&) {
450 virtual int moveListLayout() const {
451 return Variant::moveListLayout();
454 virtual AnimatorPtr
createAnimator(GraphicalAPI
* graphical_api
) {
455 return AnimatorPtr(new WrappedAnimator
<Variant
>(
457 typename UnwrappedGraphicalAPIPtr
<Variant
>::type(
458 new UnwrappedGraphicalAPI
<Variant
>(graphical_api
)))));
461 virtual MovePtr
createNormalMove(const NormalUserMove
& move
) {
462 typename VariantData
<Variant
>::MoveFactory factory
;
463 Move m
= factory
.createNormalMove(move
);
464 return MovePtr(new WrappedMove
<Variant
>(m
));
467 virtual MovePtr
createDropMove(const DropUserMove
& move
) {
468 typename VariantData
<Variant
>::MoveFactory factory
;
469 Move m
= factory
.createDropMove(move
);
470 return MovePtr(new WrappedMove
<Variant
>(m
));
473 virtual MovePtr
getVerboseMove(int, const VerboseNotation
&) const {
477 virtual bool simpleMoves() {
478 return Variant::m_simple_moves
;
481 virtual QString
name() const {
482 return Variant::m_name
;
485 virtual QString
themeProxy() const {
486 return Variant::m_theme_proxy
;
489 virtual OptList
positionOptions() const {
490 return m_variant
.positionOptions();
493 virtual ICSAPIPtr
icsAPI() const {
494 return ICSAPIPtr(ReturnICSAPI
<Variant
>::apply());
497 virtual ActionCollection
* actions() {
498 return m_variant
.actions();
501 virtual void setupMove(NormalUserMove
& m
) const {
502 m_variant
.setupMove(m
);
506 template <typename Variant
>
507 class WrappedVariantFactory
: public VariantFactory
{
509 virtual VariantInfo
* createVariant() const {
510 return new WrappedVariantInfo
<Variant
>;
513 virtual QString
name() const {
514 return Variant::m_name
;
517 virtual QString
themeProxy() const {
518 return Variant::m_theme_proxy
;
521 virtual bool hidden() const {
522 return Variant::m_hidden
;
528 #endif // HLVARIANT__TAGUA_WRAPPED_H