10 REM A BASIC program to play Tic-Tac-Toe. 20 REM Copyright 2012 by Stephen Beitzel sbeitzel@pobox.com 30 REM Released under the Perl Artistic License 2.0 40 REM See http://www.perlfoundation.org/artistic_license_2_0 50 REM Set up the board 51 GOSUB 200 60 REM Display the board 61 GOSUB 500 65 REM Choose who goes first 66 GOSUB 300 67 p = 1 70 REM If game is over, print the game over message 71 GOSUB 5000 72 IF w = 1 OR w = 2 THEN 73 PRINT "Player ";w;" wins!" 74 GOTO 120 75 END IF 76 IF os = 0 THEN 77 PRINT "It's a tie!" 78 GOTO 120 79 END IF 80 REM Get move from the current player 81 IF p = cp THEN 82 GOSUB 2000 83 ELSE 84 GOSUB 1000 85 END IF 90 REM 1) record the move, 2) switch current player 91 board%(m) = p 92 p = 3 - p 100 REM Display the board 110 GOSUB 500 115 GOTO 70 120 PRINT "Game over!" 130 END 200 REM Subroutine to set up the board 210 DIM board%(8) 220 LOCAL i 230 FOR i=0 TO 8 240 board%(i) = 0 250 NEXT i 260 RETURN 300 REM Subroutine to choose whether the computer goes first or second 310 PRINT "Does the computer go first or second? To have the computer" 311 PRINT "go first, type a '1'. To have the computer go second, type" 312 PRINT "a '2'." 313 input cp$ 320 IF left$(cp$,1)="1" THEN 330 cp = 1 340 ELSE 350 cp = 2 360 END IF 370 RETURN 500 REM Subroutine to draw the board 510 PRINT "" 520 PRINT " A B C " 530 LOCAL i, line$ 540 FOR i=1 to 3 550 line$ = str$(i)+" " 560 for j=0 to 2 565 x = (i-1)*3 + j 570 if (board%(x) = 0) then 580 line$ = line$+" " 590 ELSE 600 IF (board%(x) = 1) THEN 610 line$ = line$+"X " 620 ELSE 630 line$ = line$+"O " 640 END IF 650 END IF 660 IF j < 2 THEN 670 line$ = line$+"| " 680 END IF 690 NEXT j 700 PRINT line$ 710 IF i < 3 THEN 720 PRINT " ---+---+---" 730 END IF 740 NEXT i 750 PRINT "" 760 RETURN 1000 REM Get a move from the keyboard 1004 PRINT "Choose a spot. Specify the column first and then the row" 1005 input m$ 1010 m$ = lcase$(m$) 1020 REM m$ will be of the form /[abc][123]/ 1030 c$ = left$(m$,1) 1035 r$ = mid$(m$, 2, 1) 1040 IF r$ = "1" THEN 1050 i = 0 1060 ELSE 1070 IF r$ = "2" THEN 1080 i=1 1090 ELSE 1100 IF r$ = '3' THEN i=2 ELSE i=9 1110 END IF 1120 END IF 1130 IF c$ = "a" THEN 1140 j = 0 1150 ELSE 1160 IF c$ = "b" THEN 1170 j = 1 1180 ELSE 1190 IF c$ = "c" THEN j = 2 ELSE j = 9 1200 END IF 1210 END IF 1230 m = (i*3)+j 1240 REM We need to be sure it's a legal move before we return. 1250 IF m < 0 OR m > 8 THEN 1260 1255 IF (board%(m) <> 0) THEN 1260 1256 RETURN 1260 PRINT "That is not a valid spot. Please try again." 1270 GOTO 1005 2000 REM The computer chooses a move 2001 REM First, look to see if we're about to win. If so, play to win. 2002 DIM wins(8, 3) 2010 wins(1, 1) = 0 2011 wins(1, 2) = 1 2012 wins(1, 3) = 2 2013 wins(2, 1) = 3 2014 wins(2, 2) = 4 2015 wins(2, 3) = 5 2016 wins(3, 1) = 6 2017 wins(3, 2) = 7 2018 wins(3, 3) = 8 2019 wins(4, 1) = 0 2020 wins(4, 2) = 3 2021 wins(4, 3) = 6 2022 wins(5, 1) = 1 2023 wins(5, 2) = 4 2024 wins(5, 3) = 7 2025 wins(6, 1) = 2 2026 wins(6, 2) = 5 2027 wins(6, 3) = 8 2028 wins(7, 1) = 0 2029 wins(7, 2) = 4 2030 wins(7, 3) = 8 2031 wins(8, 1) = 2 2032 wins(8, 2) = 4 2033 wins(8, 3) = 6 2040 FOR w=1 to 8 2050 ix = checkForWin(cp, wins(w, 1), wins(w, 2), wins(w, 3)) 2060 IF ix <> -1 2070 m = wins%(w, ix) 2080 RETURN 2090 EXIT FOR 2100 END IF 2110 NEXT w 2351 REM Next, look to see if the opponent is about to win. If so, we need to play to block. 2360 FOR w=1 to 8 2370 ix = checkForWin(3-cp, wins(w, 1), wins(w, 2), wins(w, 3)) 2380 IF ix <> -1 2390 m = wins(w, ix) 2400 RETURN 2410 EXIT FOR 2420 END IF 2430 NEXT w 2800 REM Finally, play in an open square. Center, corners, sides 2810 IF board%(4) = 0 2811 m = 4 2812 RETURN 2813 END IF 2820 IF board%(0) = 0 2821 m = 0 2822 RETURN 2823 END IF 2830 IF board%(8) = 0 2831 m = 8 2832 RETURN 2833 END IF 2840 IF board%(6) = 0 2841 m = 6 2842 RETURN 2843 END IF 2850 IF board%(2) = 0 2851 m = 2 2852 RETURN 2853 END IF 2860 IF board%(1) = 0 2861 m = 1 2862 RETURN 2863 END IF 2870 IF board%(3) = 0 2871 m = 3 2872 RETURN 2873 END IF 2880 IF board%(5) = 0 2881 m = 5 2882 RETURN 2883 END IF 2890 IF board%(7) = 0 2891 m = 7 2892 RETURN 2893 END IF 2999 RETURN 4000 SUB checkForWin( player, a, b, c) 4001 REM If two of the three values are marked by player and the third value is unmarked 4002 REM then return the index of the unmarked value (1, 2, or 3). If not, return -1. 4010 rv = -1 4020 IF board%(a)=board%(b) AND board%(a)=player AND board%(c)=0 THEN 4021 rv = 3 4022 GOTO 4990 4025 END IF 4030 IF board%(a)=board%(c) AND board%(a)=player AND board%(b)=0 THEN 4031 rv = 2 4032 GOTO 4990 4035 END IF 4040 IF board%(b)=board%(c) AND board%(b)=player AND board%(a)=0 THEN 4041 rv = 1 4042 GOTO 4990 4045 END IF 4990 checkForWin = rv 4999 END SUB 5000 REM Subroutine to analyze the board. If there are no moves available 5001 REM or if one player has won, then go to the "game over" line, 5002 REM otherwise we just return. 5005 os = 0 5010 FOR i=0 to 8 5020 IF board%(i) = 0 THEN os = 1 5030 NEXT i 5040 IF os THEN 5050 REM there is at least one open spot. Check for a win. 5051 REM There are only 8 possible wins. 5060 w = 0 5070 if (board%(0) = board%(1) and board%(1) = board%(2) and board%(0) <> 0) THEN w = board%(0) 5075 if w <> 0 then return 5080 if (board%(3) = board%(4) and board%(4) = board%(5) and board%(3) <> 0) THEN w = board%(3) 5085 if w <> 0 then return 5090 if (board%(6) = board%(7) and board%(7) = board%(8) and board%(6) <> 0) THEN w = board%(6) 5095 if w <> 0 then return 5100 if (board%(0) = board%(3) and board%(3) = board%(6) and board%(0) <> 0) THEN w = board%(0) 5105 if w <> 0 then return 5110 if (board%(1) = board%(4) and board%(4) = board%(7) and board%(1) <> 0) THEN w = board%(1) 5115 if w <> 0 then return 5120 if (board%(2) = board%(5) and board%(5) = board%(8) and board%(2) <> 0) THEN w = board%(2) 5125 if w <> 0 then return 5130 if (board%(0) = board%(4) and board%(4) = board%(8) and board%(0) <> 0) THEN w = board%(0) 5135 if w <> 0 then return 5140 if (board%(2) = board%(4) and board%(4) = board%(6) and board%(2) <> 0) THEN w = board%(2) 5145 if w <> 0 then return 5150 END IF 5160 REM If we're here, it means that there's no winner and there is an open spot. 5170 RETURN
One thought on “Tic-Tac-Toe”