(define "CapturePiece" (apply (if ("IsEnemyAt" (to)) (add (piece (mapEntry "Captured" (what at:(to)))) (to (mapEntry "Where" (what at:(to)))) ) ) ) ) (define "NextCannotMove" (not (can Move (do (or { (move (from (sites Occupied by:Next container:"Hand" components:{"Kakugyo" "Ginsho" "Hisha" "Kinsho"})) (to (sites Empty)) ) (do (move (from (sites Occupied by:Next container:"Hand" component:"Fuhyo")) (to (difference (sites Empty) (sites Next "LastRank")) if:("OnePawnPerColumn" Next) ) ) ifAfterwards:(not ("IsInCheck" "Osho" Mover)) ) ("PlaceLance" Next) ("PlaceKnight" Next) (forEach Piece Next) }) ifAfterwards:(not ("IsInCheck" "Osho" Next)) ) ) ) ) (define "OnePawnPerColumn" (= (count Sites in:(sites Occupied by:#1 container:"Board" component:"Fuhyo")) (count Sites in:(difference (sites Occupied by:#1 container:"Board" component:"Fuhyo") (sites Column (column of:(to))))) ) ) (define "PlaceKnight" (move (from (sites Occupied by:#1 container:"Hand" component:"Keima")) (to (difference (sites Empty) (sites #1 "TwoFurthestRank"))) ) ) (define "PlaceLance" (move (from (sites Occupied by:#1 container:"Hand" component:"Kyosha")) (to (difference (sites Empty) (sites #1 "LastRank"))) ) ) (define "PlacePawn" (do (move (from (sites Occupied by:#1 container:"Hand" component:"Fuhyo")) (to (difference (sites Empty) (sites #1 "LastRank")) if:("OnePawnPerColumn" #1) ) ) ifAfterwards:(not (and ("IsInCheck" "Osho" #2) ("NextCannotMove"))) ) ) (define "InPromotionZone" (is In #1 (sites Mover "Promotion")) ) (define "InLastRank" (is In #1 (sites Mover "LastRank")) ) (define "InTwoFurthestRank" (is In #1 (sites Mover "TwoFurthestRank")) ) (define "Promote" (move Promote (last To) (piece (mapEntry "Promoted" (what at:(last To))))) ) (define "CanPromote" (then (if (or ("InPromotionZone" (last To)) ("InPromotionZone" (last From))) (moveAgain) ) ) ) (define "SlideMove" (move Slide #1 (to if:("IsEnemyAt" (to)) "CapturePiece") #2 ) ) (define "StepMove" (move Step #1 (to if:(not ("IsFriendAt" (to))) "CapturePiece") #2 ) ) //------------------------------------------------------------------------------ (game "Shogi" ("TwoPlayersNorthSouth") (equipment { (board (square 9)) // King (piece "Osho" Each ("StepMove")) //Pawn (piece "Fuhyo" Each ("StepMove" Forward (then (if ("InPromotionZone" (last To)) (if ("InLastRank" (last To)) ("Promote") (moveAgain) ) ) ) ) ) // Silver General (piece "Ginsho" Each ("StepMove" (directions {Forward BL BR FL FR}) "CanPromote")) // Rook (piece "Hisha" Each ("SlideMove" Orthogonal "CanPromote")) // Bishop (piece "Kakugyo" Each ("SlideMove" Diagonal "CanPromote")) // Knight (piece "Keima" Each (forEach Direction Forward (to if:True (apply (forEach Direction (from (to)) (directions {FR FL}) (if (not ("IsFriendAt" (to))) (move (from) (to (apply if:("IsEnemyAt" (to)) (add (piece (mapEntry "Captured" (what at:(to)))) (to (mapEntry "Where" (what at:(to)))) ) ) ) ) ) ) ) ) (then (if ("InPromotionZone" (last To)) (if ("InTwoFurthestRank" (last To)) "Promote" (moveAgain) ) ) ) ) ) // Lance (piece "Kyosha" Each ("SlideMove" Forward (then (if ("InPromotionZone" (last To)) (if ("InLastRank" (last To)) "Promote" (moveAgain) ) ) ) ) ) // Gold General ("ShogiGold" "Kinsho" "CapturePiece") // Promoted Pawn ("ShogiGold" "Tokin" "CapturePiece") // Promoted Silver ("ShogiGold" "Narigin" "CapturePiece") // Promoted Rook (piece "Ryuo" Each (or ("SlideMove" Orthogonal) ("StepMove" Diagonal))) // Promoted Bishop (piece "Ryuma" Each (or ("SlideMove" Diagonal) ("StepMove" Orthogonal))) // Promoted Knight ("ShogiGold" "Narikei" "CapturePiece") // Promoted Lance ("ShogiGold" "Narikyo" "CapturePiece") (regions "LastRankP1" P1 (sites Top)) (regions "LastRankP2" P2 (sites Bottom)) (regions "TwoFurthestRankP1" P1 (expand (sites Top))) (regions "TwoFurthestRankP2" P2 (expand (sites Bottom))) (regions "Promotion" P1 (expand (sites Top) steps:2)) (regions "Promotion" P2 (expand (sites Bottom) steps:2)) (map "Where" { (pair (id "Fuhyo" P1) (handSite P2)) (pair (id "Fuhyo" P2) (handSite P1)) (pair (id "Ginsho" P1) (handSite P2 1)) (pair (id "Ginsho" P2) (handSite P1 1)) (pair (id "Hisha" P1) (handSite P2 2)) (pair (id "Hisha" P2) (handSite P1 2)) (pair (id "Kakugyo" P1) (handSite P2 3)) (pair (id "Kakugyo" P2) (handSite P1 3)) (pair (id "Keima" P1) (handSite P2 4)) (pair (id "Keima" P2) (handSite P1 4)) (pair (id "Kyosha" P1) (handSite P2 5)) (pair (id "Kyosha" P2) (handSite P1 5)) (pair (id "Kinsho" P1) (handSite P2 6)) (pair (id "Kinsho" P2) (handSite P1 6)) (pair (id "Tokin" P1) (handSite P2)) (pair (id "Tokin" P2) (handSite P1)) (pair (id "Narigin" P1) (handSite P2 1)) (pair (id "Narigin" P2) (handSite P1 1)) (pair (id "Ryuo" P1) (handSite P2 2)) (pair (id "Ryuo" P2) (handSite P1 2)) (pair (id "Ryuma" P1) (handSite P2 3)) (pair (id "Ryuma" P2) (handSite P1 3)) (pair (id "Narikei" P1) (handSite P2 4)) (pair (id "Narikei" P2) (handSite P1 4)) (pair (id "Narikyo" P1) (handSite P2 5)) (pair (id "Narikyo" P2) (handSite P1 5)) }) (map "Captured" { (pair (id "Fuhyo" P1) (id "Fuhyo" P2)) (pair (id "Fuhyo" P2) (id "Fuhyo" P1)) (pair (id "Ginsho" P1) (id "Ginsho" P2)) (pair (id "Ginsho" P2) (id "Ginsho" P1)) (pair (id "Hisha" P1) (id "Hisha" P2)) (pair (id "Hisha" P2) (id "Hisha" P1)) (pair (id "Kakugyo" P1) (id "Kakugyo" P2)) (pair (id "Kakugyo" P2) (id "Kakugyo" P1)) (pair (id "Keima" P1) (id "Keima" P2)) (pair (id "Keima" P2) (id "Keima" P1)) (pair (id "Kyosha" P1) (id "Kyosha" P2)) (pair (id "Kyosha" P2) (id "Kyosha" P1)) (pair (id "Kinsho" P1) (id "Kinsho" P2)) (pair (id "Kinsho" P2) (id "Kinsho" P1)) (pair (id "Tokin" P1) (id "Fuhyo" P2)) (pair (id "Tokin" P2) (id "Fuhyo" P1)) (pair (id "Narigin" P1) (id "Ginsho" P2)) (pair (id "Narigin" P2) (id "Ginsho" P1)) (pair (id "Ryuo" P1) (id "Hisha" P2)) (pair (id "Ryuo" P2) (id "Hisha" P1)) (pair (id "Ryuma" P1) (id "Kakugyo" P2)) (pair (id "Ryuma" P2) (id "Kakugyo" P1)) (pair (id "Narikei" P1) (id "Keima" P2)) (pair (id "Narikei" P2) (id "Keima" P1)) (pair (id "Narikyo" P1) (id "Kyosha" P2)) (pair (id "Narikyo" P2) (id "Kyosha" P1)) }) (map "Promoted" { (pair (id "Fuhyo" P1) (id "Tokin" P1)) (pair (id "Fuhyo" P2) (id "Tokin" P2)) (pair (id "Ginsho" P1) (id "Narigin" P1)) (pair (id "Ginsho" P2) (id "Narigin" P2)) (pair (id "Hisha" P1) (id "Ryuo" P1)) (pair (id "Hisha" P2) (id "Ryuo" P2)) (pair (id "Kakugyo" P1) (id "Ryuma" P1)) (pair (id "Kakugyo" P2) (id "Ryuma" P2)) (pair (id "Keima" P1) (id "Narikei" P1)) (pair (id "Keima" P2) (id "Narikei" P2)) (pair (id "Kyosha" P1) (id "Narikyo" P1)) (pair (id "Kyosha" P2) (id "Narikyo" P2)) }) (hand Each size:7) }) (rules (start { (place "Osho1" coord:"E1") (place "Kinsho1" {"D1" "F1"}) (place "Ginsho1" {"C1" "G1"}) (place "Keima1" {"B1" "H1"}) (place "Kyosha1" {"A1" "I1"}) (place "Kakugyo1" coord:"B2") (place "Hisha1" coord:"H2") (place "Fuhyo1" (sites Row 2)) (place "Osho2" coord:"E9") (place "Kinsho2" {"D9" "F9"}) (place "Ginsho2" {"C9" "G9"}) (place "Keima2" {"B9" "H9"}) (place "Kyosha2" {"A9" "I9"}) (place "Kakugyo2" coord:"H8") (place "Hisha2" coord:"B8") (place "Fuhyo2" (sites Row 6)) }) (play (if ("SameTurn") (or ("Promote") (move Pass) ) (do (or { (move (from (sites Occupied by:Mover container:"Hand" components:{"Kakugyo" "Ginsho" "Hisha" "Kinsho"})) (to (sites Empty)) ) ("PlacePawn" Mover Next) ("PlaceLance" Mover) ("PlaceKnight" Mover) (forEach Piece) }) ifAfterwards:(not ("IsInCheck" "Osho" Mover)) ) ) ) (end { (if (and ("IsInCheck" "Osho" Next) ("NextCannotMove") ) (result Mover Win) ) ("BlockWin") }) ) ) //------------------------------------------------------------------------------ (metadata (info { (description "Shogi is a capturing game that is native to Japan. Early evidence suggests it was played in some recognizable form during the Heian Period. It has been hugely popular since then in Japan, and today is known throughout the world. It originated ultimately from Indian Chaturanga, like many other games such as Chess, Shatranj, and Xiangqi.") (aliases {"Sho-Shogi"}) (rules "Pieces move as follows: Osho(1): moves one space in any direction Hisha(1): moves any number of spaces orthogonally. Kakugyo(1): moves any number of spaces diagonally. Kinsho(2): moves one square in any direction except diagonally backwards. Ginsho (2): moves one square diagonally or one square forward orthogonally. Keima(2): moves one space forward and then one space diagonally forward. Kyosha(2): moves any number of spaces only forward or backward. Fuhyo(9): moves one space forward. Pieces are promoted when reaching the opposite third of the board. Pieces are captured when an opponent's piece moves to the space it occupies. Captured pieces are held and can re-enter the game under the control of the capturing player as their turn. The goal is to capture the other player's king.") (source "Murray 1913: 138-148.") (id "46") (version "1.3.12") (classification "board/war/replacement/checkmate/shogi") (credit "Eric Piette") (origin "This game was played in Japan, around 1058.") } ) (graphics { (player Colour P1 (colour White)) (player Colour P2 (colour White)) (piece Families {"Defined" "Study"}) (board Style Shogi) (piece Rotate P2 degrees:180) (piece Colour "Tokin" strokeColour:(colour Red)) (piece Colour "Narigin" strokeColour:(colour Red)) (piece Colour "Ryuo" strokeColour:(colour Red)) (piece Colour "Ryuma" strokeColour:(colour Red)) (piece Colour "Narikei" strokeColour:(colour Red)) (piece Colour "Narikyo" strokeColour:(colour Red)) (piece ExtendName P2 piece:"Osho" "1") }) (ai "Shogi_ai" ) )