Add a move-generator API.master/movegen
authorYann Dirson <ydirson@altern.org>
Sun, 20 Apr 2008 19:52:42 +0000 (20 21:52 +0200)
committerYann Dirson <ydirson@altern.org>
Sun, 20 Apr 2008 19:52:42 +0000 (20 21:52 +0200)
src/core/CMakeLists.txt
src/core/defaultstate.cpp [new file with mode: 0644]
src/core/defaultstate.h [new file with mode: 0644]
src/core/defaulttype.cpp [new file with mode: 0644]
src/core/defaulttype.h [new file with mode: 0644]
src/core/delegators/defaultstate.h [new file with mode: 0644]
src/core/delegators/state.h

index 6b5bb20..d26e4da 100644 (file)
@@ -9,6 +9,8 @@ set(taguacore_SRCS
   defaultpolicy.cpp
   defaultpool.cpp
   defaultpoolcollection.cpp
+  defaultstate.cpp
+  defaulttype.cpp
   dropanimator.cpp
   move.cpp
   moveserializer.cpp
diff --git a/src/core/defaultstate.cpp b/src/core/defaultstate.cpp
new file mode 100644 (file)
index 0000000..7df4508
--- /dev/null
@@ -0,0 +1,39 @@
+#include "behaviour.h"
+#include "board.h"
+#include "defaultstate.h"
+#include "defaulttype.h"
+
+std::vector<const Point*> DefaultState::theoreticalMoves(const Piece& piece,
+                                                        const Point& src) const {
+  std::vector<const Point*> destinations;
+
+  const IBehaviour* behaviour = this->behaviour();
+  if (!behaviour) return destinations; // empty
+
+  const std::vector<MoveDefinition> * defs =
+    dynamic_cast<const DefaultType*>(piece.type())->movesDefinitions();
+  if (!defs) return destinations; // empty
+
+  //kDebug() << "looking at moves from " << src;
+  for (unsigned direction=0; direction < defs->size(); direction++)
+    for (int distance=1;
+        (*defs)[direction].distance ? (distance <= (*defs)[direction].distance) : 1;
+        distance++) {
+      Point* candidate = new Point(src.x + ((*defs)[direction].x * distance *
+                                           -behaviour->direction(piece.color()).y),
+                                  src.y + ((*defs)[direction].y * distance *
+                                           behaviour->direction(piece.color()).y));
+      if (!board()->valid(*candidate))
+       // end of board: don't look further in that direction
+       break;
+
+      destinations.push_back(candidate);
+
+      // stop looking in direction if there is a piece blocking move here
+      const Piece otherPiece = board()->get(*candidate);
+      if (otherPiece != Piece())
+       break;
+  }
+
+  return destinations;
+}
diff --git a/src/core/defaultstate.h b/src/core/defaultstate.h
new file mode 100644 (file)
index 0000000..6c602b2
--- /dev/null
@@ -0,0 +1,17 @@
+
+#ifndef CORE__DEFAULT_STATE_H
+#define CORE__DEFAULT_STATE_H
+
+#include "piece.h"
+#include "point.h"
+#include "state.h"
+
+#include <vector>
+
+class TAGUA_EXPORT DefaultState : virtual public IState {
+public:
+  virtual std::vector<const Point*> theoreticalMoves(const Piece& piece,
+                                                    const Point& src) const;
+};
+
+#endif // CORE__DEFAULT_STATE_H
diff --git a/src/core/defaulttype.cpp b/src/core/defaulttype.cpp
new file mode 100644 (file)
index 0000000..889b4f2
--- /dev/null
@@ -0,0 +1,27 @@
+#include "defaultstate.h"
+#include "defaulttype.h"
+#include "move.h"
+
+#include <KDebug>
+
+bool DefaultType::canMove(const Piece& piece, const Piece&,
+                         Move& move, const IState* state) const {
+  const DefaultState* dstate = dynamic_cast<const DefaultState*>(state);
+  if (dstate == NULL) {
+    kDebug() << "use of a non-DefaultState-derived state with DefaultType";
+    return false;
+  }
+  std::vector<const Point*> moves = dstate->theoreticalMoves(piece, move.src());
+  std::vector<const Point*>::const_iterator it;
+  for (it = moves.begin(); it != moves.end(); it++) {
+    if (move.dst() == **it)
+      return true;
+    delete *it;
+  }
+
+  // delete remaining points in the vector
+  for (; it != moves.end(); it++)
+    delete *it;
+
+  return false;
+}
diff --git a/src/core/defaulttype.h b/src/core/defaulttype.h
new file mode 100644 (file)
index 0000000..f93c2c8
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef CORE__DEFAULT_TYPE_H
+#define CORE__DEFAULT_TYPE_H
+
+#include "type.h"
+
+#include <vector>
+
+class IState;
+class Move;
+class Piece;
+
+typedef struct {
+  unsigned x, y;
+  int distance;
+} MoveDefinition;
+
+class TAGUA_EXPORT DefaultType: public IType {
+public:
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const = 0;
+  virtual bool canMove(const Piece& piece, const Piece& target,
+                       Move& move, const IState* state) const;
+};
+
+#endif // CORE__DEFAULT_TYPE_H
diff --git a/src/core/delegators/defaultstate.h b/src/core/delegators/defaultstate.h
new file mode 100644 (file)
index 0000000..654fcca
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef DELEGATORS__DEFAULT_STATE_H
+#define DELEGATORS__DEFAULT_STATE_H
+
+#include "../defaultstate.h"
+#include "state.h"
+
+#include <KDebug>
+#include <typeinfo>
+
+namespace Delegators {
+
+class DefaultState : public State, public ::DefaultState {
+protected:
+  ::DefaultState* m_state;
+public:
+  DefaultState(IState* state)
+    : State(state) {
+    ::DefaultState* dstate = dynamic_cast< ::DefaultState*>(state);
+    if (dstate == NULL) {
+      kError() << "Delegators::DefaultState needs a ::DefaultState, cannot use a"
+              << typeid(state).name();
+      abort();
+    }
+
+    m_state = dstate;
+    m_state->setDelegator(this);
+  }
+  virtual ~DefaultState() { delete m_state; }
+
+  virtual std::vector<const Point*> theoreticalMoves(const Piece& piece,
+                                                    const Point& src) const
+  { return m_state->theoreticalMoves(piece, src); }
+};
+
+} // namespace Delegators
+
+#endif // DELEGATORS__DEFAULT_STATE_H
index d59dde4..a2155ae 100644 (file)
@@ -17,7 +17,7 @@
   */
 namespace Delegators {
 
-class State : public IState {
+class State : virtual public IState {
 protected:
   IState* m_state;
 public: