Microsoft Small Basic

Program Listing:
Embed this in your website
' DoubutsuShogi v0.5 - Copyright (c) 2011 Nonki Takahashi
'
' History
' 2010/01/25 v0.1 Created (440 lines)
' 2010/02/03 v0.2 Created GameRecord_ class (595 lines FVD421)
' 2010/02/11 v0.3 Made animation for piece move (805 lines FVD421-0)
' 2010/02/16 v0.4 Created captured piece move (936 lines FVD421-1)
' 2010/02/23 v0.5 Bug fix for Human_ etc (1049 lines FVD421-2)
'
' Reference
' [1] 北岡, 藤田: "どうぶつしょうぎのほん", 2010, 幻冬舎エデュケーション
' (Kitaoka, Fujita: "Doubutsu Shogi No Hon", 2010, Gentosha Education)
'
' Naming convention
' class Xxx_
' label lXxx
' constant XXX
' variable type integer iXxx
' variable type real rXxx
' variable type string sXxx
' variable type url uXxx
' variable type char cXxx
' variable type boolean bXxx
' variable type object oXxx
'
' Constant
VERSION = 0.5
SPACE = 0
CHICK1 = 1
CHICKEN1 = 2
ELEPHANT1 = 3
GIRAFFE1 = 4
LION1 = 5
CHICK2 = 6
CHICKEN2 = 7
ELEPHANT2 = 8
GIRAFFE2 = 9
LION2 = 10
DIRMIN = 0
TOPLEFT = 0
TOP = 1
TOPRIGHT = 2
LEFT = 3
CENTER = 4
RIGHT = 5
BOTTOMLEFT = 6
BOTTOM = 7
BOTTOMRIGHT = 8
DIRMAX = 8
FOREST = 1
SKY = 2
'
' Main
GraphicsWindow.Height = 540
GraphicsWindow.Width = 680
' Debug_Init() ' for debug
Game_Init()
Board_Init()
Console_Init()
GameRecord_Init()
Board_New()
Board_Draw()
GameRecord_Draw()
Game_Loop()
'
' Player HUMAN | Move
Sub Human_Move
  ' Get movable piece
  While "True"
    Human_bOutOfBoard = "True"
    While Human_bOutOfBoard
      GraphicsWindow.MouseDown = Human_OnMouseDown
      Human_bNotClicked = "True"
      While Human_bNotClicked
        Program.Delay(200)
      EndWhile
      GraphicsWindow.MouseDown = Human_DoNothing
      Human_GetPosition()
      bFromCaptured = bInCaptured
    EndWhile
    Game_IsMovablePiece()
    If Game_bIsMovablePiece Then
        Goto lMovablePiece
    Else
      If bDebug Then
        TextWindow.WriteLine("Human_Move: piece not movable")
      EndIf
      Sound.PlayChime()
    EndIf
  EndWhile
lMovablePiece:
  ' Erase the piece
  If bFromCaptured Then
    Board_HideCaptured()
  Else
    Stack.PushValue("human", iPiece)
    iPiece = SPACE
    iToX = iX
    iToY = iY
    Board_iCell[iFromX][iFromY] = SPACE
    Board_DrawCell()
    iPiece = Stack.PopValue("human")
    Board_iCell[iFromX][iFromY] = iPiece
  EndIf
  ' Set the piece as shape for animation
  oPiece = Shapes.AddImage(uPiece[iPiece])
  Shapes.ShowShape(oPiece)
  If bDebug Then
    TextWindow.WriteLine("oPiece = " + oPiece)
  EndIf
  Shapes.HideShape(oPiece)
  If bFromCaptured Then
    Shapes.Move(oPiece, Human_iMX - 40, Human_iMY - 40)
  Else
    Shapes.Move(oPiece, Board_iX0 + isX + (iFromX - 1) * Board_idX , Board_iY0 + isY + (iFromY - 1) * Board_idY)
  EndIf
  Shapes.ShowShape(oPiece)
  GraphicsWindow.MouseMove = Human_OnMouseMove
  ' Get possible move
  While "True"
    Human_bOutOfBoard = "True"
    While Human_bOutOfBoard
      GraphicsWindow.MouseDown = Human_OnMouseDown
      Human_bNotClicked = "True"
      While Human_bNotClicked
        Program.Delay(200)
      EndWhile
      GraphicsWindow.MouseDown = Human_DoNothing
      Human_GetPosition()
      iToX = iX
      iToY = iY
    EndWhile
    Game_IsPossibleMove()
    If Game_bIsPossibleMove Then
      Goto lPossibleMove
    Else
      If bDebug Then
        TextWindow.WriteLine("Human_Move: impossible move")
      EndIf
      Sound.PlayChime()
    EndIf
  EndWhile
lPossibleMove:
  Board_Move()
  GameRecord_Move()
  Shapes.Remove(oPiece)
  GraphicsWindow.MouseMove = Human_DoNothing
EndSub
'
' Player HUMAN | Get board position from mouse position
' out: iX, iY - next move position
' out: i, j - next piece slot if bFromCaptured
' out: Human_bOutOfBoard - mouse clicked out of board / captured slot
' out: bInCaptured - next piece from captured slot
Sub Human_GetPosition
  Debug_sCaller = "Human_GetPosition"
  iX = Math.Floor((Human_iMX - Board_iX0) / Board_idX) + 1
  iY = Math.Floor((Human_iMY - Board_iY0) / Board_idY) + 1
  Debug_DumpXY()
  Human_bOutOfBoard = "False"
  If iX < 1 Or iX > Board_iRoX Or iY < 1 Or iY > Board_iRoY Then
    bInCaptured = "True"
    Debug_DumpInCaptured()
    iX = Math.Floor((Human_iMX - Captured_iX0) / Captured_idX) + 1
    iY = Math.Floor((Human_iMY - Captured_iY0) / Captured_idY) + 1
    i = SKY
    j = (iX - 1) * 2 + iY
    Debug_DumpIJ()
    If iX < 1 Or iX > Captured_iRoX Or iY < 1 Or iY > Captured_iRoY Then
      iY = Math.Floor((Human_iMY - Captured_iY2) / Captured_idY) + 1
      i = FOREST
      j = (iX - 1) * 2 + (3 - iY)
      Debug_DumpIJ()
      If iX < 1 Or iX > Captured_iRoX Or iY < 1 Or iY > Captured_iRoY Then
        Human_bOutOfBoard = "True"
      EndIf
    EndIf
  Else
    bInCaptured = "False"
    Debug_DumpInCaptured()
  EndIf
EndSub
'
' Player HUMAN | Get mouse position
' out: Human_iMX, Human_iMY - clicked mouse position
' out: Human_bNotClicked - flag
Sub Human_OnMouseDown
  Human_iMX = GraphicsWindow.MouseX
  Human_iMY = GraphicsWindow.MouseY
  Human_bNotClicked = "False"
EndSub
'
' Player HUMAN | Move piece with mouse
Sub Human_OnMouseMove
  Human_iMX = GraphicsWindow.MouseX
  Human_iMY = GraphicsWindow.MouseY
  Shapes.Move(oPiece, Human_iMX - 40, Human_iMY - 40)
  If "False" Then ' bDebug Then
    TextWindow.Write("(" + Human_iMX + "," + Human_iMY + ")")
  EndIf
EndSub
'
' Player HUMAN | Do nothing
Sub Human_DoNothing
EndSub
'
' Console | Initialization
Sub Console_Init
  sTitle[1] = "ど"
  sTitle[2] = "う"
  sTitle[3] = "ぶ"
  sTitle[4] = "つ"
  sTitle[5] = "し"
  sTitle[6] = "ょ"
  sTitle[7] = "う"
  sTitle[8] = "ぎ"
  sColor[1] = "Red"
  sColor[2] = "Gold"
  sColor[3] = "Blue"
  sColor[4] = "Orange"
  sColor[5] = "DeepPink"
  sColor[6] = "DeepSkyblue"
  sColor[7] = "Purple"
  sColor[8] = "SeaGreen"
  GraphicsWindow.FontSize = 30
  For i = 1 To 8
    GraphicsWindow.BrushColor = sColor[i]
    GraphicsWindow.DrawText(Board_iX0 + (i - 1) * 38, Board_iY0 - Board_idY * 4 / 5, sTitle[i])
  EndFor
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.FontSize = 20
  GraphicsWindow.DrawText(Board_iX1 + Board_idX, Board_iY0 -Board_idY * 4 / 5, "バージョン " + VERSION)
EndSub
'
' Sound | Lion march
Sub Sound_LionMarch
  For i = 1 To 1
    Sound.PlayMusic("O4 G2 G4 A4 G2 E2 C2 D2 E1 F2 F4 F4 E2 E4 E4 D4 D4 D4 D4 G1 A4 A4 A4 A4 G4 G4 G4 G4 F2 O3 B2 O4 C1")
  EndFor
EndSub
'
' Game | Initialization
Sub Game_Init
  Game_bCanMove[LION1][TOP] = "True"
  Game_bCanMove[LION1][TOPRIGHT] = "True"
  Game_bCanMove[LION1][RIGHT] = "True"
  Game_bCanMove[LION1][BOTTOMRIGHT] = "True"
  Game_bCanMove[LION1][BOTTOM] = "True"
  Game_bCanMove[LION1][BOTTOMLEFT] = "True"
  Game_bCanMove[LION1][LEFT] = "True"
  Game_bCanMove[LION1][TOPLEFT] = "True"
  Game_bCanMove[LION1][CENTER] = "True"
  '
  Game_bCanMove[GIRAFFE1][TOP] = "True"
  Game_bCanMove[GIRAFFE1][TOPRIGHT] = "False"
  Game_bCanMove[GIRAFFE1][RIGHT] = "True"
  Game_bCanMove[GIRAFFE1][BOTTOMRIGHT] = "False"
  Game_bCanMove[GIRAFFE1][BOTTOM] = "True"
  Game_bCanMove[GIRAFFE1][BOTTOMLEFT] = "False"
  Game_bCanMove[GIRAFFE1][LEFT] = "True"
  Game_bCanMove[GIRAFFE1][TOPLEFT] = "False"
  Game_bCanMove[GIRAFFE1][CENTER] = "True"
  '
  Game_bCanMove[ELEPHANT1][TOP] = "False"
  Game_bCanMove[ELEPHANT1][TOPRIGHT] = "True"
  Game_bCanMove[ELEPHANT1][RIGHT] = "False"
  Game_bCanMove[ELEPHANT1][BOTTOMRIGHT] = "True"
  Game_bCanMove[ELEPHANT1][BOTTOM] = "False"
  Game_bCanMove[ELEPHANT1][BOTTOMLEFT] = "True"
  Game_bCanMove[ELEPHANT1][LEFT] = "False"
  Game_bCanMove[ELEPHANT1][TOPLEFT] = "True"
  Game_bCanMove[ELEPHANT1][CENTER] = "True"
  '
  Game_bCanMove[CHICKEN1][TOP] = "True"
  Game_bCanMove[CHICKEN1][TOPRIGHT] = "True"
  Game_bCanMove[CHICKEN1][RIGHT] = "True"
  Game_bCanMove[CHICKEN1][BOTTOMRIGHT] = "False"
  Game_bCanMove[CHICKEN1][BOTTOM] = "True"
  Game_bCanMove[CHICKEN1][BOTTOMLEFT] = "False"
  Game_bCanMove[CHICKEN1][LEFT] = "True"
  Game_bCanMove[CHICKEN1][TOPLEFT] = "True"
  Game_bCanMove[CHICKEN1][CENTER] = "True"
  '
  Game_bCanMove[CHICK1][TOP] = "True"
  Game_bCanMove[CHICK1][TOPRIGHT] = "False"
  Game_bCanMove[CHICK1][RIGHT] = "False"
  Game_bCanMove[CHICK1][BOTTOMRIGHT] = "False"
  Game_bCanMove[CHICK1][BOTTOM] = "False"
  Game_bCanMove[CHICK1][BOTTOMLEFT] = "False"
  Game_bCanMove[CHICK1][LEFT] = "False"
  Game_bCanMove[CHICK1][TOPLEFT] = "False"
  Game_bCanMove[CHICK1][CENTER] = "True"
  '
  Game_bCanMove[LION2][TOP] = "True"
  Game_bCanMove[LION2][TOPRIGHT] = "True"
  Game_bCanMove[LION2][RIGHT] = "True"
  Game_bCanMove[LION2][BOTTOMRIGHT] = "True"
  Game_bCanMove[LION2][BOTTOM] = "True"
  Game_bCanMove[LION2][BOTTOMLEFT] = "True"
  Game_bCanMove[LION2][LEFT] = "True"
  Game_bCanMove[LION2][TOPLEFT] = "True"
  Game_bCanMove[LION2][CENTER] = "True"
  '
  Game_bCanMove[GIRAFFE2][TOP] = "True"
  Game_bCanMove[GIRAFFE2][TOPRIGHT] = "False"
  Game_bCanMove[GIRAFFE2][RIGHT] = "True"
  Game_bCanMove[GIRAFFE2][BOTTOMRIGHT] = "False"
  Game_bCanMove[GIRAFFE2][BOTTOM] = "True"
  Game_bCanMove[GIRAFFE2][BOTTOMLEFT] = "False"
  Game_bCanMove[GIRAFFE2][LEFT] = "True"
  Game_bCanMove[GIRAFFE2][TOPLEFT] = "False"
  Game_bCanMove[GIRAFFE2][CENTER] = "True"
  '
  Game_bCanMove[ELEPHANT2][TOP] = "False"
  Game_bCanMove[ELEPHANT2][TOPRIGHT] = "True"
  Game_bCanMove[ELEPHANT2][RIGHT] = "False"
  Game_bCanMove[ELEPHANT2][BOTTOMRIGHT] = "True"
  Game_bCanMove[ELEPHANT2][BOTTOM] = "False"
  Game_bCanMove[ELEPHANT2][BOTTOMLEFT] = "True"
  Game_bCanMove[ELEPHANT2][LEFT] = "False"
  Game_bCanMove[ELEPHANT2][TOPLEFT] = "True"
  Game_bCanMove[ELEPHANT2][CENTER] = "True"
  '
  Game_bCanMove[CHICKEN2][TOP] = "True"
  Game_bCanMove[CHICKEN2][TOPRIGHT] = "False"
  Game_bCanMove[CHICKEN2][RIGHT] = "True"
  Game_bCanMove[CHICKEN2][BOTTOMRIGHT] = "True"
  Game_bCanMove[CHICKEN2][BOTTOM] = "True"
  Game_bCanMove[CHICKEN2][BOTTOMLEFT] = "True"
  Game_bCanMove[CHICKEN2][LEFT] = "True"
  Game_bCanMove[CHICKEN2][TOPLEFT] = "False"
  Game_bCanMove[CHICKEN2][CENTER] = "True"
  '
  Game_bCanMove[CHICK2][TOP] = "False"
  Game_bCanMove[CHICK2][TOPRIGHT] = "False"
  Game_bCanMove[CHICK2][RIGHT] = "False"
  Game_bCanMove[CHICK2][BOTTOMRIGHT] = "False"
  Game_bCanMove[CHICK2][BOTTOM] = "True"
  Game_bCanMove[CHICK2][BOTTOMLEFT] = "False"
  Game_bCanMove[CHICK2][LEFT] = "False"
  Game_bCanMove[CHICK2][TOPLEFT] = "False"
  Game_bCanMove[CHICK2][CENTER] = "True"
  If bDebug Then
    TextWindow.Write("Game_Init: Game_bCanMove = ")
    TextWindow.WriteLine(Game_bCanMove)
  EndIf
EndSub
'
' Game | Loop
Sub Game_Loop
  iTurn = FOREST
  bInGame = "True"
  While bInGame
    ' Odd turn
    Human_Move()
    Game_Judge()
    iTurn = 3 - iTurn
    If bInGame Then
      ' Even turn
      Human_Move()
      Game_Judge()
      iTurn = 3 - iTurn
    EndIf
  EndWhile
EndSub
'
' Game | Judge
' out: Game_bEnd - game end flag
' out: Game_bDraw - draw flag
' out: Game_iWinner - winner FOREST or SKY
Sub Game_Judge
  ' Check draw (with 3 times of same board pattern)
  ' Check catch
  ' Check try (legal or illegal)
EndSub
'
' Game | Is movable piece?
' in: iX, iY - next move
' in: i, j - next piece in captured if bFromCaptured
' in: iTurn - turn forest or sky
' out: Game_bIsMovablePiece - is movable
' out: iPiece - piece if movable
' out: iFromX, iFromY - position of the piece
Sub Game_IsMovablePiece
  Debug_sCaller = "Game_IsMovablePiece"
  Debug_DumpXY()
  If bFromCaptured Then
    iPiece = Board_iCaptured[i][j]
    Debug_DumpIJ()
  Else
    iPiece = Board_iCell[iX][iY]
  EndIf
  Debug_DumpPiece()
  Game_bIsMovablePiece = "False"
  If iPiece > (iTurn - 1) * 5 And iPiece < 6 + (iTurn - 1) * 5 Then
    If bFromCaptured Then
      Game_bIsMovablePiece = "True"
      Goto lExitMovable
    EndIf
    iFromX = iX
    iFromY = iY
    ' iPiece is a member of iTurn team and
    For i = DIRMIN To DIRMAX ' nine directions
      If bDebug Then
        TextWindow.WriteLine(Debug_sCaller + ": direction i = " + i)
      EndIf
      If Game_bCanMove[iPiece][i] Then
        If bDebug Then
          TextWindow.WriteLine(Debug_sCaller + ": movable direction i = " + i)
        EndIf
        iToX = iFromX + iDirX[i]
        iToY = iFromY + iDirY[i]
        iToPiece = Board_iCell[iToX][iToY]
        If bDebug Then
          Stack.PushValue("debug", iX)
          Stack.PushValue("debug", iY)
          iX = iToX
          iY = iToY
          Debug_DumpXY()
          iY = Stack.PopValue("debug")
          iX = Stack.PopValue("debug")
          Stack.PushValue("debug", iPiece)
          iPiece = iToPiece
          Debug_DumpPiece()
          iPiece = Stack.PopValue("debug")
          Debug_DumpTurn()
        EndIf
        If iToPiece = SPACE Or (iToPiece > (2 - iTurn) * 5 And iToPiece < 6 + (2 - iTurn) * 5) Then
          ' iToX, iToY is movable position for iPiece
          Game_bIsMovablePiece = "True"
          If bDebug Then
            TextWindow.WriteLine(Debug_sCaller + ": movable")
          EndIf
        EndIf
      EndIf
    EndFor
  Else
    If bDebug Then
      TextWindow.WriteLine(Debug_sCaller + ": piece not iTurn team")
    EndIf
  EndIf
lExitMovable:
EndSub
'
' Game | Is possible move?
' in: iFromX, iFromY - piece position (if not bFromCaptured)
' in: iToX, iToY - next move
' in: iPiece - piece to move
' out: Game_bIsPossibleMove - flag if possible move
' out: Game_bCapture - flag if capture
Sub Game_IsPossibleMove
  Debug_sCaller = "Game_IsPossibleMove"
  If bFromCaptured Then
    If Board_iCell[iToX][iToY] = SPACE Then
      Debug_Case1()
      Game_bIsPossibleMove = "True"
      Game_bCapture = "False"
    Else
      Debug_Case2()
      Game_bIsPossibleMove = "False"
      Game_bCapture = "False"
    EndIf
  Else
    idX = iToX - iFromX
    idY = iToY - iFromY
    If idX >= -1 And idX <= 1 And idY >= -1 And idY <= 1 Then
      i = (idY + 1) * 3 + (idX + 1)
      If Game_bCanMove[iPiece][i] Then
        ' iToX, iToY is movable position for iPiece
        If Board_iCell[iToX][iToY] = SPACE Then
          Debug_Case3()
          Game_bIsPossibleMove = "True"
          Game_bCapture = "False"
        ElseIf Board_iCell[iToX][iToY] > (2 - iTurn) * 5 And Board_iCell[iToX][iToY] < 6 + (2 - iTurn) * 5 Then
          ' opposite team peace already exists ... capture it
          Debug_Case4()
          Game_bIsPossibleMove = "True"
          Game_bCapture = "True"
        Else
          Debug_Case5()
          Game_bIsPossibleMove = "False"
          Game_bCapture = "False"
        EndIf
      Else
        Debug_Case6()
        Game_bIsPossibleMove = "False"
        Game_bCapture = "False"
      EndIf
    Else
      Debug_Case7()
      Game_bIsPossibleMove = "False"
      Game_bCapture = "False"
    EndIf
  EndIf
EndSub
'
' Board | Initialization
Sub Board_Init
  Board_iRoX = 3
  Board_iRoY = 4
  Board_iX0 = 50
  Board_iY0 = 100
  Board_idX = 100
  Board_idY = 100
  Board_iX1 = Board_iX0 + Board_idX * Board_iRoX
  Board_iY1 = Board_iY0 + Board_idY * Board_iRoY
  isX = 10
  isY = 10
  Captured_iRoX = 3
  Captured_iRoY = 2
  Captured_idX = Board_idX / 2
  Captured_idY = Board_idY / 2
  Captured_iX0 = Board_iX1
  Captured_iX1 = Captured_iX0 + Captured_idX * Captured_iRoX
  Captured_iY0 = Board_iY0
  Captured_iY1 = Captured_iY0 + Captured_idY * Captured_iRoY
  Captured_iY3 = Board_iY1
  Captured_iY2 = Captured_iY3 - Captured_idY * Captured_iRoY
  sBoard = "http://homepage2.nifty.com/nobukit/smallbasic.files/Board300.png"
  Board_sX[1] = "A"
  Board_sX[2] = "B"
  Board_sX[3] = "C"
  Board_sY[1] = "1"
  Board_sY[2] = "2"
  Board_sY[3] = "3"
  Board_sY[4] = "4"
  uCell[1][1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/A1.png"
  uCell[2][1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/B1.png"
  uCell[3][1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/C1.png"
  uCell[1][2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/A2.png"
  uCell[2][2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/B2.png"
  uCell[3][2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/C2.png"
  uCell[1][3] = "http://homepage2.nifty.com/nobukit/smallbasic.files/A3.png"
  uCell[2][3] = "http://homepage2.nifty.com/nobukit/smallbasic.files/B3.png"
  uCell[3][3] = "http://homepage2.nifty.com/nobukit/smallbasic.files/C3.png"
  uCell[1][4] = "http://homepage2.nifty.com/nobukit/smallbasic.files/A4.png"
  uCell[2][4] = "http://homepage2.nifty.com/nobukit/smallbasic.files/B4.png"
  uCell[3][4] = "http://homepage2.nifty.com/nobukit/smallbasic.files/C4.png"
  '
  uPiece[LION1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Lion1t.png"
  uPiece[GIRAFFE1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Giraffe1t.png"
  uPiece[ELEPHANT1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Elephant1t.png"
  uPiece[CHICK1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Chick1t.png"
  uPiece[CHICKEN1] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Chicken1t.png"
  uPiece[LION2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Lion2t.png"
  uPiece[GIRAFFE2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Giraffe2t.png"
  uPiece[ELEPHANT2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Elephant2t.png"
  uPiece[CHICK2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Chick2t.png"
  uPiece[CHICKEN2] = "http://homepage2.nifty.com/nobukit/smallbasic.files/Chicken2t.png"
  '
  iDirX[TOP] = 0
  iDirY[TOP] = -1
  iDirX[TOPRIGHT] = 1
  iDirY[TOPRIGHT] = -1
  iDirX[RIGHT] = 1
  iDirY[RIGHT] = 0
  iDirX[BOTTOMRIGHT] = 1
  iDirY[BOTTOMRIGHT] = 1
  iDirX[BOTTOM] = 0
  iDirY[BOTTOM] = 1
  iDirX[BOTTOMLEFT] = -1
  iDirY[BOTTOMLEFT] = 1
  iDirX[LEFT] = -1
  iDirY[LEFT] = 0
  iDirX[TOPLEFT] = -1
  iDirY[TOPLEFT] = -1
  iDirX[CENTER] = 0
  iDirY[CENTER] = 0
  If bDebug Then
    TextWindow.WriteLine("Board_Init: iDirX = " + iDirX)
    TextWindow.WriteLine("Board_Init: iDirY = " + iDirY)
  EndIf
EndSub
'
' Board | New
Sub Board_New
  GraphicsWindow.PenColor = "DarkOrange"
  GraphicsWindow.BrushColor = "DarkOrange"
  GraphicsWindow.PenWidth = 2
  GraphicsWindow.FontSize = 20
  GraphicsWindow.DrawImage(sBoard, Board_iX0, Board_iY0)
  For i = 0 To 3
    Dotted_iX0 = Board_iX0 + i * Board_idX
    Dotted_iY0 = Board_iY0
    Dotted_iX1 = Board_iX0 + i * Board_idX
    Dotted_iY1 = Board_iY1
    Graphics_DrawDottedLine()
    If i > 0 Then
      GraphicsWindow.DrawText(Board_iX0 + i * Board_idX - Board_idX / 2 - 5, Board_iY0 - Board_idY / 3, Board_sX[i])
    EndIf
  EndFor
  For i = 0 To 4
    Dotted_iX0 = Board_iX0
    Dotted_iY0 = Board_iY0 + i * Board_idY
    Dotted_iX1 = Board_iX1
    Dotted_iY1 = Board_iY0 + i * Board_idY
    Graphics_DrawDottedLine()
    If i > 0 Then
      GraphicsWindow.DrawText(Board_iX0 - Board_idX / 4, Board_iY0 + i * Board_idY - Board_idY / 2 - 10, Board_sY[i])
    EndIf
  EndFor
  Board_iCell[1][1] = GIRAFFE2
  Board_iCell[2][1] = LION2
  Board_iCell[3][1] = ELEPHANT2
  Board_iCell[1][2] = SPACE
  Board_iCell[2][2] = CHICK2
  Board_iCell[3][2] = SPACE
  Board_iCell[1][3] = SPACE
  Board_iCell[2][3] = CHICK1
  Board_iCell[3][3] = SPACE
  Board_iCell[1][4] = ELEPHANT1
  Board_iCell[2][4] = LION1
  Board_iCell[3][4] = GIRAFFE1
  If bDebug Then
    TextWindow.Write("Board_New: Board_iCell = ")
    TextWindow.WriteLine(Board_iCell)
  EndIf
  ' Captured by SKY, FOREST
  For i = FOREST To SKY
    Board_iNumCaptured[i] = 0
    For j = 1 To 6
      Board_iCaptured[i][j] = SPACE
    EndFor
  EndFor
EndSub
'
' Board | Move
' in bFromCaptured - if from captured slot (not from board cell)
' in iFromX, iFromY, iPiece - piece and the position
' in: i, j - captured slot if bFromCaptured
' in iToX, iToY - to position
Sub Board_Move
  Debug_sCaller = "Board_Move"
  Debug_DumpFromCaptured()
  ' check i, j are in captured slot
  If bFromCaptured Then
    If (i > FOREST And i < SKY) Or (j < 1 And j > 6) Then
      If bDebug Then
        TextWindow.Write("Board_Move: i = " + i + " or ")
        TextWindow.WriteLine("j = " + j + "out of bounce")
      EndIf
      Goto lOutOfBounce
    Else
      Debug_DumpIJ()
      iPiece = Board_iCaptured[i][j]
      Goto lValidPiece
    EndIf
  EndIf
  ' check iFromX, iFromY, iToX, iToX are in board
  If iFromX < 1 Or iFromX > Board_iRoX Then
    If bDebug Then
      TextWindow.WriteLine("Board_Move: iFromX = " + iFromX + " out of bounce")
    EndIf
    Goto lOutOfBounce
  EndIf
  If iFromY < 1 Or iFromY > Board_iRoY Then
    If bDebug Then
      TextWindow.WriteLine("Board_Move: iFromY = " + iFromY + " out of bounce")
    EndIf
    Goto lOutOfBounce
  EndIf
  iPiece = Board_iCell[iFromX][iFromY]
lValidPiece:
  Debug_DumpPiece()
  If iToX < 1 Or iToX > Board_iRoX Then
    If bDebug Then
      TextWindow.WriteLine("Board_Move: iToX = " + iToX + " out of bounce")
    EndIf
    Goto lOutOfBounce
  EndIf
  If iToY < 1 Or iToY > Board_iRoY Then
    If bDebug Then
      TextWindow.WriteLine("Board_Move: iToY = " + iToY + " out of bounce")
    EndIf
    Goto lOutOfBounce
  EndIf
  If iPiece > (iTurn - 1) * 5 And iPiece < 6 + (iTurn - 1) * 5 Then
    ' iPiece is a member of iTurn team
    If bFromCaptured And Board_iCell[iToX][iToY] = SPACE Then
      ' iToX, iToY is movable position for captured iPiece
      Goto lMatch
    EndIf
    For i = DIRMIN To DIRMAX ' nine directions
      If iDirX[i] = iToX - iFromX And iDirY[i] = iToY - iFromY Then
        Debug_sCaller = "Board_Move"
        Debug_DumpCanMove()
        If Game_bCanMove[iPiece][i] Then
          ' iToX, iToY is movable position for iPiece
          Goto lMatch
        EndIf
      EndIf
    EndFor
    If bDebug Then
      TextWindow.WriteLine("Board_Move: " + sPiece[iPiece] + " not movable")
    EndIf
    Sound.PlayChime()
    Goto lExit
  EndIf
lMatch:
  Game_IsPossibleMove()
  If Game_bCapture Then
    iCaptured = Board_iCell[iToX][iToY]
  EndIf
  If Game_bIsPossibleMove Then
    If bFromCaptured Then
      Board_RemoveCaptured()
    Else
      iX = iFromX
      iY = iFromY
      Board_iCell[iX][iY] = SPACE
      Board_DrawCell()
    EndIf
    iX = iToX
    iY = iToY
    Board_iCell[iX][iY] = iPiece
    Board_DrawCell()
  EndIf
  If Game_bCapture Then
    iOpposite = iTurn * 10 - 15
    iCaptured = iCaptured + iOpposite
    Board_AddCaptured()
  EndIf
  Goto lExit
lOutOfBounce:
  Sound.PlayChime()
lExit:
EndSub
'
' Board | Draw
Sub Board_Draw
  For iY = 1 To 4
    For iX = 1 To 3
      Board_DrawCell()
    EndFor
  EndFor
  For i = FOREST To SKY
    For j = 1 To 6
      Board_DrawCaptured()
    EndFor
  EndFor
EndSub
'
' Board | Draw cell
' in: iX, iY - cell index
Sub Board_DrawCell
  If Board_iCell[iX][iY] = SPACE Then
    GraphicsWindow.DrawImage(uCell[iX][iY], Board_iX0 + (iX - 1) * Board_idX + 2, Board_iY0 + (iY - 1) * Board_idY + 2)
  Else
    GraphicsWindow.DrawImage(uPiece[Board_iCell[iX][iY]], Board_iX0 + (iX - 1) * Board_idX + isX, Board_iY0 + (iY - 1) * Board_idY + isY)
    Sound.PlayClickAndWait()
  EndIf
EndSub
'
' Board | Draw captured piece
' in: i - index FOREST team or SKY team
' in: j - index 1 to 6 for each team's capture slot
Sub Board_DrawCaptured
  If i = FOREST Then
    iX = Captured_iX0 + (Math.Floor((j + 1) / 2) - 1) * Captured_idX
    iY = Captured_iY2 + Math.Remainder(8 - j, 2) * Captured_idY
  Else ' i = SKY
    iX = Captured_iX0 + (Math.Floor((j + 1) / 2) - 1) * Captured_idX
    iY = Captured_iY0 + Math.Remainder(j + 1, 2) * Captured_idY
  EndIf
  If Board_iCaptured[i][j] = SPACE Then
    GraphicsWindow.BrushColor = "White"
    GraphicsWindow.FillRectangle(iX + 1, iY + 1, 48, 48)
  Else
    GraphicsWindow.DrawResizedImage(uPiece[Board_iCaptured[i][j]], iX + isX / 2, iY + isY / 2, 42, 42)
    Sound.PlayClickAndWait()
  EndIf
EndSub
'
' Board | Find piece
' in: sInfo - additional information
' "上" ... to foreward
' "寄" ... to side
' "引" ... to backward
' "右" ... from right piece
' "左" ... from left piece
' "打" ... from captured
' out: bFoundInBoard
' out: iX, iY - found board position
' out: i, j - found captured slot
Sub Board_FindPiece
  bFound = "False"
  For iY = 1 To 4
    For iX = 1 To 3
      If Board_iCell[iX][iY] = iPiece Then
        bFound = "True"
        iFromX = iX
        iFromY = iY
        Goto lFound
      EndIf
    EndFor
  EndFor
  For i = FOREST To SKY
    For j = 1 To 6
      If Board_iCaptured[i][j] = iPiece Then
        bFound = "True"
        iTurn = i
        iSlot = j
        Goto lFound
      EndIf
    EndFor
  EndFor
lFound:
EndSub
'
' Board | Add captured piece
' in: iCaptured - captured piece
' out: i, j - captured slot index
Sub Board_AddCaptured
  Debug_sCaller = "Board_AddCaptured"
  If iCaptured <= 5 Then
    i = FOREST
  Else
    i = SKY
  EndIf
  j = Board_iNumCaptured[i]
  j = j + 1
  Board_iCaptured[i][j] = iCaptured
  Debug_DumpCaptured()
  Board_iNumCaptured[i] = j
  Board_DrawCaptured()
EndSub
'
' Board | Remove captured piece
' in: i, j - captured slot index
' out: iPiece - removed piece
Sub Board_RemoveCaptured
  Debug_sCaller = "Board_RemoveCaptured"
  If j > Board_iNumCaptured[i] Then
    TextWindow.WriteLine("Error: j out of bounce")
    Goto lRemoveError
  EndIf
  iPiece = Board_iCaptured[i][j]
  Stack.PushValue("board", j)
  For j = j To Board_iNumCaptured[i] - 1
    Board_iCaptured[i][j] = Board_iCaptured[i][j + 1]
    Board_DrawCaptured()
  EndFor
  Board_iCaptured[i][j] = SPACE
  Board_DrawCaptured()
  j = Stack.PopValue("board")
  Board_iNumCaptured[i] = Board_iNumCaptured[i] - 1
lRemoveError:
EndSub
'
' Board | Hide captured piece
' in: i, j - captured slot index
' out: iPiece - hidden piece
Sub Board_HideCaptured
  Debug_sCaller = "Board_HideCaptured"
  If j > Board_iNumCaptured[i] Then
    TextWindow.WriteLine("Error: j out of bounce")
    Goto lHideError
  EndIf
  iPiece = Board_iCaptured[i][j]
  Board_iCaptured[i][j] = SPACE
  Board_DrawCaptured()
  Board_iCaptured[i][j] = iPiece
lHideError:
EndSub
'
' Game Record | Initialization
Sub GameRecord_Init
  sPiece[LION1] = "ライオン"
  sPiece[ELEPHANT1] = "ぞう"
  sPiece[GIRAFFE1] = "きりん"
  sPiece[CHICKEN1] = "ニワトリ"
  sPiece[CHICK1] = "ひよこ"
  sPiece[LION2] = "ライオン"
  sPiece[ELEPHANT2] = "ぞう"
  sPiece[GIRAFFE2] = "きりん"
  sPiece[CHICKEN2] = "ニワトリ"
  sPiece[CHICK2] = "ひよこ"
  GameRecord_iNum = 0
EndSub
'
' Game record | Draw
Sub GameRecord_Draw
  For iRec = 1 To GameRecord_iNum
    sTo = Board_sX[GameRecord_iToX[iRec]] + Board_sY[GameRecord_iToY[iRec]]
    iPiece = GameRecord_iPiece[iRec]
    GameRecord_DrawLine()
  EndFor
EndSub
'
' Game record | Draw line
Sub GameRecord_DrawLine
  If Math.Remainder(iRec, 2) = FOREST Then
    GraphicsWindow.BrushColor = "LawnGreen"
  Else
    GraphicsWindow.BrushColor = "PowderBlue"
  EndIf
  GraphicsWindow.FillEllipse(Board_iX1 + Board_idX * 1.6 - 4, Board_iY0 + (iRec - 1) * 30 + 2, 24, 24)
  GraphicsWindow.BrushColor = "Black"
  sLine = iRec + " " + sTo + " " + sPiece[iPiece]
  GraphicsWindow.DrawText(Board_iX1 + Board_idX * 1.6, Board_iY0 + (iRec - 1) * 30, sLine)
  TextWindow.WriteLine(sLine)
EndSub
'
' Game record | Move
Sub GameRecord_Move
  iRec = GameRecord_iNum + 1
  GameRecord_iPiece[iRec] = iPiece
  GameRecord_iToX[iRec] = iToX
  GameRecord_iToY[iRec] = iToY
  GameRecord_iNum = iRec
  sTo = Board_sX[iToX] + Board_sY[iToY]
  GameRecord_DrawLine()
EndSub
'
' Graphics | Draw dotted line
' in: Dotted_iX0, Dotted_iY0 - line start point
' in: Dotted_iX1, Dotted_iY1 - line end point
Sub Graphics_DrawDottedLine
  iLen = 10
  iSqX = (Dotted_iX1 - Dotted_iX0) * (Dotted_iX1 - Dotted_iX0)
  iSqY = (Dotted_iY1 - Dotted_iY0) * (Dotted_iY1 - Dotted_iY0)
  For rLen = 0 To Math.SquareRoot(iSqX + iSqY) - iLen Step iLen * 2
    rRatio = rLen / Math.SquareRoot(iSqX + iSqY)
    iDX0 = Dotted_iX0 + rRatio * (Dotted_iX1 - Dotted_iX0)
    iDY0 = Dotted_iY0 + rRatio * (Dotted_iY1 - Dotted_iY0)
    rRatio = (rLen + iLen) / Math.SquareRoot(iSqX + iSqY)
    iDX1 = Dotted_iX0 + rRatio * (Dotted_iX1 - Dotted_iX0)
    iDY1 = Dotted_iY0 + rRatio * (Dotted_iY1 - Dotted_iY0)
    GraphicsWindow.DrawLine(iDX0, iDY0, iDX1, iDY1)
  EndFor
EndSub
'
' Debug | Initialization
Sub Debug_Init
  bDebug = "True"
  sTurn[FOREST] = "FOREST"
  sTurn[SKY] = "SKY"
EndSub
'
' Debug | Dump flag Game_bCanMove[][]
' in: iPiece - piece
' in: i - direction
' in: Game_bCanMove[][] - flag can move
' in: Debug_sCaller - caller routine name
Sub Debug_DumpCanMove
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": Game_bCanMove[" + iPiece + "][" + i + "] = " + Game_bCanMove[i][j])
  EndIf
EndSub
'
' Debug | Dump iX, iY
' in: iX, iY
' in: Debug_sCaller - caller routine name
Sub Debug_DumpXY
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": iX = " + iX + ", iY = " + iY)
  EndIf
EndSub
'
' Debug | Dump i, i
' in: iX, iY
' in: Debug_sCaller - caller routine name
Sub Debug_DumpIJ
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": i = " + i + ", j = " + j)
  EndIf
EndSub
'
' Debug | Dump iPiece
' in: iPiece
' in: Debug_sCaller - caller routine name
Sub Debug_DumpPiece
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": iPiece = " + iPiece + " (" + sPiece[iPiece] + ")")
  EndIf
EndSub
'
' Debug | Dump iTurn
' in: iTurn
' in: Debug_sCaller - caller routine name
Sub Debug_DumpTurn
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": iTurn = " + iTurn + " (" + sTurn[iTurn] + ")")
  EndIf
EndSub
'
' Debug | Dump Board_iCaptured[i][j]
' in: i, j
' in: Debug_sCaller - caller routine name
Sub Debug_DumpCaptured
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": Board_iCaptured[" + i + "][" + j + "] = " + sPiece[Board_iCaptured[i][j]])
  EndIf
EndSub
'
' Debug | Dump bFromCaptured
' in: bFromCaptured
' in: Debug_sCaller - caller routine name
Sub Debug_DumpFromCaptured
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": bFromCaptured = " + bFromCaptured)
  EndIf
EndSub
'
' Debug | Dump bInCaptured
' in: bInCaptured
' in: Debug_sCaller - caller routine name
Sub Debug_DumpInCaptured
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": bInCaptured = " + bInCaptured)
  EndIf
EndSub
'
' Debug | Dump case number
Sub Debug_Case1
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 1")
  EndIf
EndSub
Sub Debug_Case2
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 2")
  EndIf
EndSub
Sub Debug_Case3
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 3")
  EndIf
EndSub
Sub Debug_Case4
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 4")
  EndIf
EndSub
Sub Debug_Case5
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 5")
  EndIf
EndSub
Sub Debug_Case6
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 6")
  EndIf
EndSub
Sub Debug_Case7
  If bDebug Then
    TextWindow.WriteLine(Debug_sCaller + ": case 7")
  EndIf
EndSub
Copyright (c) Microsoft Corporation. All rights reserved.