Microsoft Small Basic

Program Listing:
Embed this in your website
' Tic-tac-toe v1.4 - Copyright (c) 2011 Nonki Takahashi
'
' History
' v1.0 2011/01/18 Created, can play HUMAN vs HUMAN only (419 lines LBW762)
' v1.1 2011/01/18 Added cross reference (505 lines LBW762-0)
' v1.2 2011/01/19 Shaws game tree (419 lines LBW762-1)
' v1.3 2011/01/21 can play RANDOM vs HUMAN (579 lines LBW762-2)
' v1.4 2011/01/24 can play MINIMAX vs HUMAN (678 lines LBW762-3)
'
' Reference
' [1] en.wikipedia.org/wiki/Tic-tac-toe
' [2] 森田, 国枝, 津田: "思考ゲームプログラミング" 1986, アスキー
' (Morita, Kunieda, Tsuda: "Shikou Game Programming" 1986, ASCII)
'
' Naming convention
' class Xxx_
' label lXxx
' constant XXX
' variable type integer iXxx
' variable type real rXxx
' variable type string sXxx
' variable type char cXxx
' variable type boolean bXxx
'
' Constant
SPACE = 0   ' for Board
CROSS = 1   ' X for Board
NOUGHT = 2  ' O for Board
DRAW = 3    ' for Winner
UPPERA = Text.GetCharacterCode("A")   ' for Parse
UPPERZ = Text.GetCharacterCode("Z")   ' for Parse
LETTER0 = Text.GetCharacterCode("0")  ' for Parse
LETTER9 = Text.GetCharacterCode("9")  ' for Parse
REPLAY = "4"  ' Webdings replay mark for replay button
SAVE = "="    ' Windings save mark save button
NEW = "NEW"   ' String for new button
VERSION = "v1.4"  ' Program version
LEVEL = 5     ' Max depth level for minimax method
'
' Main
bPreset = "True"
Game_Init()
While "True"
  Game_New()
  If bPreset Then
    GameRecord_sBuf = "A1"
    Controls.SetTextBoxText(Console_oGameRecord, GameRecord_sBuf)
    GameRecord_Read()
    GameRecord_Replay()
  EndIf
  While Game_iWinner = SPACE
    iTurn = Math.Remainder(Board_iMove, 2) + 1
    If iTurn = NOUGHT Then
      Lamp_iOn = iTurn
      Lamp_Draw()
      Goto lTurnO
    EndIf
    ' Turn X (CROSS)
    Player_iScore = 0
    Player_iLevel = LEVEL
    Console_bShow = "False"
    Console_bShowResult = "False"
    Player_MiniMax()
    Console_bShow = "True"
    Console_bShowResult = "True"
    Board_Move()
    Lamp_iOn = 3 - iTurn
    Lamp_Draw()
    GameRecord_Move()
    GameRecord_Write()
    Game_Judge()
    If Game_iWinner <> SPACE Then
      Goto lGameEnd
    EndIf
lTurnO:
    ' Turn O (NOUGHT)
    Player_Human()
    Board_Move()
    Lamp_iOn = 3 - iTurn
    Lamp_Draw()
    GameRecord_Move()
    GameRecord_Write()
    Game_Judge()
  EndWhile
lGameEnd:
  Controls.ShowControl(Console_oReplay)
  Controls.ShowControl(Console_oNew)
  Console_bNew = "False"
  Controls.ButtonClicked = Console_OnButtonClicked
  While Console_bNew = "False"
    ' Wait replay or new button
    While Console_bButtonClicked = "False"
      Program.Delay(100)
    EndWhile
    Console_bButtonClicked = "False"
    ' Replay game record
    If Console_bReplay Then
      Board_New()
      GameRecord_Read()
      GameRecord_Replay()
    EndIf
  EndWhile
  Controls.ButtonClicked = Console_DoNothing
EndWhile
'
' Player MINIMAX | Next move
' in: Player_iLevel - depth level
' out: iX, iY - next move position when Player_iLevel = LEVEL
' out: iScore - evaluated score
Sub Player_MiniMax
  Stack.PushValue("nextmove", iX)
  Stack.PushValue("nextmove", iY)
  Stack.PushValue("nextmove", iTurn)
  Stack.PushValue("nextmove", iMaxScore)
  Stack.PushValue("nextmove", bMax)
  iTurn = Math.Remainder(Board_iMove, 2) + 1
  If iTurn = CROSS Then
    iMaxScore = -2 ' Minimum
  ElseIf iTurn = NOUGHT Then
    iMaxScore = 2 ' Maximum
  EndIf
  bMax = "True"
  For iY = 1 To Board_iRo
    For iX = 1 To Board_iRo
      Game_IsPossibleMove()
      If Game_bIsPossibleMove Then
        If bMax = "False" Then
          iXC = iX
          iXY = iY
        EndIf
        Board_Move()
        GameRecord_Move()
        Game_Judge()
        If Game_iWinner = CROSS Then
          iScore = 1
        ElseIf Game_iWinner = NOUGHT Then
          iScore = -1
        ElseIf Game_iWinner = DRAW Then
          iScore = 0
        ElseIf Player_iLevel > 1 Then
          Player_iLevel = Player_iLevel - 1
          Player_MiniMax()
          Player_iLevel = Player_iLevel + 1
        Else
          iScore = 0
        EndIf
        If iTurn = CROSS And iScore >= iMaxScore Then ' Max level
          iMaxScore = iScore
          If Player_iLevel = LEVEL Then
            bMax = "True"
            iXC = iX
            iYC = iY
          EndIf
        ElseIf iTurn = NOUGHT And iScore <= iMaxScore Then ' Minimum level
          iMaxScore = iScore
        EndIf
        Board_Unmove()
        GameRecord_Unmove()
      EndIf
    EndFor
  EndFor
  bMax = Stack.PopValue("nextmove")
  iScore = iMaxScore
  iMaxScore = Stack.PopValue("nextmove")
  iTurn = Stack.PopValue("nextmove")
  iY = Stack.PopValue("nextmove")
  iX = Stack.PopValue("nextmove")
  If Player_iLevel = LEVEL Then
    iX = iXC ' Next move candidate
    iY = iYC ' Next move candidate
  EndIf
EndSub
'
' Player HUMAN | Next move
' out: iX, iY - next move position
Sub Player_Human
  GraphicsWindow.MouseDown = Player_OnMouseDown
  While "True"
    Player_bOutOfBoard = "True"
    While Player_bOutOfBoard
      Player_bNotClicked = "True"
      While Player_bNotClicked
        Program.Delay(200)
      EndWhile
      Player_GetPosition()
    EndWhile
    Game_IsPossibleMove()
    If Game_bIsPossibleMove Then
        Goto lPossibleMove
    Else
      Sound.PlayChimeAndWait()
    EndIf
  EndWhile
lPossibleMove:
  GraphicsWindow.MouseDown = Player_DoNothing
  iTurn = Math.Remainder((Board_iMove - 1), 2) + 1
EndSub
'
' Player HUMAN | Get mouse position
' out: Player_iMX, Player_iMY - clicked mouse position
' out: Player_bNotClicked - flag
Sub Player_OnMouseDown
  Player_iMX = GraphicsWindow.MouseX
  Player_iMY = GraphicsWindow.MouseY
  Player_bNotClicked = "False"
EndSub
'
Sub Player_DoNothing
EndSub
'
' Player HUMAN | Get board position from mouse position
' out: iX, iY - next move position
Sub Player_GetPosition
  iX = Math.Floor((Player_iMX - Board_iX0) / Board_idX) + 1
  iY = Math.Floor((Player_iMY - Board_iY0) / Board_idY) + 1
  If iX < 1 Or iX > Board_iRo Or iY < 1 Or iY > Board_iRo Then
    Player_bOutOfBoard = "True"
  Else
    Player_bOutOfBoard = "False"
  EndIf
EndSub
'
' Game | Get possible moves list
' in: Board_iCell[][] - board
' out: iPossible - entry count of possible moves
' out: iPX[], iPY[] - possible moves
' work: iNP - instead of x, y for Board_iCell[][]
Sub Game_GetPossibleMoves
  iPossible = 0
  For iNP = 0 To 8
    If Board_iCell[Math.Remainder(iNP, 3) + 1][Math.Floor(iNP / 3) + 1] = SPACE Then
      iPossible = iPossible + 1
      iPX[iPossible] = Math.Remainder(iNP, 3) + 1
      iPY[iPossible] = Math.Floor(iNP / 3) + 1
    EndIf
  EndFor
EndSub
'
' Game | Initialization
Sub Game_Init
  GraphicsWindow.BackgroundColor = "LightGray"
  GraphicsWindow.Title = "Tic-tac-toe " + VERSION
  Console_bShowResult = "True"
  Console_bSound = "True"
  Board_Init()
  Console_Init()
EndSub
'
' Game | Set game properties for new game
Sub Game_New
  Board_New()
  Console_New()
  GameRecord_New()
  Controls.HideControl(Console_oReplay)
  Controls.HideControl(Console_oNew)
  Game_iWinner = SPACE
EndSub
'
' Game | Is possible move?
' in: iX, iY - next move
Sub Game_IsPossibleMove
  If Board_iCell[iX][iY] = SPACE Then
    Game_bIsPossibleMove = "True"
  Else
    Game_bIsPossibleMove = "False"
  EndIf
EndSub
'
' Game | Judge
Sub Game_Judge
  Stack.PushValue("judge", iX)
  Stack.PushValue("judge", iY)
  Stack.PushValue("judge", iTurn)
  If Console_bShowResult Then
    GraphicsWindow.PenColor = "Magenta"
    GraphicsWindow.PenWidth = 5
  EndIf
  Game_iWinner = SPACE
  iTurn = Board_iCell[1][1] ' \
  If iTurn = SPACE Then
    Goto lLine2
  EndIf
  For i = 2 To Board_iRo
    If Board_iCell[i][i] <> iTurn Then
      Goto lLine2
    EndIf
  EndFor
  If Console_bShowResult Then
    GraphicsWindow.DrawLine(Board_iX0, Board_iY0, Board_iX1, Board_iY1)
  EndIf
  Game_iWinner = iTurn
lLine2:
  iTurn = Board_iCell[Board_iRo][1] ' /
  If iTurn = SPACE Then
    Goto lLine3
  EndIf
  For i = 2 To Board_iRo
    If Board_iCell[Board_iRo + 1 - i][i] <> iTurn Then
      Goto lLine3
    EndIf
  EndFor
  If Console_bShowResult Then
    GraphicsWindow.DrawLine(Board_iX1, Board_iY0, Board_iX0, Board_iY1)
  EndIf
  Game_iWinner = iTurn
lLine3:
  For iY = 1 To Board_iRo
    iTurn = Board_iCell[1][iY]
    If iTurn = SPACE Then
      Goto lLine4
    EndIf
    For iX = 2 To Board_iRo
      If Board_iCell[iX][iY] <> iTurn Then
        Goto lLine4
      EndIf
    EndFor
    If Console_bShowResult Then
      GraphicsWindow.DrawLine(Board_iX0, Board_iY0 + (iY - 1 / 2) * Board_idY, Board_iX1, Board_iY0 + (iY - 1 / 2) * Board_idY)
    EndIf
    Game_iWinner = iTurn
lLine4:
  EndFor
  For iX = 1 To Board_iRo
    iTurn = Board_iCell[iX][1]
    If iTurn = SPACE Then
      Goto lLine5
    EndIf
    For iY = 2 To Board_iRo
      If Board_iCell[iX][iY] <> iTurn Then
        Goto lLine5
      EndIf
    EndFor
    If Console_bShowResult Then
      GraphicsWindow.DrawLine(Board_iX0 + (iX - 1 / 2) * Board_idX, Board_iY0, Board_iX0 + (iX - 1 / 2) * Board_idX, Board_iY1)
    EndIf
    Game_iWinner = iTurn
lLine5:
  EndFor
  If Board_iMove = 9 And Game_iWinner = SPACE Then
    Game_iWinner = DRAW
  EndIf
  If Game_iWinner = CROSS Then
    Game_iScore = 1
  ElseIf Game_iWinner = NOUGHT Then
    Game_iScore = -1
  Else
    Game_iScore = 0
  EndIf
  If Console_bShowResult And Game_iWinner <> SPACE Then
    Console_ShowWinner()
  EndIf
  iTurn = Stack.PopValue("judge")
  iY = Stack.PopValue("judge")
  iX = Stack.PopValue("judge")
EndSub
'
' Game console | Do nothing
Sub Console_DoNothing
EndSub
'
' Game console | Set flags about clicked buttons
' out: Console_bReplay, Console_bNew, Console_bButtonClicked
Sub Console_OnButtonClicked
  If Controls.LastClickedButton = Console_oReplay Then
    Console_bReplay = "True"
  Else
    Console_bReplay = "False"
  EndIf
  If Controls.LastClickedButton = Console_oNew Then
    Console_bNew = "True"
  Else
    Console_bNew = "False"
  EndIf
  If Console_bReplay Or Console_bNew Then
    Console_bButtonClicked = "True"
  Else
    Console_bButtonClicked = "False"
  EndIf
EndSub
'
' Game console | Initialization
Sub Console_Init
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.FontSize = 20
  GraphicsWindow.DrawText(Board_iX1 + Board_isX * 2, Board_iY0, "X (CROSS)")
  GraphicsWindow.DrawText(Board_iX1 + Board_isX * 2, Board_iY0 + Board_iRo * Board_idY / 3, "O (NOUGHT)")
  Lamp_iCount = 2
  Lamp_iX[CROSS] = Board_iX1 + Board_idX * 2
  Lamp_iY[CROSS] = Board_iY0
  Lamp_iX[NOUGHT] = Board_iX1 + Board_idX * 2
  Lamp_iY[NOUGHT] = Board_iY0 + Board_iRo * Board_idY / 3
  Console_oCross = Controls.AddTextBox(Board_iX1 + Board_isX * 2 + 70, Board_iY0 + 30)
  Controls.SetTextBoxText(Console_oCross, "MINIMAX")
  Console_oNought = Controls.AddTextBox(Board_iX1 + Board_isX * 2 + 70, Board_iY0 + Board_iRo * Board_idY / 3 + 30)
  Controls.SetTextBoxText(Console_oNought, "HUMAN")
  GraphicsWindow.DrawText(Board_iX0 - Board_isX * 2.5, Board_iY1 + Board_isY * 3, "GAME RECORD")
  Console_oGameRecord = Controls.AddTextBox(Board_iX0 - Board_isX * 2 + 150, Board_iY1 + Board_isY * 3)
  Controls.SetSize(Console_oGameRecord, 12 * 27, 30)
  sFontName = GraphicsWindow.FontName
  GraphicsWindow.FontName = "Webdings"
  Console_oReplay = Controls.AddButton(REPLAY, Board_iX0 + 12 * 37, Board_iY1 + Board_isY * 3)
  GraphicsWindow.FontName = sFontName
  iFontSize = GraphicsWindow.FontSize
  GraphicsWindow.FontSize = 17
  Console_oNew = Controls.AddButton(NEW, Board_iX0 + 12 * 40, Board_iY1 + Board_isY * 3)
  GraphicsWindow.FontSize = iFontSize
  GameRecord_sBuf = ""
  Console_New()
EndSub
'
' Game console | Set console for new game
Sub Console_New
  Lamp_iOn = CROSS
  Lamp_Draw()
  Console_bReplay = "False"
  Console_bNew = "False"
  Controls.SetTextBoxText(Console_oGameRecord, GameRecord_sBuf)
  GameRecord_Write()
EndSub
'
' Game console | Show winner to console
Sub Console_ShowWinner
  iX = Board_iX1 + Board_isX * 2
  iY = Board_iY0 + 30
  GraphicsWindow.BrushColor = "Black"
  If Game_iWinner = CROSS Then
    GraphicsWindow.DrawText(iX, iY, "WIN")
  ElseIf Game_iWinner = NOUGHT Then
    GraphicsWindow.DrawText(iX, iY, "LOSE")
  ElseIf Game_iWinner = DRAW Then
    GraphicsWindow.DrawText(iX, iY, "DRAW")
  EndIf
  iY = iY + Board_iRo * Board_idY / 3
  If Game_iWinner = NOUGHT Then
    GraphicsWindow.DrawText(iX, iY, "WIN")
  ElseIf Game_iWinner = CROSS Then
    GraphicsWindow.DrawText(iX, iY, "LOSE")
  ElseIf Game_iWinner = DRAW Then
    GraphicsWindow.DrawText(iX, iY, "DRAW")
  EndIf
EndSub
'
' Game console | Hide winner from console
Sub Console_HideWinner
  iX = Board_iX1 + Board_isX * 2
  iY = Board_iY0 + 30
  GraphicsWindow.BrushColor = "LightGray"
  GraphicsWindow.FillRectangle(iX, iY, 80, 30)
  iY = iY + Board_iRo * Board_idY / 3
  GraphicsWindow.FillRectangle(iX, iY, 80, 30)
EndSub
'
' Select lamp | Draw select lamps
' in: Lamp_iOn - index of lamp selected
' in: Lamp_iCount - number of lamps
Sub Lamp_Draw
  For Lamp_iIndex = 1 To Lamp_iCount
    GraphicsWindow.BrushColor = "White"
    GraphicsWindow.FillRectangle(Lamp_iX[Lamp_iIndex] + 1, Lamp_iY[Lamp_iIndex] + 1, 21, 7)
    GraphicsWindow.BrushColor = "DimGray"
    GraphicsWindow.FillRectangle(Lamp_iX[Lamp_iIndex] - 2, Lamp_iY[Lamp_iIndex] - 2, 21, 7)
    If Lamp_iIndex = Lamp_iOn Then
      GraphicsWindow.BrushColor = "Lime"
    Else
      GraphicsWindow.BrushColor = "Black"
    EndIf
    GraphicsWindow.FillRectangle(Lamp_iX[Lamp_iIndex], Lamp_iY[Lamp_iIndex], 20, 6)
  EndFor
EndSub
'
' Tic-tac-toe board | Initialization
Sub Board_Init
  Board_iRo = 3
  Board_idX = 90
  Board_idY = 90
  Board_isX = 20
  Board_isY = 20
  Board_iX0 = 65
  Board_iY0 = 60
  Board_iX1 = Board_iX0 + Board_idX * Board_iRo
  Board_iY1 = Board_iY0 + Board_idY * Board_iRo
  Board_cX[1] = "A"
  Board_cX[2] = "B"
  Board_cX[3] = "C"
  Board_cY[1] = "1"
  Board_cY[2] = "2"
  Board_cY[3] = "3"
  Console_bShow = "True"
  Board_New()
EndSub
'
' Tic-tac-toe board | Set board for new game
Sub Board_New
  Board_iMove = 0
  For iY = 1 To Board_iRo
    For iX = 1 To Board_iRo
      Board_iCell[iX][iY] = SPACE
    EndFor
  EndFor
  Board_Draw()
  If Console_bShowResult Then
    Console_HideWinner()
  EndIf
EndSub
'
' Tic-tac-toe board | Draw board
Sub Board_Draw
  GraphicsWindow.BrushColor = "DarkGreen"
  GraphicsWindow.FillRectangle(Board_iX0 - Board_isX, Board_iY0 - Board_isY, Board_iRo * Board_idX + 2 * Board_isX, Board_iRo * Board_idY + 2 * Board_isY)
  GraphicsWindow.PenColor = "Khaki"
  GraphicsWindow.PenWidth = 5
  For i = 1 To Board_iRo - 1
    iX = Board_iX0 + Board_idX * i
    iY = Board_iY0 + Board_idY * i
    GraphicsWindow.DrawLine(Board_iX0, iY, Board_iX1, iY)
    GraphicsWindow.DrawLine(iX, Board_iY0, iX, Board_iY1)
  EndFor
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.FontSize = 20
  For i = 1 To Board_iRo
    iX = Board_iX0 + Board_idX * (i - 1) + Board_idX / 2
    GraphicsWindow.DrawText(iX, Board_iY0 - 2.5 * Board_isY, Board_cX[i])
    iY = Board_iY0 + Board_idY * (i - 1) + Board_idY / 2
    GraphicsWindow.DrawText(Board_iX0 - 2.5 * Board_isX, iY, Board_cY[i])
  EndFor
EndSub
'
' Tic-tac-toe board | set next move to board and draw the move
' in: iX, iY - next move
Sub Board_Move
  Game_IsPossibleMove()
  If Game_bIsPossibleMove Then
    Board_iMove = Board_iMove + 1
    iTurn = Math.Remainder((Board_iMove - 1), 2) + 1
    Board_iCell[iX][iY] = iTurn
    If Console_bShow Then
      GraphicsWindow.PenColor = "White"
      GraphicsWindow.PenWidth = 10
      If iTurn = CROSS Then
        GraphicsWindow.DrawLine(Board_iX0 + (iX - 1) * Board_idX + Board_isX, Board_iY0 + (iY - 1) * Board_idY + Board_isY, Board_iX0 + iX * Board_idX - Board_isX, Board_iY0 + iY * Board_idY - Board_isY)
        GraphicsWindow.DrawLine(Board_iX0 + iX * Board_idX - Board_isX, Board_iY0 + (iY - 1) * Board_idY + Board_isY, Board_iX0 + (iX - 1) * Board_idX + Board_isX, Board_iY0 + iY * Board_idY - Board_isY)
      ElseIf iTurn = NOUGHT Then
        GraphicsWindow.DrawEllipse(Board_iX0 + (iX - 1) * Board_idX + Board_isX, Board_iY0 + (iY - 1) * Board_idY + Board_isY, Board_idX - 2 * Board_isX, Board_idY - 2 * Board_isY)
      EndIf
      GraphicsWindow.BrushColor = "Khaki"
      GraphicsWindow.DrawText(Board_iX0 + (iX - 1) * Board_idX + Board_isX / 3, Board_iY0 + (iY - 1) * Board_idY + Board_isY / 3, Board_iMove)
      If Console_bSound Then
        Sound.PlayClickAndWait()
      EndIf
    EndIf
  Else
    TextWindow.Write("ERROR: Board_Move(")
    Debug_DumpXY()
  EndIf
EndSub
'
' Tic-tac-toe board | Undo last move
' in: GameRecord_iX[], GameRecord_iY[] - last moves
' out: iX, iY - last move
Sub Board_Unmove
  iX = GameRecord_iX[GameRecord_iMove]
  iY = GameRecord_iY[GameRecord_iMove]
  If Board_iCell[iX][iY] <> SPACE Then
    Board_iCell[iX][iY] = SPACE
    If Console_bShow Then
      GraphicsWindow.BrushColor = "DarkGreen"
      GraphicsWindow.FillRectangle(Board_iX0 + (iX - 1) * Board_idX + 3, Board_iY0 + (iY - 1) * Board_idY + 3, Board_idX - 6, Board_idY - 6)
    EndIf
    Board_iMove = Board_iMove - 1
    iTurn = Math.Remainder(Board_iMove - 1, 2) + 1
  EndIf
EndSub
'
' Game record | Set game record to new game
Sub GameRecord_New
  GameRecord_iMove = 0
  Controls.SetTextBoxText(Console_oGameRecord, "")
EndSub
'
' Game record | Replay game record
Sub GameRecord_Replay
  For iMove = 1 To GameRecord_iMove
    iX = GameRecord_iX[iMove]
    iY = GameRecord_iY[iMove]
    iTurn = GameRecord_iTurn[iMove]
    Lamp_iOn = iTurn
    Lamp_Draw()
    Board_Move()
    Game_Judge()
  EndFor
EndSub
'
' Game record | Read game record from textbox
Sub GameRecord_Read
  GameRecord_iMove = 0
  Parse_sBuf = Controls.GetTextBoxText(Console_oGameRecord)
  Parse_iBufPtr = 1
  Parse_iBufLen = Text.GetLength(Parse_sBuf)
  While Parse_iBufPtr <= Parse_iBufLen
    Parse_Move()
    If Parse_bError Then
      Parse_iBufPtr = Parse_iBufPtr + 1
    EndIf
  EndWhile
EndSub
'
' Game record | Write game record to textbox
Sub GameRecord_Write
  GameRecord_sBuf = ""
  For iMove = 1 To GameRecord_iMove
    GameRecord_sBuf = GameRecord_sBuf + Text.GetSubText("ABCD", GameRecord_iX[iMove], 1)
    GameRecord_sBuf = GameRecord_sBuf + Text.GetSubText("1234", GameRecord_iY[iMove], 1)
    If iMove < GameRecord_iMove Then
      GameRecord_sBuf = GameRecord_sBuf + " "
    EndIf
  EndFor
  Controls.SetTextBoxText(Console_oGameRecord, GameRecord_sBuf)
EndSub
'
' Game record | Record next move
Sub GameRecord_Move
  GameRecord_iMove = GameRecord_iMove + 1
  iTurn = Math.Remainder(GameRecord_iMove - 1, 2) + 1
  GameRecord_iTurn[GameRecord_iMove] = iTurn
  GameRecord_iX[GameRecord_iMove] = iX
  GameRecord_iY[GameRecord_iMove] = iY
EndSub
'
' Game record | Undo last move in game recode
Sub GameRecord_Unmove
  If GameRecord_iMove > 0 Then
    GameRecord_iMove = GameRecord_iMove - 1
    iTurn = Math.Remainder(GameRecord_iMove - 1, 2) + 1
  EndIf
EndSub
'
' Game record parse | Parse move in textbox
Sub Parse_Move
  Parse_Upper()
  If Parse_bError = "False" Then
    iX = Text.GetIndexOf("ABCD", Parse_c)
    Parse_Digit()
    If Parse_bError = "False" Then
      iY = Text.GetIndexOf("1234", Parse_c)
      GameRecord_Move()
    EndIf
  EndIf
EndSub
'
' Game record parse | Parse upper case char in textbox
Sub Parse_Upper
  Parse_c = Text.GetSubText(Parse_sBuf,Parse_iBufPtr, 1)
  iCode = Text.GetCharacterCode(Parse_c)
  If iCode >= UPPERA And iCode <= UPPERZ Then
    Parse_bError = "False"
    Parse_iBufPtr = Parse_iBufPtr + 1
  Else
    Parse_bError = "True"
  EndIf
EndSub
'
' Game record parse | Parse digit in textbox
Sub Parse_Digit
  Parse_c = Text.GetSubText(Parse_sBuf,Parse_iBufPtr, 1)
  iCode = Text.GetCharacterCode(Parse_c)
  If iCode >= LETTER0 And iCode <= LETTER9 Then
    Parse_bError = "False"
    Parse_iBufPtr = Parse_iBufPtr + 1
  Else
    Parse_bError = "True"
  EndIf
EndSub
'
' Debug | Dump iX iY
' in: iX, iY
Sub Debug_DumpXY
  TextWindow.WriteLine("iX = " + iX + ", iY= " + iY)
EndSub
Copyright (c) Microsoft Corporation. All rights reserved.