162 lines
4.2 KiB
Plaintext
162 lines
4.2 KiB
Plaintext
' Tic-tac-toe
|
|
|
|
DECLARE FUNCTION Win% (Piece AS STRING)
|
|
DECLARE FUNCTION SpacesFilled% ()
|
|
DECLARE SUB ClearBoard ()
|
|
DECLARE SUB DisplayNumberedBoard ()
|
|
DECLARE SUB DisplayPiecedBoard ()
|
|
DECLARE FUNCTION Evaluate% (Me AS STRING, Him AS STRING)
|
|
|
|
DIM SHARED Board(8) AS STRING * 1, BestMove AS INTEGER
|
|
DIM SHARED WinPos(7, 2) AS INTEGER
|
|
DIM SHARED MyPiece AS STRING, HisPiece AS STRING
|
|
|
|
FOR I = 0 TO 7
|
|
FOR J = 0 TO 2
|
|
READ WinPos(I, J)
|
|
NEXT J
|
|
NEXT I
|
|
' Winning positions
|
|
DATA 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 3, 6, 1, 4, 7, 2, 5, 8, 0, 4, 8, 2, 4, 6
|
|
MyWinsCnt = 0: HisWinsCnt = 0: DrawsCnt = 0
|
|
CompFirst = -1 ' It be reversed, so human goes first
|
|
CLS
|
|
PRINT
|
|
PRINT " TIC-TAC-TOE"
|
|
PRINT
|
|
PRINT "In this version, X always goes first."
|
|
PRINT "The board is numbered:"
|
|
DO
|
|
CompFirst = NOT CompFirst ' reverse who goes first
|
|
MovesCnt = 0
|
|
PRINT
|
|
DisplayNumberedBoard
|
|
PRINT
|
|
IF CompFirst THEN PRINT "I go first." ELSE PRINT "You go first. ";
|
|
ClearBoard
|
|
IF CompFirst THEN MyPiece = "X": HisPiece = "O" ELSE MyPiece = "O": HisPiece = "X"
|
|
' -1: human; 1: computer; 0: nobody
|
|
IF CompFirst THEN Mover = 1 ELSE Mover = -1
|
|
WHILE Mover <> 0
|
|
SELECT CASE Mover
|
|
CASE 1
|
|
IF MovesCnt = 0 THEN
|
|
BestMove = INT(RND * 9)
|
|
ELSEIF MovesCnt = 1 THEN
|
|
IF Board(4) <> " " THEN BestMove = INT(RND * 2) * 6 + INT(RND * 2) * 2 ELSE BestMove = 4
|
|
ELSE
|
|
T = Evaluate(MyPiece, HisPiece)
|
|
END IF
|
|
Board(BestMove) = MyPiece
|
|
MovesCnt = MovesCnt + 1
|
|
PRINT
|
|
CALL DisplayPiecedBoard
|
|
PRINT
|
|
IF Win(MyPiece) THEN
|
|
MyWinsCnt = MyWinsCnt + 1
|
|
PRINT "I win!"
|
|
Mover = 0
|
|
ELSEIF SpacesFilled THEN
|
|
DrawsCnt = DrawsCnt + 1
|
|
PRINT "It's a draw. Thank you."
|
|
Mover = 0
|
|
ELSE
|
|
Mover = -1
|
|
END IF
|
|
CASE -1
|
|
DO
|
|
INPUT "Where do you move? ", I
|
|
IF I < 1 OR I > 9 THEN
|
|
PRINT "Illegal! ";
|
|
ELSEIF Board(I - 1) <> " " THEN
|
|
PRINT "Place already occupied. ";
|
|
ELSE
|
|
EXIT DO
|
|
END IF
|
|
LOOP
|
|
Board(I - 1) = HisPiece
|
|
MovesCnt = MovesCnt + 1
|
|
PRINT
|
|
CALL DisplayPiecedBoard
|
|
PRINT
|
|
IF Win(HisPiece) THEN
|
|
HisWinsCnt = HisWinsCnt + 1
|
|
PRINT "You beat me! Good game."
|
|
Mover = 0
|
|
ELSEIF SpacesFilled THEN
|
|
DrawsCnt = DrawsCnt + 1
|
|
PRINT "It's a draw. Thank you."
|
|
Mover = 0
|
|
ELSE
|
|
Mover = 1
|
|
END IF
|
|
END SELECT
|
|
WEND
|
|
PRINT
|
|
INPUT "Another game (y/n)? ", Answ$
|
|
LOOP UNTIL UCASE$(Answ$) <> "Y"
|
|
PRINT
|
|
PRINT "Final score:"
|
|
PRINT "You won", HisWinsCnt; "game";
|
|
IF HisWinsCnt <> 1 THEN PRINT "s";
|
|
PRINT "."
|
|
PRINT "I won", MyWinsCnt; "game";
|
|
IF MyWinsCnt <> 1 THEN PRINT "s";
|
|
PRINT "."
|
|
PRINT "We tied", DrawsCnt; "game";
|
|
IF DrawsCnt <> 1 THEN PRINT "s";
|
|
PRINT "."
|
|
PRINT "See you later!"
|
|
END
|
|
|
|
SUB ClearBoard
|
|
FOR I = 0 TO 8: Board(I) = " ": NEXT I
|
|
END SUB
|
|
|
|
SUB DisplayNumberedBoard
|
|
FOR I = 0 TO 8 STEP 3
|
|
PRINT I + 1; "|"; I + 2; "|"; I + 3
|
|
IF I <> 6 THEN PRINT "---+---+---"
|
|
NEXT I
|
|
END SUB
|
|
|
|
SUB DisplayPiecedBoard
|
|
FOR I = 0 TO 8 STEP 3
|
|
PRINT " "; Board(I); " | "; Board(I + 1); " | "; Board(I + 2)
|
|
IF I <> 6 THEN PRINT "---+---+---"
|
|
NEXT I
|
|
END SUB
|
|
|
|
FUNCTION Evaluate% (Me AS STRING, Him AS STRING)
|
|
' Recursive algorithm
|
|
IF Win(Me) THEN Evaluate = 1: EXIT FUNCTION
|
|
IF Win(Him) THEN Evaluate = -1: EXIT FUNCTION
|
|
IF SpacesFilled THEN Evaluate = 0: EXIT FUNCTION
|
|
LoseFlag = 1
|
|
FOR I = 0 TO 8
|
|
IF Board(I) = " " THEN
|
|
Board(I) = Me ' Try the move.
|
|
V = Evaluate(Him, Me)
|
|
Board(I) = " " ' Restore the empty space.
|
|
IF V = -1 THEN BestMove = I: Evaluate = 1: EXIT FUNCTION
|
|
IF V = 0 THEN LoseFlag = 0: SafeMove = I
|
|
END IF
|
|
NEXT
|
|
BestMove = SafeMove
|
|
Evaluate = -LoseFlag
|
|
END FUNCTION
|
|
|
|
FUNCTION SpacesFilled%
|
|
FOR I = 0 TO 8
|
|
IF Board(I) = " " THEN SpacesFilled = 0: EXIT FUNCTION
|
|
NEXT I
|
|
SpacesFilled = -1
|
|
END FUNCTION
|
|
|
|
FUNCTION Win% (Piece AS STRING)
|
|
FOR I = 0 TO 7
|
|
IF Board(WinPos(I, 0)) = Piece AND Board(WinPos(I, 1)) = Piece AND Board(WinPos(I, 2)) = Piece THEN Win = -1: EXIT FUNCTION
|
|
NEXT I
|
|
Win = 0
|
|
END FUNCTION
|