Preliminary port of Shogi to the component API.master/shogi
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)
51 files changed:
TODO_shogi
data/themes/pieces/ShogiTTF/theme.lua
debian/.gitignore
debian/control
debian/tagua-variant-shogi.files [new file with mode: 0644]
src/variantfactories/builtinvariants.cpp
src/variants/CMakeLists.txt
src/variants/shogi/CMakeLists.txt [new file with mode: 0644]
src/variants/shogi/behaviour.cpp [new file with mode: 0644]
src/variants/shogi/behaviour.h [new file with mode: 0644]
src/variants/shogi/colors.cpp [new file with mode: 0644]
src/variants/shogi/colors.h [new file with mode: 0644]
src/variants/shogi/moveserializer.cpp [new file with mode: 0644]
src/variants/shogi/moveserializer.h [new file with mode: 0644]
src/variants/shogi/shogi.cpp [new file with mode: 0644]
src/variants/shogi/state.cpp [new file with mode: 0644]
src/variants/shogi/state.h [new file with mode: 0644]
src/variants/shogi/tagua-shogi.desktop [new file with mode: 0644]
src/variants/shogi/type.cpp [new file with mode: 0644]
src/variants/shogi/type.h [new file with mode: 0644]
src/variants/shogi/types.h [new file with mode: 0644]
src/variants/shogi/types/bishop.cpp [new file with mode: 0644]
src/variants/shogi/types/bishop.h [new file with mode: 0644]
src/variants/shogi/types/dragonhorse.cpp [new file with mode: 0644]
src/variants/shogi/types/dragonhorse.h [new file with mode: 0644]
src/variants/shogi/types/dragonking.cpp [new file with mode: 0644]
src/variants/shogi/types/dragonking.h [new file with mode: 0644]
src/variants/shogi/types/gold.cpp [new file with mode: 0644]
src/variants/shogi/types/gold.h [new file with mode: 0644]
src/variants/shogi/types/king.cpp [new file with mode: 0644]
src/variants/shogi/types/king.h [new file with mode: 0644]
src/variants/shogi/types/knight.cpp [new file with mode: 0644]
src/variants/shogi/types/knight.h [new file with mode: 0644]
src/variants/shogi/types/lance.cpp [new file with mode: 0644]
src/variants/shogi/types/lance.h [new file with mode: 0644]
src/variants/shogi/types/narigin.cpp [new file with mode: 0644]
src/variants/shogi/types/narigin.h [new file with mode: 0644]
src/variants/shogi/types/narikei.cpp [new file with mode: 0644]
src/variants/shogi/types/narikei.h [new file with mode: 0644]
src/variants/shogi/types/narikyo.cpp [new file with mode: 0644]
src/variants/shogi/types/narikyo.h [new file with mode: 0644]
src/variants/shogi/types/pawn.cpp [new file with mode: 0644]
src/variants/shogi/types/pawn.h [new file with mode: 0644]
src/variants/shogi/types/rook.cpp [new file with mode: 0644]
src/variants/shogi/types/rook.h [new file with mode: 0644]
src/variants/shogi/types/silver.cpp [new file with mode: 0644]
src/variants/shogi/types/silver.h [new file with mode: 0644]
src/variants/shogi/types/tokin.cpp [new file with mode: 0644]
src/variants/shogi/types/tokin.h [new file with mode: 0644]
src/variants/shogi/validator.cpp [new file with mode: 0644]
src/variants/shogi/validator.h [new file with mode: 0644]

index 988d1ad..8fade13 100644 (file)
@@ -1,3 +1,40 @@
+move generator:
+- add to IType and implement for chess
+- use a "set" class instead of a vector for quick is-in test ?
+- call from core once, to avoid the numerous calls to canMove()
+- have the GUI highlight all possible moves
+- remove individual highlighting of square under cursor
+- maybe export moves definitions to lua to avoid duplicating the
+  same data in theme shogi-lib
+
+general:
+- plugins linked with too many libs
+- at ui startup, some moves do get badly animated
+ - chess knight gets its animation, but too fast
+ - first move of a shogi pawn/king or of a knight does not get animated (or too fast ?)
+component-api port:
+- finalize shogi functionnality:
+ - promoting moves
+       legalitycheck.h pseudolegal() -> validator.cpp
+       shogiactions.* -> ?
+       ? -> state.cpp move()
+ - drops
+       - pieces do not appear in pool
+       ? -> moveserializer.* serialize()
+ - dropped pawn cannot checkmate (not in master ?!)
+ - piece orientation
+ - japanese digits on shogiban (shogiban.h borderCoords() -> move to theme ?)
+ - put correct credits in variants/shogi/*
+ - knight moves -> caracterize jump moves instead of hardcoding Knight in animations
+ - caracterize royal status (maybe policy-driven to account for Prince in Sho)
+   instead of hardcoding King
+ - king and knight do not have a figurine displayed
+
+other general non-shogi-related things to do quickly:
+- find out how to use uninstalled plugins, document running from source tree
+- shlib versionning scheme
+- engines do not work any more (No such slot EngineInfo::playAsWhite)
+
 tagua core:
 - gnushogi engine gets confused when moving through history => generic pb ?
 - tooltips for figurines, for people who can't read kanji
@@ -5,6 +42,7 @@ tagua core:
   -> maybe by splitting target square, so the piece gets all different
      moves in one click, depending on which part of the square is hit ?
 - allow to setup and play problems (tsume shogi)
+- install engine declarations system-wide
 
 engines/core:
 - engine options (eg. select difficulty level)
index 63925b6..2f36730 100644 (file)
@@ -50,75 +50,75 @@ function shogi_piece(first, char, white, promoted, ratio, moves)
                           addChar(first, char, promoted)))
 end
 
-theme.black_king      = shogi_piece(shogichars["jade general"][2], shogichars["jade general"][1],
-                                   false, false, 1, shogimoves_king)
-theme.black_rook      = shogi_piece(shogichars["flying chariot"][2], shogichars["flying chariot"][1],
+theme.black_king       = shogi_piece(shogichars["jade general"][2], shogichars["jade general"][1],
+                                   false, false, 1, shogimoves_king);
+theme.black_rook       = shogi_piece(shogichars["flying chariot"][2], shogichars["flying chariot"][1],
                                    false, false, 0.96, shogimoves_rook)
-theme.black_p_rook    = shogi_piece(shogichars["dragon king"][2], shogichars["dragon king"][1],
+theme.black_dragonking  = shogi_piece(shogichars["dragon king"][2], shogichars["dragon king"][1],
                                    false, true, 0.96, shogimoves_dragon)
-theme.black_bishop    = shogi_piece(shogichars["bishop"][2], shogichars["bishop"][1],
+theme.black_bishop     = shogi_piece(shogichars["bishop"][2], shogichars["bishop"][1],
                                    false, false, 0.93, shogimoves_bishop)
-theme.black_p_bishop  = shogi_piece(shogichars["dragon horse"][2], shogichars["dragon horse"][1],
+theme.black_dragonhorse = shogi_piece(shogichars["dragon horse"][2], shogichars["dragon horse"][1],
                                    false, true, 0.93, shogimoves_horse)
-theme.black_gold      = shogi_piece(shogichars["gold general"][2], shogichars["gold general"][1],
+theme.black_gold       = shogi_piece(shogichars["gold general"][2], shogichars["gold general"][1],
                                    false, false, 0.9, shogimoves_gold)
-theme.black_silver    = shogi_piece(shogichars["silver general"][2], shogichars["silver general"][1],
+theme.black_silver     = shogi_piece(shogichars["silver general"][2], shogichars["silver general"][1],
                                    false, false, 0.9, shogimoves_silver)
-theme.black_p_silver  = shogi_piece(shogichars["narikei"][2], shogichars["narikei"][1],
+theme.black_narigin    = shogi_piece(shogichars["narigin"][2], shogichars["narigin"][1],
                                    false, true, 0.9, shogimoves_gold)
-theme.black_knight    = shogi_piece(shogichars["knight"][2], shogichars["knight"][1],
+theme.black_knight     = shogi_piece(shogichars["knight"][2], shogichars["knight"][1],
                                    false, false, 0.86, shogimoves_knight)
-theme.black_p_knight  = shogi_piece(shogichars["narikei"][2], shogichars["narikei"][1],
+theme.black_narikei    = shogi_piece(shogichars["narikei"][2], shogichars["narikei"][1],
                                    false, true, 0.86, shogimoves_gold)
-theme.black_lance     = shogi_piece(shogichars["incense chariot"][2], shogichars["incense chariot"][1],
+theme.black_lance      = shogi_piece(shogichars["incense chariot"][2], shogichars["incense chariot"][1],
                                    false, false, 0.83, shogimoves_lance)
-theme.black_p_lance   = shogi_piece(shogichars["narikyo"][2], shogichars["narikyo"][1],
+theme.black_narikyo    = shogi_piece(shogichars["narikyo"][2], shogichars["narikyo"][1],
                                    false, true, 0.83, shogimoves_gold)
-theme.black_pawn      = shogi_piece(shogichars["pawn"][2], shogichars["pawn"][1],
+theme.black_pawn       = shogi_piece(shogichars["pawn"][2], shogichars["pawn"][1],
                                    false, false, 0.8, shogimoves_pawn)
-theme.black_p_pawn    = shogi_piece(shogichars["tokin"][2], shogichars["tokin"][1],
+theme.black_tokin      = shogi_piece(shogichars["tokin"][2], shogichars["tokin"][1],
                                    false, true, 0.8, shogimoves_gold)
 
-theme.white_king      = shogi_piece(shogichars["king"][2], shogichars["king"][1],
+theme.white_king       = shogi_piece(shogichars["king"][2], shogichars["king"][1],
                                    true, false, 1, shogimoves_king)
-theme.white_rook      = shogi_piece(shogichars["flying chariot"][2], shogichars["flying chariot"][1],
+theme.white_rook       = shogi_piece(shogichars["flying chariot"][2], shogichars["flying chariot"][1],
                                    true, false, 0.96, shogimoves_rook)
-theme.white_p_rook    = shogi_piece(shogichars["dragon king"][2], shogichars["dragon king"][1],
+theme.white_dragonking  = shogi_piece(shogichars["dragon king"][2], shogichars["dragon king"][1],
                                    true, true, 0.96, shogimoves_dragon)
-theme.white_bishop    = shogi_piece(shogichars["bishop"][2], shogichars["bishop"][1],
+theme.white_bishop     = shogi_piece(shogichars["bishop"][2], shogichars["bishop"][1],
                                    true, false, 0.93, shogimoves_bishop)
-theme.white_p_bishop  = shogi_piece(shogichars["dragon horse"][2], shogichars["dragon horse"][1],
+theme.white_dragonhorse        = shogi_piece(shogichars["dragon horse"][2], shogichars["dragon horse"][1],
                                    true, true, 0.93, shogimoves_horse)
-theme.white_gold      = shogi_piece(shogichars["gold general"][2], shogichars["gold general"][1],
+theme.white_gold       = shogi_piece(shogichars["gold general"][2], shogichars["gold general"][1],
                                    true, false, 0.9, shogimoves_gold)
-theme.white_silver    = shogi_piece(shogichars["silver general"][2], shogichars["silver general"][1],
+theme.white_silver     = shogi_piece(shogichars["silver general"][2], shogichars["silver general"][1],
                                    true, false, 0.9, shogimoves_silver)
-theme.white_p_silver  = shogi_piece(shogichars["narikei"][2], shogichars["narikei"][1],
+theme.white_narigin    = shogi_piece(shogichars["narigin"][2], shogichars["narigin"][1],
                                    true, true, 0.9, shogimoves_gold)
-theme.white_knight    = shogi_piece(shogichars["knight"][2], shogichars["knight"][1],
+theme.white_knight     = shogi_piece(shogichars["knight"][2], shogichars["knight"][1],
                                    true, false, 0.86, shogimoves_knight)
-theme.white_p_knight  = shogi_piece(shogichars["narikei"][2], shogichars["narikei"][1],
+theme.white_narikei    = shogi_piece(shogichars["narikei"][2], shogichars["narikei"][1],
                                    true, true, 0.86, shogimoves_gold)
-theme.white_lance     = shogi_piece(shogichars["incense chariot"][2], shogichars["incense chariot"][1],
+theme.white_lance      = shogi_piece(shogichars["incense chariot"][2], shogichars["incense chariot"][1],
                                    true, false, 0.83, shogimoves_lance)
-theme.white_p_lance   = shogi_piece(shogichars["narikyo"][2], shogichars["narikyo"][1],
+theme.white_narikyo    = shogi_piece(shogichars["narikyo"][2], shogichars["narikyo"][1],
                                    true, true, 0.83, shogimoves_gold)
-theme.white_pawn      = shogi_piece(shogichars["pawn"][2], shogichars["pawn"][1],
+theme.white_pawn       = shogi_piece(shogichars["pawn"][2], shogichars["pawn"][1],
                                    true, false, 0.8, shogimoves_pawn)
-theme.white_p_pawn    = shogi_piece(shogichars["tokin"][2],shogichars["tokin"][1],
+theme.white_tokin      = shogi_piece(shogichars["tokin"][2],shogichars["tokin"][1],
                                    true, true, 0.8, shogimoves_gold)
 
 -- Sho Shogi
 
-theme.black_drunken_elephant = shogi_piece(shogichars["drunken elephant"][2], shogichars["drunken elephant"][1],
-                                          false, false, 1, shogimoves_drunken_elephant)
-theme.black_p_drunken_elephant = shogi_piece(shogichars["crown prince"][2], shogichars["crown prince"][1],
-                                            false, true, 1, shogimoves_king)
+theme.black_drunkenelephant = shogi_piece(shogichars["drunken elephant"][2], shogichars["drunken elephant"][1],
+                                         false, false, 1, shogimoves_drunken_elephant)
+theme.black_crownprince     = shogi_piece(shogichars["crown prince"][2], shogichars["crown prince"][1],
+                                         false, true, 1, shogimoves_king)
 
-theme.white_drunken_elephant = shogi_piece(shogichars["drunken elephant"][2], shogichars["drunken elephant"][1],
-                                          true, false, 1, shogimoves_drunken_elephant)
-theme.white_p_drunken_elephant = shogi_piece(shogichars["crown prince"][2], shogichars["crown prince"][1],
-                                            true, true, 1, shogimoves_king)
+theme.white_drunkenelephant = shogi_piece(shogichars["drunken elephant"][2], shogichars["drunken elephant"][1],
+                                         true, false, 1, shogimoves_drunken_elephant)
+theme.white_crownprince     = shogi_piece(shogichars["crown prince"][2], shogichars["crown prince"][1],
+                                         true, true, 1, shogimoves_king)
 
 -- This is part of Dai Shohi
 
index ab75d84..0b6b6da 100644 (file)
@@ -6,4 +6,5 @@ tagua-data
 tagua-variant-chess
 tagua-variant-chess5x5
 tagua-variant-crazyhouse
+tagua-variant-shogi
 tagua-dbg
index 5480776..4721787 100644 (file)
@@ -58,3 +58,12 @@ Provides: tagua-variant
 Description: Chess 5x5 support for the tagua board-game frontend
  This package allows to play "chess 5x5", a chess variant on a 5x5
  board, from tagua.
+
+Package: tagua-variant-shogi
+Architecture: any
+Depends: tagua, tagua-variant-chess, tagua-variant-crazyhouse
+Suggests: gnushogi, gpsshogi
+Provides: tagua-variant
+Description: Shogi support for the tagua board-game frontend
+ This package allows to play Shogi, a japanese chess-like game, from
+ tagua.
diff --git a/debian/tagua-variant-shogi.files b/debian/tagua-variant-shogi.files
new file mode 100644 (file)
index 0000000..67667f1
--- /dev/null
@@ -0,0 +1,2 @@
+usr/lib/kde4/taguashogi.so
+usr/share/kde4/services/tagua-shogi.desktop
index 67a7a3c..ed75bb7 100644 (file)
@@ -6,6 +6,7 @@
 extern "C" Repository* taguachess_initrepo(IVariantLoader*);
 extern "C" Repository* taguachess5x5_initrepo(IVariantLoader*);
 extern "C" Repository* taguacrazyhouse_initrepo(IVariantLoader*);
+extern "C" Repository* taguashogi_initrepo(IVariantLoader*);
 
 // FIXME: a KDE plugin willing to reuse a builtin one crashes
 
@@ -20,6 +21,7 @@ static const struct builtin {
   { "Chess", taguachess_initrepo, "Chess" },
   { "Chess 5x5", taguachess5x5_initrepo, "Chess" },
   { "Crazyhouse", taguacrazyhouse_initrepo, "Chess" },
+  { "Shogi", taguashogi_initrepo, "Shogi" },
 };
 
 static const struct builtin* const get_builtin(QString name) {
index 8ac4eaf..8e7de5d 100644 (file)
@@ -2,12 +2,15 @@ add_subdirectory(chess)
 add_subdirectory(chess5x5)
 add_subdirectory(crazyhouse)
 
+add_subdirectory(shogi)
+
 if(MONOLITH)
 kde4_add_library(taguavariants SHARED dummy.cpp)
 target_link_libraries(taguavariants
   taguachess
   taguachess5x5
   taguacrazyhouse
+  taguashogi
 )
 install(TARGETS taguavariants DESTINATION ${LIB_INSTALL_DIR})
 endif(MONOLITH)
diff --git a/src/variants/shogi/CMakeLists.txt b/src/variants/shogi/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ac156b5
--- /dev/null
@@ -0,0 +1,43 @@
+set(taguashogi_SRCS
+  shogi.cpp
+
+  types/king.cpp
+  types/gold.cpp
+  types/silver.cpp
+  types/knight.cpp
+  types/lance.cpp
+  types/pawn.cpp
+  types/rook.cpp
+  types/bishop.cpp
+
+  types/narigin.cpp
+  types/narikei.cpp
+  types/narikyo.cpp
+  types/tokin.cpp
+  types/dragonking.cpp
+  types/dragonhorse.cpp
+
+  behaviour.cpp
+  colors.cpp
+  moveserializer.cpp
+#  san.cpp
+  state.cpp
+  type.cpp
+  validator.cpp
+)
+
+include_directories(${CMAKE_SOURCE_DIR}/src/)
+
+if(MONOLITH)
+kde4_add_library(taguashogi SHARED ${taguashogi_SRCS})
+else(MONOLITH)
+kde4_add_plugin(taguashogi ${taguashogi_SRCS})
+endif(MONOLITH)
+
+target_link_libraries(taguashogi
+  taguacore
+  ${KDE4_KDECORE_LIBS}
+)
+
+install(TARGETS taguashogi DESTINATION ${PLUGIN_INSTALL_DIR})
+install(FILES tagua-shogi.desktop DESTINATION ${SERVICES_INSTALL_DIR})
diff --git a/src/variants/shogi/behaviour.cpp b/src/variants/shogi/behaviour.cpp
new file mode 100644 (file)
index 0000000..d24d83d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "behaviour.h"
+
+#include <core/board.h>
+#include <core/color.h>
+#include <core/move.h>
+#include <core/piece.h>
+#include <core/poolcollection.h>
+#include <core/pool.h>
+#include <core/state.h>
+
+#include <KDebug>
+
+namespace Shogi {
+
+Behaviour::Behaviour(IBehaviour* behaviour)
+: Delegators::Behaviour(behaviour)
+, m_promotionmanager(NULL)
+, m_delegator(this) { }
+
+IBehaviour* Behaviour::clone() const {
+  IBehaviour* dgate_clone;
+  Q_ASSERT(QMetaObject::invokeMethod(m_dgate_behaviour, "clone",
+                                    Q_RETURN_ARG(IBehaviour*, dgate_clone)));
+  Behaviour* b = new Behaviour(dgate_clone);
+  //FIXME: b->m_promotionmanager = m_promotionmanager->clone();
+  b->m_promotionmanager = m_promotionmanager;
+  return b;
+}
+
+void Behaviour::captureOn(IState* state, const Point& square) const {
+  Piece captured = state->board()->get(square);
+  if (captured != Piece()) {
+    if (captured.get("promoted").toBool()) {
+      if (promotionManager())
+       captured.setType(promotionManager()->getDepromotion(captured.type()));
+    }
+    state->pools()->pool(opponent(captured.color()))->insert(-1, captured);
+  }
+  m_dgate_behaviour->captureOn(state, square);
+}
+
+bool Behaviour::mayPromote(const IState* state, const Move& move) const {
+  // promoted piece cannot promote again
+  if (move.promotion())
+    return false;
+
+  // does that piece type can even promote ?
+  if (promotionManager() == NULL ||
+      promotionManager()->getPromotion(state->board()->get(move.src()).type()) == NULL)
+    return false;
+
+  // move starts or ends on the promotion rows on the other side ?
+  unsigned pzwidth;
+  Q_ASSERT(QMetaObject::invokeMethod(m_delegator, "promotionZoneWidth",
+                                    Q_RETURN_ARG(unsigned, pzwidth)));
+  return ((state->turn() == Black::self()) ?
+         (move.src().y >= state->board()->size().y - pzwidth ||
+          move.dst().y >= state->board()->size().y - pzwidth) :
+         (move.src().y < pzwidth ||
+          move.dst().y < pzwidth));
+}
+
+void Behaviour::setDelegator(IBehaviour* behaviour) {
+  Delegators::Behaviour::setDelegator(behaviour);
+  m_delegator = behaviour;
+}
+
+IBehaviour* Behaviour::clone(PromotionManager* pm) const {
+  Behaviour* b = dynamic_cast<Behaviour*>(clone()); // FIXME: cannot use static_cast ?
+  Q_ASSERT(b);
+  if (pm)
+    b->m_promotionmanager = pm;
+  return b;
+}
+
+} // namespace Shogi
diff --git a/src/variants/shogi/behaviour.h b/src/variants/shogi/behaviour.h
new file mode 100644 (file)
index 0000000..52313e5
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__BEHAVIOUR_H
+#define SHOGI__BEHAVIOUR_H
+
+#include <core/delegators/behaviour.h>
+#include <core/promotionmanager.h>
+
+class Move;
+
+namespace Shogi {
+
+class TAGUA_EXPORT Behaviour : public Delegators::Behaviour {
+Q_OBJECT
+  PromotionManager* m_promotionmanager;
+  IBehaviour* m_delegator;
+public:
+  Behaviour(IBehaviour* behaviour);
+  virtual IBehaviour* clone() const;
+  virtual void captureOn(IState* state, const Point& square) const;
+  virtual void setDelegator(IBehaviour* behaviour);
+
+public Q_SLOTS:
+  void setPromotionManager(PromotionManager* pm) {
+    m_promotionmanager = pm;
+    kDebug() << this << "m_promotionmanager=" << m_promotionmanager;
+  }
+  const PromotionManager* promotionManager() const {
+    if (!m_promotionmanager)
+      kError() << "no promotion manager";
+    return m_promotionmanager;
+  }
+
+  bool mayPromote(const IState* state, const Move& move) const;
+  unsigned promotionZoneWidth() const { return 3; }
+
+  virtual IBehaviour* clone(PromotionManager* pm) const;
+};
+
+} // namespace Shogi
+
+#endif // SHOGI__BEHAVIOUR_H
diff --git a/src/variants/shogi/colors.cpp b/src/variants/shogi/colors.cpp
new file mode 100644 (file)
index 0000000..420b67e
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "colors.h"
+
+namespace Shogi {
+
+IColor* COLORS[] = { Black::self(), White::self() };
+
+}
diff --git a/src/variants/shogi/colors.h b/src/variants/shogi/colors.h
new file mode 100644 (file)
index 0000000..45e24f3
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__COLORS_H
+#define SHOGI__COLORS_H
+
+#include <core/color.h>
+
+namespace Shogi {
+
+extern IColor* COLORS[2];
+
+}
+
+#endif // SHOGI__COLORS_H
diff --git a/src/variants/shogi/moveserializer.cpp b/src/variants/shogi/moveserializer.cpp
new file mode 100644 (file)
index 0000000..eab4be5
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include "moveserializer.h"
+
+#include <core/board.h>
+#include <core/state.h>
+
+namespace Shogi {
+
+MoveSerializer::MoveSerializer(IMoveSerializer* serializer)
+: Delegators::MoveSerializer(serializer) { }
+
+QString MoveSerializer::serialize(const Move& move, const IState* ref) const {
+  if (type() == "simple") {
+    int ysize = ref->board()->size().y;
+    QString res = move.src().toString(ysize) + move.dst().toString(ysize);
+    if (move.promotion())
+      res = res + "=" + 
+        symbol(
+          move.promotion()
+        ).toUpper();
+    return res;
+  }
+  else if (type() == "compact") {
+    return san(move, ref);
+  }
+  else if (type() == "decorated") {
+    QString res = san(move, ref);
+    res.replace('K', "{king}");
+    res.replace('G', "{gold}");
+    res.replace('S', "{silver}");
+    res.replace('N', "{knight}");
+    res.replace('L', "{lance}");
+    res.replace('B', "{bishop}");
+    res.replace('R', "{rook}");
+    res.replace('P', "{pawn}");
+    return res;
+  }
+  else {
+    return "";
+  }
+}
+
+} // namespace Shogi
diff --git a/src/variants/shogi/moveserializer.h b/src/variants/shogi/moveserializer.h
new file mode 100644 (file)
index 0000000..3e39f48
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SHOGI__MOVESERIALIZER_H
+#define SHOGI__MOVESERIALIZER_H
+
+#include <core/component.h>
+#include <core/delegators/moveserializer.h>
+
+namespace Shogi {
+class TAGUA_EXPORT MoveSerializer : public Component, public Delegators::MoveSerializer {
+public:
+  MoveSerializer(IMoveSerializer* serializer);
+
+  virtual QString serialize(const Move& move, const IState* ref) const;
+};
+
+} // namespace Shogi
+
+#endif // SHOGI__MOVESERIALIZER_H
+
diff --git a/src/variants/shogi/shogi.cpp b/src/variants/shogi/shogi.cpp
new file mode 100644 (file)
index 0000000..2af0220
--- /dev/null
@@ -0,0 +1,83 @@
+#include <core/repository.h>
+#include <core/variantloader.h>
+
+#include "behaviour.h"
+#include "colors.h"
+#include "moveserializer.h"
+#include "types.h"
+#include "state.h"
+#include "validator.h"
+
+using namespace Shogi;
+
+extern "C" KDE_EXPORT Repository*
+taguashogi_initrepo(IVariantLoader* loader) {
+  Repository* repo = new Repository;
+  Repository* chess = loader->getRepository("chess");
+  if (!chess)
+    // bail out if there is no chess variant
+    return 0;
+#if 0
+  Repository* crazyhouse = loader->getRepository("crazyhouse");
+  if (!crazyhouse)
+    // bail out if there is no crazyhouse variant
+    return 0;
+#endif
+
+  repo->addComponent("player/0", dynamic_cast<Component*>(COLORS[0]));
+  repo->addComponent("player/1", dynamic_cast<Component*>(COLORS[1]));
+  
+  repo->addComponent("type/king", King::self());
+  repo->addComponent("type/gold", Gold::self());
+  repo->addComponent("type/silver", Silver::self());
+  repo->addComponent("type/knight", Knight::self());
+  repo->addComponent("type/lance", Lance::self());
+  repo->addComponent("type/rook", Rook::self());
+  repo->addComponent("type/bishop", Bishop::self());
+  repo->addComponent("type/pawn", Pawn::self());
+
+  repo->addComponent("type/narigin", Narigin::self());
+  repo->addComponent("type/narikei", Narikei::self());
+  repo->addComponent("type/narikyo", Narikyo::self());
+  repo->addComponent("type/dragonking", DragonKing::self());
+  repo->addComponent("type/dragonhorse", DragonHorse::self());
+  repo->addComponent("type/tokin", Tokin::self());
+
+  PromotionManager* promotion_manager = new PromotionManager();
+  promotion_manager->setPromotion(Silver::self(), Narigin::self());
+  promotion_manager->setPromotion(Knight::self(), Narikei::self());
+  promotion_manager->setPromotion(Lance::self(), Narikyo::self());
+  promotion_manager->setPromotion(Rook::self(), DragonKing::self());
+  promotion_manager->setPromotion(Bishop::self(), DragonHorse::self());
+  promotion_manager->setPromotion(Pawn::self(), Tokin::self());
+  repo->addComponent("promotion_manager", promotion_manager);
+
+  // base behaviour on chess
+  Component* chess_behaviour_comp = chess->getComponent("behaviour");
+  Q_ASSERT(chess_behaviour_comp);
+  IBehaviour* behaviour_clone = NULL;
+  Q_ASSERT(QMetaObject::invokeMethod(chess_behaviour_comp, "clone",
+                                    Q_RETURN_ARG(IBehaviour*, behaviour_clone)));
+  Q_ASSERT(behaviour_clone);
+  Behaviour* behaviour = new Behaviour(behaviour_clone);
+  behaviour->setPromotionManager(promotion_manager);
+  repo->addComponent("behaviour", behaviour);
+  repo->addComponent("state", new State(behaviour, Point(9, 9)));
+
+  Validator* validator = new Validator;
+  repo->addComponent("validator", validator);
+  repo->addComponent("animator_factory", chess->getComponent("animator_factory"));
+  repo->addComponent("namer", chess->getComponent("namer"));
+  repo->addComponent("policy", chess->getComponent("policy"));
+  
+  // set move serializers
+  Repository::ComponentMap serializers = chess->listComponents("move_serializer");
+  for (Repository::ComponentMap::const_iterator it = serializers.begin(),
+       end = serializers.end(); it != end; ++it) {
+    IMoveSerializer* s = requestInterface<IMoveSerializer>(it.value());
+    if (s) repo->addComponent("move_serializer/" + it.key(), new MoveSerializer(s));
+  }
+  
+  return repo;
+}
+
diff --git a/src/variants/shogi/state.cpp b/src/variants/shogi/state.cpp
new file mode 100644 (file)
index 0000000..4745428
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "state.h"
+
+#include <core/behaviour.h>
+#include <core/move.h>
+#include <core/defaultpoolcollection.h>
+#include <core/defaultpool.h>
+
+#include "colors.h"
+#include "types.h"
+
+namespace Shogi {
+
+State::State(const IBehaviour* behaviour, 
+             const Point& size)
+: m_board(size)
+, m_behaviour(behaviour)
+, m_delegator(this) {
+  DefaultPoolCollection* c = new DefaultPoolCollection;
+  for (int i = 0; i < 2; i++)
+    c->addPool(COLORS[i], new DefaultPool(COLORS[i]));
+  m_pools = c;
+}
+
+State::State(const State& other)
+: IState()
+, DefaultState()
+, m_board(other.m_board)
+, m_flags(other.m_flags)
+, m_turn(other.m_turn)
+, m_behaviour(other.m_behaviour)
+, m_delegator(this)
+, m_pools(other.m_pools) { }
+
+State::~State() { delete m_pools; }
+
+IState* State::clone() const {
+  State* s = new State(*this);
+  s->m_pools = m_pools->clone();
+  return s;
+}
+
+#define COL(i, c) c == Black::self() ? (i) : (m_board.size().x - i - 1)
+void State::setup() {
+  for (int c = 0; c < 2; c++) {
+    IColor* color = COLORS[c];
+    int r0 = rank(0, color);
+    int r1 = rank(1, color);
+    int r2 = rank(2, color);
+    
+    for (int i = 0; i < m_board.size().x; i++) {
+      m_board.set(Point(i, r2), Piece(color, Pawn::self()));
+    }
+    m_board.set(Point(0, r0), Piece(color, Lance::self()));
+    m_board.set(Point(1, r0), Piece(color, Knight::self()));
+    m_board.set(Point(2, r0), Piece(color, Silver::self()));
+    m_board.set(Point(3, r0), Piece(color, Gold::self()));
+    m_board.set(Point(4, r0), Piece(color, King::self()));
+    m_board.set(Point(5, r0), Piece(color, Gold::self()));
+    m_board.set(Point(6, r0), Piece(color, Silver::self()));
+    m_board.set(Point(7, r0), Piece(color, Knight::self()));
+    m_board.set(Point(8, r0), Piece(color, Lance::self()));
+
+    m_board.set(Point(COL(1, color), r1), Piece(color, Bishop::self()));
+    m_board.set(Point(COL(7, color), r1), Piece(color, Rook::self()));
+  }
+  
+  m_turn = White::self();
+}
+#undef COL
+
+const Board* State::board() const {
+  return &m_board;
+}
+
+Board* State::board() {
+  return &m_board;
+}
+  
+const IColor* State::turn() const {
+  return m_turn;
+}
+  
+void State::setTurn(const IColor* turn) {
+  m_turn = turn;
+}
+  
+bool State::equals(IState* other) const {
+  return m_board.equals(other->board()) &&
+         m_turn == other->turn() &&
+         m_flags == *other->flags();
+}
+
+void State::assign(const IState* other) {
+  m_board = *other->board();
+  m_turn = other->turn();
+  m_flags = *other->flags();
+
+  const IPoolCollection* pools = other->pools();
+  if (pools) {
+    delete m_pools;
+    m_pools = pools->clone();
+  }
+}
+
+void State::move(const Move& m) {
+  if (m.drop() != Piece()) {
+    //const Piece captured = board()->get(m.dst());
+    board()->set(m.dst(), m.drop());
+    pools()->pool(m.drop().color())->take(m.drop());
+
+#if 0
+    // handle capturing by drop: some variants could use it
+    if (captured != Piece()) {
+      if (captured.get("promoted").toBool()) {
+        captured.setType(pawn);
+      }
+      pools()->pool(behaviour()->opponent(captured.color()))
+             ->insert(-1, captured);
+    }
+#endif
+  } else {
+    const Piece piece = m_board.get(m.src());
+    if (piece == Piece()) return;
+
+    Point captureSquare = behaviour()->captureSquare(this, m);
+    behaviour()->captureOn(m_delegator, captureSquare);
+    behaviour()->move(m_delegator, m);
+
+    const IType* promotion_type = m.promotion();
+
+    if (promotion_type != 0) {
+      m_board.set(m.dst(), Piece(piece.color(), promotion_type));
+    }
+  }
+
+  behaviour()->advanceTurn(m_delegator);
+}
+
+const TaguaObject* State::flags() const { return &m_flags; }
+TaguaObject* State::flags() { return &m_flags; }
+
+int State::rank(int n, const IColor* turn) const {
+  if (turn == White::self())
+    return m_board.size().y - n - 1;
+  else
+    return n;
+}
+
+IPoolCollection* State::pools() { return m_pools; }
+const IPoolCollection* State::pools() const { return m_pools; }
+
+const IBehaviour* State::behaviour() const { return m_behaviour; }
+
+void State::setDelegator(IState* delegator) {
+  m_delegator = delegator;
+}
+
+IState* State::clone(const IBehaviour* behaviour,
+                    const Point& size) const {
+  return new State(behaviour, size);
+}
+
+} // namespace Shogi
diff --git a/src/variants/shogi/state.h b/src/variants/shogi/state.h
new file mode 100644 (file)
index 0000000..6a26fd5
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__STATE_H
+#define SHOGI__STATE_H
+
+#include <core/board.h>
+#include <core/component.h>
+#include <core/defaultstate.h>
+#include <core/piece.h>
+#include <core/taguaobject.h>
+
+/**
+  * @brief Namespace holding Shogi components.
+  */
+namespace Shogi {
+
+class State : public DefaultState {
+Q_OBJECT
+  Board m_board;
+  TaguaObject m_flags;
+  const IColor* m_turn;
+  const IBehaviour* m_behaviour;
+  IState* m_delegator;
+  IPoolCollection* m_pools;
+protected:
+  State(const State&);
+public:
+  State(const IBehaviour* behaviour, 
+        const Point& size);
+  virtual ~State();
+public:
+  virtual IState* clone() const;
+  
+  virtual void setup();
+  
+  virtual const Board* board() const;
+  virtual Board* board();
+  
+  virtual const IColor* turn() const;
+  
+  virtual void setTurn(const IColor* turn);
+  
+  virtual bool equals(IState* other) const;
+  
+  virtual void assign(const IState* other);
+
+  virtual void move(const Move& move);
+  
+  virtual TaguaObject* flags();
+  virtual const TaguaObject* flags() const;
+  
+  virtual int rank(int n, const IColor* turn) const;
+
+  virtual const IPoolCollection* pools() const;
+  virtual IPoolCollection* pools();
+  
+  virtual const IBehaviour* behaviour() const;
+  
+  virtual void setDelegator(IState* delegator);
+public Q_SLOTS:
+  virtual IState* clone(const IBehaviour* behaviour,
+                       const Point& size) const;
+};
+
+} // namespace Shogi
+
+#endif // SHOGI__STATE_H
+
diff --git a/src/variants/shogi/tagua-shogi.desktop b/src/variants/shogi/tagua-shogi.desktop
new file mode 100644 (file)
index 0000000..6d61ae8
--- /dev/null
@@ -0,0 +1,20 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Shogi
+Comment=The Game of Shogi (Japanese Chess)
+Icon=tagua
+Type=Service
+ServiceTypes=Tagua/Variant
+
+X-KDE-Library=taguashogi
+X-KDE-PluginInfo-Author=Paolo Capriotti
+X-KDE-PluginInfo-Email=p.capriotti@gmail.com
+X-KDE-PluginInfo-Name=shogi
+X-KDE-PluginInfo-Version=0.5.1
+X-KDE-PluginInfo-Website=http://www.tagua-project.org
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=true
+
+X-Tagua-Proxy=Shogi
+X-Tagua-Hidden=false
diff --git a/src/variants/shogi/type.cpp b/src/variants/shogi/type.cpp
new file mode 100644 (file)
index 0000000..a4ca0d6
--- /dev/null
@@ -0,0 +1,38 @@
+#include "type.h"
+
+#include <core/behaviour.h>
+#include <core/promotionmanager.h>
+#include <core/state.h>
+#include <core/move.h>
+
+#include <KDebug>
+
+namespace Shogi {
+
+bool Type::canMove(const Piece& piece, const Piece& target,
+                    Move& move, const IState* state) const {
+  bool valid = DefaultType::canMove(piece, target, move, state);
+  if (!valid)
+    return false;
+
+  IBehaviour* behaviour = const_cast<IBehaviour*>(state->behaviour());
+  Q_ASSERT(behaviour);
+  bool may_promote;
+  Q_ASSERT(QMetaObject::invokeMethod(behaviour, "mayPromote",
+                                    Q_RETURN_ARG(bool, may_promote),
+                                    Q_ARG(const IState*, state),
+                                    Q_ARG(const Move, move))); // FIXME: Move& ?
+  if (may_promote) {
+    move.setType("promotion");
+    const PromotionManager* pm;
+    Q_ASSERT(QMetaObject::invokeMethod(behaviour, "promotionManager",
+                                      Q_RETURN_ARG(const PromotionManager*, pm)));
+    const IType* newtype = pm->getPromotion(piece.type());
+    kDebug() << "promoting to" << newtype->name();
+    move.setPromotion(newtype);
+  }
+
+  return true;
+}
+
+} // namespace Shogi
diff --git a/src/variants/shogi/type.h b/src/variants/shogi/type.h
new file mode 100644 (file)
index 0000000..3ff0ad1
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+  Copyright (c) 2008 Yann Dirson <ydirson@altern.org>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPE_H
+#define SHOGI__TYPE_H
+
+#include <core/defaulttype.h>
+
+namespace Shogi {
+
+class TAGUA_EXPORT Type : public DefaultType {
+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 // SHOGI__TYPE_H
diff --git a/src/variants/shogi/types.h b/src/variants/shogi/types.h
new file mode 100644 (file)
index 0000000..d89432f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES_H
+#define SHOGI__TYPES_H
+
+// include all shogi types
+#include "types/king.h"
+#include "types/gold.h"
+#include "types/silver.h"
+#include "types/knight.h"
+#include "types/lance.h"
+#include "types/rook.h"
+#include "types/bishop.h"
+#include "types/pawn.h"
+
+#include "types/narigin.h"
+#include "types/narikei.h"
+#include "types/narikyo.h"
+#include "types/dragonking.h"
+#include "types/dragonhorse.h"
+#include "types/tokin.h"
+
+#endif // SHOGI__TYPES_H
diff --git a/src/variants/shogi/types/bishop.cpp b/src/variants/shogi/types/bishop.cpp
new file mode 100644 (file)
index 0000000..bf39caa
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+  Copyright (c) 2008 Yann Dirson <ydirson@altern.org>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "bishop.h"
+
+namespace Shogi {
+
+Bishop::Bishop() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 0 },
+    { 1,  1, 0 },
+    {-1, -1, 0 },
+    { 1, -1, 0 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Bishop::name() const { return "bishop"; }
+
+const std::vector<MoveDefinition> * const Bishop::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Bishop::index() const { return 35; }
+
+Bishop* Bishop::self() {
+  static Bishop s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/bishop.h b/src/variants/shogi/types/bishop.h
new file mode 100644 (file)
index 0000000..f9af866
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__BISHOP_H
+#define SHOGI__TYPES__BISHOP_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Bishop : public Component, public Type {
+Q_OBJECT
+  Bishop();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Bishop* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__BISHOP_H
diff --git a/src/variants/shogi/types/dragonhorse.cpp b/src/variants/shogi/types/dragonhorse.cpp
new file mode 100644 (file)
index 0000000..0640ab3
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "dragonhorse.h"
+
+namespace Shogi {
+
+DragonHorse::DragonHorse() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 0 },
+    { 0,  1, 1 },
+    { 1,  1, 0 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    {-1, -1, 0 },
+    { 0, -1, 1 },
+    { 1, -1, 0 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString DragonHorse::name() const { return "dragonhorse"; }
+
+const std::vector<MoveDefinition> * const DragonHorse::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int DragonHorse::index() const { return 35; }
+
+DragonHorse* DragonHorse::self() {
+  static DragonHorse s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/dragonhorse.h b/src/variants/shogi/types/dragonhorse.h
new file mode 100644 (file)
index 0000000..dacfe7d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__DRAGONHORSE_H
+#define SHOGI__TYPES__DRAGONHORSE_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT DragonHorse : public Component, public Type {
+Q_OBJECT
+  DragonHorse();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static DragonHorse* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__DRAGONHORSE_H
diff --git a/src/variants/shogi/types/dragonking.cpp b/src/variants/shogi/types/dragonking.cpp
new file mode 100644 (file)
index 0000000..ca11458
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "dragonking.h"
+
+namespace Shogi {
+
+DragonKing::DragonKing() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 0 },
+    { 1,  1, 1 },
+    {-1,  0, 0 },
+    { 1,  0, 0 },
+    {-1, -1, 1 },
+    { 0, -1, 0 },
+    { 1, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString DragonKing::name() const { return "dragonking"; }
+
+const std::vector<MoveDefinition> * const DragonKing::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int DragonKing::index() const { return 50; }
+
+DragonKing* DragonKing::self() {
+  static DragonKing s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/dragonking.h b/src/variants/shogi/types/dragonking.h
new file mode 100644 (file)
index 0000000..936e52e
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__DRAGONKING_H
+#define SHOGI__TYPES__DRAGONKING_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT DragonKing : public Component, public Type {
+Q_OBJECT
+  DragonKing();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static DragonKing* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__DRAGONKING_H
diff --git a/src/variants/shogi/types/gold.cpp b/src/variants/shogi/types/gold.cpp
new file mode 100644 (file)
index 0000000..cd891f0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "gold.h"
+
+namespace Shogi {
+
+Gold::Gold() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    { 0, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Gold::name() const { return "gold"; }
+
+const std::vector<MoveDefinition> * const Gold::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Gold::index() const { return 10000; }
+
+Gold* Gold::self() {
+  static Gold s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/gold.h b/src/variants/shogi/types/gold.h
new file mode 100644 (file)
index 0000000..2ea0f06
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__GOLD_H
+#define SHOGI__TYPES__GOLD_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Gold : public Component, public Type {
+Q_OBJECT
+  Gold();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Gold* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__GOLD_H
diff --git a/src/variants/shogi/types/king.cpp b/src/variants/shogi/types/king.cpp
new file mode 100644 (file)
index 0000000..a13ed6e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "king.h"
+
+namespace Shogi {
+
+King::King() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    {-1, -1, 1 },
+    { 0, -1, 1 },
+    { 1, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString King::name() const { return "king"; }
+
+const std::vector<MoveDefinition> * const King::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int King::index() const { return 10000; }
+
+King* King::self() {
+  static King s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/king.h b/src/variants/shogi/types/king.h
new file mode 100644 (file)
index 0000000..d337285
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__KING_H
+#define SHOGI__TYPES__KING_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT King : public Component, public Type {
+Q_OBJECT
+  King();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static King* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__KING_H
diff --git a/src/variants/shogi/types/knight.cpp b/src/variants/shogi/types/knight.cpp
new file mode 100644 (file)
index 0000000..7a95472
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "knight.h"
+
+namespace Shogi {
+
+Knight::Knight() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  2, 1 },
+    { 1,  2, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Knight::name() const { return "knight"; }
+
+const std::vector<MoveDefinition> * const Knight::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Knight::index() const { return 30; }
+
+Knight* Knight::self() {
+  static Knight s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/knight.h b/src/variants/shogi/types/knight.h
new file mode 100644 (file)
index 0000000..669e917
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__KNIGHT_H
+#define SHOGI__TYPES__KNIGHT_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Knight : public Component, public Type {
+Q_OBJECT
+  Knight();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Knight* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__KNIGHT_H
diff --git a/src/variants/shogi/types/lance.cpp b/src/variants/shogi/types/lance.cpp
new file mode 100644 (file)
index 0000000..e894931
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "lance.h"
+
+namespace Shogi {
+
+Lance::Lance() {
+  MoveDefinition movesDefinition[] = {
+    { 0,  1, 0 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Lance::name() const { return "lance"; }
+
+const std::vector<MoveDefinition> * const Lance::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Lance::index() const { return 10000; }
+
+Lance* Lance::self() {
+  static Lance s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/lance.h b/src/variants/shogi/types/lance.h
new file mode 100644 (file)
index 0000000..f8ee8df
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__LANCE_H
+#define SHOGI__TYPES__LANCE_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Lance : public Component, public Type {
+Q_OBJECT
+  Lance();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Lance* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__LANCE_H
diff --git a/src/variants/shogi/types/narigin.cpp b/src/variants/shogi/types/narigin.cpp
new file mode 100644 (file)
index 0000000..4009c5b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "narigin.h"
+
+namespace Shogi {
+
+Narigin::Narigin() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    { 0, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Narigin::name() const { return "narigin"; }
+
+const std::vector<MoveDefinition> * const Narigin::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Narigin::index() const { return 10000; }
+
+Narigin* Narigin::self() {
+  static Narigin s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/narigin.h b/src/variants/shogi/types/narigin.h
new file mode 100644 (file)
index 0000000..24c93db
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__NARIGIN_H
+#define SHOGI__TYPES__NARIGIN_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Narigin : public Component, public Type {
+Q_OBJECT
+  Narigin();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Narigin* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__NARIGIN_H
diff --git a/src/variants/shogi/types/narikei.cpp b/src/variants/shogi/types/narikei.cpp
new file mode 100644 (file)
index 0000000..0548178
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "narikei.h"
+
+namespace Shogi {
+
+Narikei::Narikei() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    { 0, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Narikei::name() const { return "narikei"; }
+
+const std::vector<MoveDefinition> * const Narikei::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Narikei::index() const { return 30; }
+
+Narikei* Narikei::self() {
+  static Narikei s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/narikei.h b/src/variants/shogi/types/narikei.h
new file mode 100644 (file)
index 0000000..66604ec
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__NARIKEI_H
+#define SHOGI__TYPES__NARIKEI_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Narikei : public Component, public Type {
+Q_OBJECT
+  Narikei();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Narikei* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__NARIKEI_H
diff --git a/src/variants/shogi/types/narikyo.cpp b/src/variants/shogi/types/narikyo.cpp
new file mode 100644 (file)
index 0000000..152b81f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "narikyo.h"
+
+namespace Shogi {
+
+Narikyo::Narikyo() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    { 0, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Narikyo::name() const { return "narikyo"; }
+
+const std::vector<MoveDefinition> * const Narikyo::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Narikyo::index() const { return 10000; }
+
+Narikyo* Narikyo::self() {
+  static Narikyo s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/narikyo.h b/src/variants/shogi/types/narikyo.h
new file mode 100644 (file)
index 0000000..c0dd7aa
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__NARIKYO_H
+#define SHOGI__TYPES__NARIKYO_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Narikyo : public Component, public Type {
+Q_OBJECT
+  Narikyo();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Narikyo* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__NARIKYO_H
diff --git a/src/variants/shogi/types/pawn.cpp b/src/variants/shogi/types/pawn.cpp
new file mode 100644 (file)
index 0000000..42efe64
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "pawn.h"
+
+namespace Shogi {
+
+Pawn::Pawn() {
+  MoveDefinition movesDefinition[] = {
+    { 0,  1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Pawn::name() const { return "pawn"; }
+
+const std::vector<MoveDefinition> * const Pawn::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Pawn::index() const { return 10; }
+
+Pawn* Pawn::self() {
+  static Pawn s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/pawn.h b/src/variants/shogi/types/pawn.h
new file mode 100644 (file)
index 0000000..72ea98a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__PAWN_H
+#define SHOGI__TYPES__PAWN_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Pawn : public Component, public Type {
+Q_OBJECT
+  Pawn();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Pawn* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__PAWN_H
diff --git a/src/variants/shogi/types/rook.cpp b/src/variants/shogi/types/rook.cpp
new file mode 100644 (file)
index 0000000..e7391a9
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "rook.h"
+
+namespace Shogi {
+
+Rook::Rook() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  0, 0 },
+    { 1,  0, 0 },
+    { 0,  1, 0 },
+    { 0, -1, 0 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Rook::name() const { return "rook"; }
+
+const std::vector<MoveDefinition> * const Rook::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Rook::index() const { return 50; }
+
+Rook* Rook::self() {
+  static Rook s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/rook.h b/src/variants/shogi/types/rook.h
new file mode 100644 (file)
index 0000000..6c3b14d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__ROOK_H
+#define SHOGI__TYPES__ROOK_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Rook : public Component, public Type {
+Q_OBJECT
+  Rook();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Rook* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__ROOK_H
diff --git a/src/variants/shogi/types/silver.cpp b/src/variants/shogi/types/silver.cpp
new file mode 100644 (file)
index 0000000..b7bd073
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "silver.h"
+
+namespace Shogi {
+
+Silver::Silver() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1, -1, 1 },
+    { 1, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Silver::name() const { return "silver"; }
+
+const std::vector<MoveDefinition> * const Silver::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Silver::index() const { return 10000; }
+
+Silver* Silver::self() {
+  static Silver s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/silver.h b/src/variants/shogi/types/silver.h
new file mode 100644 (file)
index 0000000..af02bf1
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__SILVER_H
+#define SHOGI__TYPES__SILVER_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Silver : public Component, public Type {
+Q_OBJECT
+  Silver();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Silver* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__SILVER_H
diff --git a/src/variants/shogi/types/tokin.cpp b/src/variants/shogi/types/tokin.cpp
new file mode 100644 (file)
index 0000000..c6fda7b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#include "tokin.h"
+
+namespace Shogi {
+
+Tokin::Tokin() {
+  MoveDefinition movesDefinition[] = {
+    {-1,  1, 1 },
+    { 0,  1, 1 },
+    { 1,  1, 1 },
+    {-1,  0, 1 },
+    { 1,  0, 1 },
+    { 0, -1, 1 },
+  };
+
+  for (unsigned i = 0; i < sizeof(movesDefinition)/sizeof(movesDefinition[0]); i++)
+    m_moveDefinitions.push_back(movesDefinition[i]);
+}
+
+QString Tokin::name() const { return "tokin"; }
+
+const std::vector<MoveDefinition> * const Tokin::movesDefinitions() const {
+  return &m_moveDefinitions;
+}
+
+int Tokin::index() const { return 10; }
+
+Tokin* Tokin::self() {
+  static Tokin s_instance;
+  return &s_instance;
+}
+
+}
diff --git a/src/variants/shogi/types/tokin.h b/src/variants/shogi/types/tokin.h
new file mode 100644 (file)
index 0000000..2a61d6f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__TYPES__TOKIN_H
+#define SHOGI__TYPES__TOKIN_H
+
+#include <core/component.h>
+#include "../type.h"
+
+namespace Shogi {
+
+class TAGUA_EXPORT Tokin : public Component, public Type {
+Q_OBJECT
+  Tokin();
+public:
+  virtual QString name() const;
+  virtual const std::vector<MoveDefinition> * const movesDefinitions() const;
+  virtual int index() const;
+  static Tokin* self();
+private:
+  std::vector<MoveDefinition> m_moveDefinitions;
+};
+
+}
+
+#endif // SHOGI__TYPES__TOKIN_H
diff --git a/src/variants/shogi/validator.cpp b/src/variants/shogi/validator.cpp
new file mode 100644 (file)
index 0000000..ba6267a
--- /dev/null
@@ -0,0 +1,157 @@
+#include "validator.h"
+#include <memory>
+#include <core/behaviour.h>
+#include <core/board.h>
+#include <core/move.h>
+#include <core/poolcollection.h>
+#include <core/pool.h>
+#include <core/state.h>
+#include <core/type.h>
+#include "colors.h"
+#include "types.h"
+
+namespace Shogi {
+
+Validator::Validator() : m_delegator(this) { }
+
+bool Validator::pseudolegal(const IState* state, Move& move) const {
+  // add drop information to move, if missing
+  if (move.drop() == Piece() &&
+      move.pool() && move.index() != -1) {
+    move.setDrop(state->pools()->pool(move.pool())->get(move.index()));
+  }
+
+  Piece dropped = move.drop();
+  if (dropped == Piece()) {
+    if (!state->board()->valid(move.src())) return false;
+    if (!state->board()->valid(move.dst())) return false;
+  
+    const Piece piece = state->board()->get(move.src());
+    if (piece == Piece()) return false;
+  
+    const IBehaviour* behaviour = state->behaviour();
+    if (!behaviour) return false;
+  
+    const IColor* thisTurn = piece.color();
+    if (state->turn() != thisTurn) return false;
+  
+    const Piece target = state->board()->get(move.dst());
+    if (target.color() == piece.color())
+      return false;
+    if (!piece.type()->canMove(piece, target, move, state))
+      return false;
+
+#if 0
+    if (move.type() == "promotion") {
+      const IType* promotionType = move.promotion();
+      if (promotionType != Queen::self() &&
+         promotionType != Bishop::self() &&
+         promotionType != Rook::self() &&
+         promotionType != Knight::self()) return false;
+    }
+#endif
+  } else {
+    // dropping on a valid square
+    if (!state->board()->valid(move.dst()))
+      return false;
+
+    // cannot drop on occupied squares
+    if (state->board()->get(move.dst()) != Piece())
+      return false;
+
+    // cannot drop on a place where piece would be stuck
+    if (stuckPiece(state, dropped, move.dst()))
+      return false;
+
+    // cannot drop a pawn in a column with already a pawn of same color
+    if (dropped.type() == Pawn::self()) {
+      for (int i = 0; i < state->board()->size().y; i++) {
+        const Piece other = state->board()->get(Point(move.dst().x, i));
+        if (other.type() == Pawn::self() &&
+            other.color() == state->turn() &&
+            !other.get("promoted").toBool())
+          return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool Validator::legal(const IState* state, Move& move) const {
+  // do not check a move more than once
+  if (!move.type().isEmpty()) return true;
+
+  if (!m_delegator->pseudolegal(state, move))
+    return false;
+    
+  const IBehaviour* behaviour = state->behaviour();
+  if (!behaviour) return false;
+    
+  const IColor* turn = m_delegator->mover(state, move);
+  
+  std::auto_ptr<IState> tmp(state->clone());
+  tmp->move(move);
+  
+  Point kingPos = tmp->board()->find(Piece(turn, King::self()));
+  
+  if (kingPos == Point::invalid())
+    return false;
+    
+  if (m_delegator->attacks(tmp.get(), behaviour->opponent(turn), kingPos))
+    return false;
+    
+  // set move type as normal, if not already set    
+  if (move.type().isEmpty()) move.setType("normal");
+  return true;
+}
+
+// FIXME: move this logic into Piece classes ?
+bool Validator::stuckPiece(const IState* state,
+                          const Piece& piece, const Point& p) const {
+  const IBehaviour* behaviour = state->behaviour();
+
+  if (piece.type() == Pawn::self() || piece.type() == Lance::self()) {
+    return p.y == state->rank(0, behaviour->opponent(piece.color()));
+  }
+  else if (piece.type() == Knight::self()) {
+    int rank = state->rank(0, behaviour->opponent(piece.color()));
+    return p.y == rank || p.y == rank - behaviour->direction(piece.color()).y;
+  }
+  else {
+    return false;
+  }
+}
+
+bool Validator::attacks(const IState* state, const IColor* player,
+                        const Point& square, const Piece& target_) const {
+  Piece target;
+  if (target_ != Piece())
+    target = target_;
+  else
+    target = state->board()->get(square);
+
+  for (int i = 0; i < state->board()->size().x; i++) {
+    for (int j = 0; j < state->board()->size().y; j++) {
+      const Point p(i, j);
+      const Piece piece = state->board()->get(p);
+      Move move(p, square);
+      if (piece != Piece() &&
+          piece.color() == player &&
+          piece.type()->canMove(piece, target, move, state))
+        return true;
+    }
+  }
+  return false;
+}
+
+const IColor* Validator::mover(const IState* state, const Move& move) const {
+  return state->board()->get(move.src()).color();
+}
+
+void Validator::setDelegator(IValidator* delegator) {
+  m_delegator = delegator;
+}
+
+}
+
diff --git a/src/variants/shogi/validator.h b/src/variants/shogi/validator.h
new file mode 100644 (file)
index 0000000..6281cd8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+  Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
+            (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+*/
+
+#ifndef SHOGI__VALIDATOR_H
+#define SHOGI__VALIDATOR_H
+
+#include <core/component.h>
+#include <core/validator.h>
+
+namespace Shogi {
+
+class Validator : public Component, public IValidator {
+Q_OBJECT
+  IValidator* m_delegator;
+protected:
+  virtual bool stuckPiece(const IState* state,
+                         const Piece& piece, const Point& p) const;
+public:
+  Validator();
+
+  virtual bool pseudolegal(const IState* state, Move& move) const;
+
+  virtual bool legal(const IState* state, Move& move) const;
+
+  virtual bool attacks(const IState* state, const IColor* player,
+                       const Point& square, const Piece& target = Piece()) const;
+                       
+  virtual const IColor* mover(const IState* state, const Move& move) const;
+  
+  virtual void setDelegator(IValidator* validator);
+};
+
+}
+
+#endif // SHOGI__VALIDATOR_H
+