Ported ICSAPI.
[tagua.git] / src / hlvariant / tagua_wrapped.h
blob3786c1e34b35225bcf490f6e43c8e417768dc2ef
1 #ifndef HLVARIANT__TAGUA_WRAPPED_H
2 #define HLVARIANT__TAGUA_WRAPPED_H
4 #include "tagua.h"
5 #include "fwd.h"
6 #include "movefactory.h"
7 #include "nopool.h"
8 #include "variantdata.h"
10 #ifdef Q_CC_GNU
11 #define __FUNC__ __PRETTY_FUNCTION__
12 #else
13 #define __FUNC__ __FUNCTION__
14 #endif
16 #define MISMATCH(x,y) (std::cout << " --> Error in "<<__FUNC__<<", MISMATCH!" << std::endl \
17 << " got type " << prettyTypeName(typeid(x).name()) << std::endl \
18 << " instead of " << prettyTypeName(typeid(y).name()) << std::endl \
19 << " this is " << prettyTypeName(typeid(*this).name()) << std::endl)
21 namespace HLVariant {
23 template <typename Variant> class WrappedPosition;
25 template <typename Variant>
26 class WrappedPiece : public AbstractPiece {
27 typedef typename VariantData<Variant>::Piece Piece;
29 Piece m_piece;
30 public:
31 const Piece& inner() const { return m_piece; }
33 WrappedPiece(const Piece& piece)
34 : m_piece(piece) { }
36 virtual bool equals(const PiecePtr& _other) const {
37 if (!_other) return false;
38 WrappedPiece<Variant>* other = dynamic_cast<WrappedPiece<Variant>*>(_other.get());
40 if (other)
41 return m_piece == other->inner();
42 else {
43 MISMATCH(*_other.get(),WrappedPiece<Variant>);
44 return false;
48 virtual QString name() const {
49 return m_piece.name();
52 virtual PiecePtr clone() const {
53 return PiecePtr(new WrappedPiece<Variant>(m_piece));
57 template <typename Variant>
58 class WrappedPool : public AbstractPool {
59 typedef typename VariantData<Variant>::Pool Pool;
60 typedef typename VariantData<Variant>::Piece Piece;
62 Pool& m_pool;
63 public:
64 WrappedPool(Pool& pool)
65 : m_pool(pool) { }
67 WrappedPool(const Pool& pool)
68 : m_pool(const_cast<Pool&>(pool)) {
69 // FIXME: const_cast is not necessary, here, but to avoid it
70 // we would need to change the API, adding for example an
71 // AbstractConstPool with only const functions and changing the
72 // wrapper accordingly.
75 virtual int size() {
76 return m_pool.size();
79 virtual int insert(int pref_index, const PiecePtr& _piece) {
80 if (!_piece) {
81 return m_pool.insert(pref_index, Piece());
83 else {
84 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
86 if (piece)
87 return m_pool.insert(pref_index, Piece(piece->inner()) );
88 else {
89 MISMATCH(*_piece.get(), WrappedPiece<Variant>);
90 return -1;
95 virtual PiecePtr get(int index) {
96 Piece piece = m_pool.get(index);
97 if (piece != Piece())
98 return PiecePtr(new WrappedPiece<Variant>(piece));
99 else
100 return PiecePtr();
103 virtual PiecePtr take(int index) {
104 Piece piece = m_pool.take(index);
105 if (piece != Piece())
106 return PiecePtr(new WrappedPiece<Variant>(piece));
107 else
108 return PiecePtr();
112 template <typename Variant>
113 class WrappedMove : public AbstractMove {
114 typedef typename VariantData<Variant>::LegalityCheck LegalityCheck;
115 typedef typename VariantData<Variant>::Serializer Serializer;
116 typedef typename VariantData<Variant>::Move Move;
117 typedef typename VariantData<Variant>::GameState GameState;
119 Move m_move;
120 public:
121 const Move& inner() const { return m_move; }
122 Move& inner() { return m_move; }
124 WrappedMove(const Move& move)
125 : m_move(move) { }
127 virtual QString SAN(const PositionPtr& _ref) const {
128 WrappedPosition<Variant>* ref = dynamic_cast<WrappedPosition<Variant>*>(_ref.get());
130 if (ref) {
131 Serializer serializer(Serializer::COMPACT);
132 return serializer.serialize(m_move, ref->inner());
134 else {
135 MISMATCH(*_ref.get(), WrappedPosition<Variant>);
136 return "$@%";
140 virtual DecoratedMove toDecoratedMove(const PositionPtr& _ref) const {
141 WrappedPosition<Variant>* ref = dynamic_cast<WrappedPosition<Variant>*>(_ref.get());
143 if (ref) {
144 Serializer serializer(Serializer::DECORATED);
145 return DecoratedMove(serializer.serialize(m_move, ref->inner()));
147 else {
148 MISMATCH(*_ref.get(), WrappedPosition<Variant>);
149 return DecoratedMove("$@%");
153 virtual QString toString(const PositionPtr& _ref) const {
154 WrappedPosition<Variant>* ref = dynamic_cast<WrappedPosition<Variant>*>(_ref.get());
156 if (ref) {
157 Serializer serializer(Serializer::SIMPLE);
158 return serializer.serialize(m_move, ref->inner());
160 else {
161 MISMATCH(*_ref.get(), WrappedPosition<Variant>);
162 return "$@%";
166 virtual NormalUserMove toUserMove() const {
167 typename VariantData<Variant>::MoveFactory factory;
168 return factory.toNormal(m_move);
171 virtual bool equals(const MovePtr& _other) const {
172 WrappedMove<Variant>* other = dynamic_cast<WrappedMove<Variant>*>(_other.get());
174 if (other)
175 return m_move == other->inner();
176 else {
177 MISMATCH(*_other.get(), WrappedMove<Variant>);
178 return false;
184 * Metafunction that returns a null pointer when
185 * its template argument is NoPool.
187 template <typename Variant, typename Pool>
188 struct ReturnPoolAux {
189 static PoolPtr apply(typename VariantData<Variant>::GameState& state, int player) {
190 return PoolPtr(new WrappedPool<Variant>(state.pools().pool(
191 static_cast<typename VariantData<Variant>::Piece::Color>(player))));
195 template <typename Variant>
196 struct ReturnPoolAux<Variant, NoPool> {
197 static PoolPtr apply(typename VariantData<Variant>::GameState&, int) {
198 return PoolPtr();
202 template <typename Variant>
203 struct ReturnPool {
204 static PoolPtr apply(typename VariantData<Variant>::GameState& state, int player) {
205 return ReturnPoolAux<Variant, typename VariantData<Variant>::Pool>::apply(state, player);
209 template <typename Variant>
210 class WrappedPosition : public AbstractPosition {
211 typedef typename VariantData<Variant>::LegalityCheck LegalityCheck;
212 typedef typename VariantData<Variant>::GameState GameState;
213 typedef typename VariantData<Variant>::Board Board;
214 typedef typename VariantData<Variant>::Piece Piece;
215 typedef typename VariantData<Variant>::Move Move;
216 typedef typename VariantData<Variant>::Serializer Serializer;
218 GameState m_state;
219 public:
220 const GameState& inner() const { return m_state; }
221 GameState& inner() { return m_state; }
223 WrappedPosition(const GameState& state)
224 : m_state(state) { }
226 virtual Point size() const {
227 return m_state.board().size();
230 virtual QStringList borderCoords() const {
231 return m_state.board().borderCoords();
234 virtual void setup() {
235 m_state.setup();
238 virtual PiecePtr get(const Point& p) const {
239 Piece piece = m_state.board().get(p);
240 if (piece != Piece())
241 return PiecePtr(new WrappedPiece<Variant>(piece));
242 else
243 return PiecePtr();
246 virtual void set(const Point& p, const PiecePtr& _piece) {
247 if (!_piece) {
248 m_state.board().set(p, Piece());
250 else {
251 WrappedPiece<Variant>* piece = dynamic_cast<WrappedPiece<Variant>*>(_piece.get());
253 if (piece)
254 m_state.board().set(p, piece->inner());
255 else
256 MISMATCH(*_piece.get(), WrappedPiece<Variant>);
260 virtual PoolPtr pool(int player) {
261 return ReturnPool<Variant>::apply(m_state, player);
264 virtual void copyPoolFrom(const PositionPtr&) {
265 // BROKEN
268 virtual InteractionType movable(const TurnTest& test, const Point& p) const {
269 LegalityCheck check(m_state);
270 return check.movable(test, p);
273 virtual InteractionType droppable(const TurnTest& test, int index) const {
274 LegalityCheck check(m_state);
275 return check.droppable(test, index);
278 virtual int turn() const {
279 return static_cast<int>(m_state.turn());
282 virtual void setTurn(int turn) {
283 m_state.setTurn(static_cast<typename Piece::Color>(turn));
286 virtual int previousTurn() const {
287 return static_cast<int>(m_state.previousTurn());
290 virtual void switchTurn() {
291 m_state.switchTurn();
294 virtual bool testMove(const MovePtr& _move) const {
295 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
297 if (move) {
298 LegalityCheck check(m_state);
299 return check.legal(move->inner());
301 else {
302 MISMATCH(*_move.get(), WrappedMove<Variant>);
303 return false;
307 virtual void move(const MovePtr& _move) {
308 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
310 if (move)
311 m_state.move(move->inner());
312 else
313 MISMATCH(*_move.get(), WrappedMove<Variant>);
316 virtual PositionPtr clone() const {
317 return PositionPtr(new WrappedPosition<Variant>(m_state));
320 virtual void copyFrom(const PositionPtr& _p) {
321 // TODO: check if this is used somewhere
322 WrappedPosition<Variant>* p = dynamic_cast<WrappedPosition<Variant>*>(_p.get());
324 if (p)
325 m_state = p->inner();
326 else
327 MISMATCH(*_p.get(), WrappedPosition);
330 virtual bool equals(const PositionPtr& _other) const {
331 WrappedPosition<Variant>* other = dynamic_cast<WrappedPosition<Variant>*>(_other.get());
333 if (other)
334 return m_state == other->inner();
335 else {
336 MISMATCH(*_other.get(), WrappedPosition<Variant>);
337 return false;
341 virtual MovePtr getMove(const QString& san) const {
342 Serializer serializer(Serializer::COMPACT);
343 Move res = serializer.deserialize(san, m_state);
344 if (res.valid()) {
345 return MovePtr(new WrappedMove<Variant>(res));
347 else
348 return MovePtr();
351 virtual QString state() const {
352 return ""; // BROKEN
355 virtual QString fen(int, int) const {
356 return ""; // BROKEN
359 virtual PiecePtr moveHint(const MovePtr&) const {
360 return PiecePtr(); // BROKEN
363 virtual QString variant() const {
364 return Variant::m_name;
367 virtual void dump() const {
368 // BROKEN
374 #include "graphicalapi_unwrapped.h"
375 #include "icsapi_wrapped.h"
377 namespace HLVariant {
379 template <typename Variant>
380 class WrappedAnimator : public AbstractAnimator {
381 typedef typename VariantData<Variant>::GameState GameState;
382 typedef typename VariantData<Variant>::Animator Animator;
383 typedef typename VariantData<Variant>::Move Move;
385 Animator m_animator;
386 public:
387 const Animator& inner() const { return m_animator; }
389 WrappedAnimator(const Animator& animator)
390 : m_animator(animator) { }
392 virtual AnimationPtr warp(const PositionPtr& _pos) {
393 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
394 if (pos)
395 return m_animator.warp(pos->inner());
396 else {
397 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
398 return AnimationPtr();
402 virtual AnimationPtr forward(const PositionPtr& _pos, const MovePtr& _move) {
403 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
404 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
406 if (move && pos)
407 return m_animator.forward(pos->inner(), move->inner());
408 else {
409 if (!move)
410 MISMATCH(*_move.get(), WrappedMove<Variant>);
411 if (!pos)
412 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
413 return AnimationPtr();
417 virtual AnimationPtr back(const PositionPtr& _pos, const MovePtr& _move) {
418 WrappedPosition<Variant>* pos = dynamic_cast<WrappedPosition<Variant>*>(_pos.get());
419 WrappedMove<Variant>* move = dynamic_cast<WrappedMove<Variant>*>(_move.get());
421 if (move && pos)
422 return m_animator.back(pos->inner(), move->inner());
423 else {
424 if (!move)
425 MISMATCH(*_move.get(), WrappedMove<Variant>);
426 if (!pos)
427 MISMATCH(*_pos.get(), WrappedPosition<Variant>);
428 return AnimationPtr();
435 template <typename Variant>
436 class WrappedVariantInfo : public VariantInfo {
437 typedef typename VariantData<Variant>::Animator Animator;
438 typedef typename VariantData<Variant>::GameState GameState;
439 typedef typename VariantData<Variant>::Piece Piece;
440 typedef typename VariantData<Variant>::Move Move;
441 // typedef typename VariantData<Variant>::Pool Pool;
442 public:
443 virtual PositionPtr createPosition() {
444 return PositionPtr(
445 new WrappedPosition<Variant>(GameState()));
448 virtual PositionPtr createCustomPosition(const OptList&) {
449 return PositionPtr(
450 new WrappedPosition<Variant>(GameState())); // BROKEN
453 virtual PositionPtr createPositionFromFEN(const QString&) {
454 return PositionPtr(); // BROKEN
457 virtual void forallPieces(class PieceFunction&) {
458 // BROKEN
461 virtual int moveListLayout() const {
462 return Variant::moveListLayout();
465 virtual AnimatorPtr createAnimator(GraphicalAPI* graphical_api) {
466 return AnimatorPtr(new WrappedAnimator<Variant>(
467 Animator(
468 typename UnwrappedGraphicalAPIPtr<Variant>::type(
469 new UnwrappedGraphicalAPI<Variant>(graphical_api)))));
472 virtual MovePtr createNormalMove(const NormalUserMove& move) {
473 typename VariantData<Variant>::MoveFactory factory;
474 Move m = factory.createNormalMove(move);
475 return MovePtr(new WrappedMove<Variant>(m));
478 virtual MovePtr createDropMove(const DropUserMove& move) {
479 typename VariantData<Variant>::MoveFactory factory;
480 Move m = factory.createDropMove(move);
481 return MovePtr(new WrappedMove<Variant>(m));
484 virtual MovePtr getVerboseMove(int, const VerboseNotation&) const {
485 return MovePtr(); // BROKEN
488 virtual bool simpleMoves() {
489 return Variant::m_simple_moves;
492 virtual QString name() const {
493 return Variant::m_name;
496 virtual QString themeProxy() const {
497 return Variant::m_theme_proxy;
500 virtual OptList positionOptions() const {
501 return Variant::positionOptions();
504 virtual ICSAPIPtr icsAPI() const {
505 return ICSAPIPtr(ReturnICSAPI<Variant>::apply());
510 #endif // HLVARIANT__TAGUA_WRAPPED_H