From e11317b1369864c230c4c5008598b3a5edeacc6b Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Mon, 6 Aug 2007 23:53:23 +0200 Subject: [PATCH] Add Sho Shogi variant. Variant specificities are: - no drops - new piece Drunken Elephant, promoting to Crown Prince - game is not mate as long as one of King and Crown Prince can still move Signed-off-by: Yann Dirson Signed-off-by: Paolo Capriotti Signed-off-by: Yann Dirson --- data/scripts/shogi_themelib.lua | 8 +++ data/themes/pieces/ShogiTTF/theme.desktop | 2 +- data/themes/pieces/ShogiTTF/theme.lua | 12 +++++ data/themes/squares/Default/theme_shogi.desktop | 2 +- src/CMakeLists.txt | 2 + src/hlvariant/sho-shogi/gamestate.h | 66 +++++++++++++++++++++++ src/hlvariant/sho-shogi/legalitycheck.h | 70 +++++++++++++++++++++++++ src/hlvariant/sho-shogi/variant.cpp | 32 +++++++++++ src/hlvariant/sho-shogi/variant.h | 58 ++++++++++++++++++++ src/hlvariant/shogi/legalitycheck.h | 8 +++ src/hlvariant/shogi/piece.cpp | 4 ++ src/hlvariant/shogi/piece.h | 4 ++ src/variants.cpp | 2 + 13 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 src/hlvariant/sho-shogi/gamestate.h create mode 100644 src/hlvariant/sho-shogi/legalitycheck.h create mode 100644 src/hlvariant/sho-shogi/variant.cpp create mode 100644 src/hlvariant/sho-shogi/variant.h diff --git a/data/scripts/shogi_themelib.lua b/data/scripts/shogi_themelib.lua index 907cb10..8907d5e 100644 --- a/data/scripts/shogi_themelib.lua +++ b/data/scripts/shogi_themelib.lua @@ -97,6 +97,9 @@ shogichars["narigin"] = {"0x5168", {"0x6210", "0x9280"}} shogichars["narikei"] = {"0x572d", {"0x6210", "0x6842"}} shogichars["narikyo"] = {"0x674f", {"0x6210", "0x9999"}} shogichars["tokin"] = {"0x3068", {"0x3068", "0x91d1"}} +-- Sho Shogi +shogichars["drunken elephant"] = {"0x9154", {"0x9154", "0x8c61"}} +shogichars["crown prince"] = {"0x592a", {"0x592a", "0x5b50"}} -- Chess compatibility (part of Dai Shogi) shogichars["free king"] = {"0x5954", {"0x5954", "0x738b"}} @@ -122,6 +125,11 @@ shogimoves_knight = {{-1,2},{1,2}} shogimoves_lance = {{0,1,1}} shogimoves_pawn = {{0,1}} +shogimoves_drunken_elephant = { + {-1,1},{0,1},{1,1}, + {-1,0},{1,0}, + {-1,-1},{1,-1}} + shogimoves_freeking = { {-1,1,1},{0,1,1},{1,1,1}, {-1,0,1},{1,0,1}, diff --git a/data/themes/pieces/ShogiTTF/theme.desktop b/data/themes/pieces/ShogiTTF/theme.desktop index 7af5f41..f705218 100644 --- a/data/themes/pieces/ShogiTTF/theme.desktop +++ b/data/themes/pieces/ShogiTTF/theme.desktop @@ -4,4 +4,4 @@ Name=ShogiTTF Type=Application Comment=Shogi TTF theme X-Tagua-ThemeType=Pieces -X-Tagua-Variants=Chess,Shogi[default] +X-Tagua-Variants=Chess,Shogi[default],LargeShogi[default] diff --git a/data/themes/pieces/ShogiTTF/theme.lua b/data/themes/pieces/ShogiTTF/theme.lua index 3079dfb..63925b6 100644 --- a/data/themes/pieces/ShogiTTF/theme.lua +++ b/data/themes/pieces/ShogiTTF/theme.lua @@ -108,6 +108,18 @@ theme.white_pawn = shogi_piece(shogichars["pawn"][2], shogichars["pawn"][1] theme.white_p_pawn = 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.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) + -- This is part of Dai Shohi theme.black_freeking = shogi_piece(shogichars["free king"][2], shogichars["free king"][1], diff --git a/data/themes/squares/Default/theme_shogi.desktop b/data/themes/squares/Default/theme_shogi.desktop index 6c98e38..9c872ff 100644 --- a/data/themes/squares/Default/theme_shogi.desktop +++ b/data/themes/squares/Default/theme_shogi.desktop @@ -4,4 +4,4 @@ Name=Shogi Type=Application Comment=Shogi-like squares X-Tagua-ThemeType=Squares -X-Tagua-Variants=Shogi[default],Chess +X-Tagua-Variants=Shogi[default],LargeShogi[default],Chess diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f744348..53b892e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,8 @@ set(tagua_SRC hlvariant/minishogi/variant.cpp + hlvariant/sho-shogi/variant.cpp + animationfactory.cpp constrainedtext.cpp movelist.cpp diff --git a/src/hlvariant/sho-shogi/gamestate.h b/src/hlvariant/sho-shogi/gamestate.h new file mode 100644 index 0000000..a655f97 --- /dev/null +++ b/src/hlvariant/sho-shogi/gamestate.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + (c) 2007 Yann Dirson + + 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 HLVARIANT__SHOSHOGI__GAMESTATE_H +#define HLVARIANT__SHOSHOGI__GAMESTATE_H + +#include "../shogi/gamestate.h" +#include "../shogi/piece.h" + +namespace HLVariant { +namespace ShoShogi { + +template + class GameState: + public Shogi::GameState<_Board, _Move> { +public: + virtual void setup(); +}; + +// IMPLEMENTATION + +#define MS_COL(i, c) c == Shogi::Piece::BLACK ? (i) : \ + (Shogi::GameState::board().size().x - i - 1) +#define MS_ROW(i, c) rank + i * Shogi::GameState::direction(color).y +#define MS_PIECE(x,y,p) Shogi::GameState::board().set(Point(MS_COL(x, c), MS_ROW(y, c)), \ + Shogi::Piece(color, p)) +template +void GameState::setup() { + for (int c = 0; c < 2; c++) { + typename Shogi::Piece::Color color = static_cast(c); + int rank = Shogi::GameState::startingRank(color); + + for (int i = 0; i < Shogi::GameState::board().size().x; i++) { + MS_PIECE(i, 2, Shogi::Piece::PAWN); + } + MS_PIECE(0, 0, Shogi::Piece::LANCE); + MS_PIECE(1, 0, Shogi::Piece::KNIGHT); + MS_PIECE(2, 0, Shogi::Piece::SILVER); + MS_PIECE(3, 0, Shogi::Piece::GOLD); + MS_PIECE(4, 0, Shogi::Piece::KING); + MS_PIECE(5, 0, Shogi::Piece::GOLD); + MS_PIECE(6, 0, Shogi::Piece::SILVER); + MS_PIECE(7, 0, Shogi::Piece::KNIGHT); + MS_PIECE(8, 0, Shogi::Piece::LANCE); + + MS_PIECE(1, 1, Shogi::Piece::BISHOP); + MS_PIECE(4, 1, Shogi::Piece::DRUNKEN_ELEPHANT); + MS_PIECE(7, 1, Shogi::Piece::ROOK); + } +} +#undef MS_PIECE +#undef MS_ROW +#undef MS_COL + +} // namespace ShoShogi +} // namespace HLVariant + +#endif // HLVARIANT__SHOSHOGI__GAMESTATE_H diff --git a/src/hlvariant/sho-shogi/legalitycheck.h b/src/hlvariant/sho-shogi/legalitycheck.h new file mode 100644 index 0000000..a11fd07 --- /dev/null +++ b/src/hlvariant/sho-shogi/legalitycheck.h @@ -0,0 +1,70 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + + 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 HLVARIANT__SHOSHOGI__LEGALITYCHECK_H +#define HLVARIANT__SHOSHOGI__LEGALITYCHECK_H + +#include "interactiontype.h" +#include "../shogi/legalitycheck.h" + +namespace HLVariant { +namespace ShoShogi { + +template +class LegalityCheck: public Shogi::LegalityCheck<_GameState> { + typedef Shogi::LegalityCheck<_GameState> Base; +public: + typedef _GameState GameState; + typedef typename GameState::Board Board; + typedef typename Board::Piece Piece; + typedef typename GameState::Move Move; + + LegalityCheck(const GameState& state); + bool legal(Move& move) const; + virtual InteractionType droppable(const TurnTest&, int index) const; +}; + +// IMPLEMENTATION + +template +LegalityCheck::LegalityCheck(const GameState& state) +: Base(state) { } + +template +InteractionType LegalityCheck::droppable(const TurnTest&, int) const { + return NoAction; +} + +template +bool LegalityCheck::legal(Move& move) const { + if (!pseudolegal(move)) + return false; + + GameState tmp(Base::m_state); + tmp.move(move); + + // find king and prince positions + Point king_pos = tmp.board().find(Piece(Base::m_state.turn(), Piece::KING)); + Point prince_pos = tmp.board().find(Piece(Base::m_state.turn(), Piece::DRUNKEN_ELEPHANT, true)); + + // check if the king and prince can be captured + if ((canBeCaptured(tmp, king_pos) && canBeCaptured(tmp, prince_pos)) || + (canBeCaptured(tmp, king_pos) && !prince_pos.valid()) || + (canBeCaptured(tmp, prince_pos) && !king_pos.valid()) || + (!prince_pos.valid() && !king_pos.valid())) + return false; + + return true; +} + +} // namespace ShoShogi +} // namespace HLVariant + +#endif // HLVARIANT__SHOSHOGI__LEGALITYCHECK_H diff --git a/src/hlvariant/sho-shogi/variant.cpp b/src/hlvariant/sho-shogi/variant.cpp new file mode 100644 index 0000000..0858ac5 --- /dev/null +++ b/src/hlvariant/sho-shogi/variant.cpp @@ -0,0 +1,32 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + (c) 2007 Yann Dirson + + 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 "variant.h" +#include "../tagua_wrapped.h" + +namespace HLVariant { +namespace ShoShogi { + +const char* Variant::m_name = "Sho Shogi"; +const char* Variant::m_theme_proxy = "LargeShogi"; + +void Variant::setupMove(NormalUserMove& m) const { + m.promotionType = m_actions.promotion() ? 0 : -1; +} + +ActionCollection* Variant::actions() { + return &m_actions; +} + +DEFINE_VARIANT_FACTORY(); + +} // namespace ShoShogi +} // namespace HLVariant diff --git a/src/hlvariant/sho-shogi/variant.h b/src/hlvariant/sho-shogi/variant.h new file mode 100644 index 0000000..891842d --- /dev/null +++ b/src/hlvariant/sho-shogi/variant.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2007 Paolo Capriotti + (c) 2007 Maurizio Monge + (c) 2007 Yann Dirson + + 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 HLVARIANT__SHOSHOGI__VARIANT_H +#define HLVARIANT__SHOSHOGI__VARIANT_H + +#include "../shogi/piece.h" +#include "../shogi/shogiban.h" +#include "../chess/move.h" +#include "../crazyhouse/move.h" +#include "gamestate.h" +#include "legalitycheck.h" +#include "../shogi/serializer.h" +#include "../crazyhouse/movefactory.h" +#include "../animator.h" +#include "../dropanimator.h" +#include "../shogi/shogiactions.h" + +namespace HLVariant { +namespace ShoShogi { + +struct TAGUA_EXPORT Variant { + typedef Crazyhouse::MoveMixin Move; + typedef GameState, Move> GameState; + typedef LegalityCheck LegalityCheck; + typedef Shogi::Serializer Serializer; + typedef DropAnimatorMixin > Animator; + typedef Crazyhouse::MoveFactory MoveFactory; + typedef Variant MoveGenerator; // to make VariantData happy + + static const bool hasICS = false; + static const bool m_simple_moves = false; + static const bool m_hidden = false; + static const char *m_name; + static const char *m_theme_proxy; + + static int moveListLayout() { return 0; } + + OptList positionOptions() const { return OptList(); } + void setupMove(NormalUserMove& m) const; + ActionCollection* actions(); +private: + Shogi::ShogiActions m_actions; +}; + +} // namespace ShoShogi +} // namespace HLVariant + +#endif // HLVARIANT__SHOSHOGI__VARIANT_H diff --git a/src/hlvariant/shogi/legalitycheck.h b/src/hlvariant/shogi/legalitycheck.h index 6775897..a8cdff9 100644 --- a/src/hlvariant/shogi/legalitycheck.h +++ b/src/hlvariant/shogi/legalitycheck.h @@ -96,6 +96,10 @@ bool LegalityCheck::getMoveType(const Piece& piece, const Move& move) } case Piece::PAWN: return delta == m_state.direction(piece.color()); + + case Piece::DRUNKEN_ELEPHANT: + return (abs(delta.x) == 1 && abs(delta.y) <= 1) + || (delta.x == 0 && delta.y == m_state.direction(piece.color()).y); default: return false; } @@ -121,6 +125,10 @@ bool LegalityCheck::getMoveType(const Piece& piece, const Move& move) PathInfo path = m_state.board().path(move.from(), move.to()); return path.diagonal() && path.clear(); } + + case Piece::DRUNKEN_ELEPHANT: // Crown Prince + return abs(delta.x) <= 1 && abs(delta.y) <= 1; + default: return false; } diff --git a/src/hlvariant/shogi/piece.cpp b/src/hlvariant/shogi/piece.cpp index 8f47254..4b6a186 100644 --- a/src/hlvariant/shogi/piece.cpp +++ b/src/hlvariant/shogi/piece.cpp @@ -65,6 +65,10 @@ QString Piece::typeName(Type type) { return "bishop"; case PAWN: return "pawn"; + + case DRUNKEN_ELEPHANT: + return "drunken_elephant"; + default: return "unknown"; } diff --git a/src/hlvariant/shogi/piece.h b/src/hlvariant/shogi/piece.h index 4ebaac7..03e128f 100644 --- a/src/hlvariant/shogi/piece.h +++ b/src/hlvariant/shogi/piece.h @@ -33,6 +33,10 @@ public: ROOK, BISHOP, PAWN, + + // Sho Shogi + DRUNKEN_ELEPHANT, + INVALID_TYPE = -1 }; private: diff --git a/src/variants.cpp b/src/variants.cpp index 1be98c6..3e7388b 100644 --- a/src/variants.cpp +++ b/src/variants.cpp @@ -24,6 +24,7 @@ DECLARE_FACTORY(Crazyhouse) DECLARE_FACTORY(Dummy) DECLARE_FACTORY(Shogi) DECLARE_FACTORY(MiniShogi) +DECLARE_FACTORY(ShoShogi) #undef DECLARE_FACTORY Variants::Variants() { @@ -33,6 +34,7 @@ Variants::Variants() { addFactory(Dummy::createFactory()); addFactory(Shogi::createFactory()); addFactory(MiniShogi::createFactory()); + addFactory(ShoShogi::createFactory()); } Variants& Variants::instance() { -- 2.11.4.GIT