' 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