TIC-TAC-TOE 1 PLAYER

This module is part of the original MMBasic library. It is reproduced here with kind permission of Hugh Buckle and Geoff Graham. Be aware it may reference functionality which has changed or is deprecated in the latest versions of MMBasic.

TICTAC.BAS:

' TIC-TAC-TOE 1 PLAYER
Mode 4
f=7
background:
  b=random(6)
  If b=6 Or b=3 Or b=2 Then f=0
Color f,b
Dim pk(9)
Cls
For x=0 To 99:t=Val(Inkey$):Next x
Font 2,1:Print "   Tic-Tac-Toe"
Font 1,1:Print "       X = You    O = Computer"
Print:Print "        Enter your move (1-9)"
Print @(75,80) "7  ";
Print CLR$(Black,White) " ";
Print "8  ";
Print CLR$(Black,White) " ";
Print "9"
Print @(93,90);:GoSub spaces
Print @(93,100);:GoSub spaces
Print @(75,110);:GoSub bars
Print @(75,120) "4  ";
Print CLR$(Black,White) " ";
Print "5  ";CLR$(Black,White) " ";
Print "6  "
Print @(93,130);:GoSub spaces
Print @(93,140);:GoSub spaces
Print @(75,150);:GoSub bars
Print @(75,160) "1  ";
Print CLR$(Black,White) " ";
Print "2  ";
Print CLR$(Black,White) " ";
Print "3  "
Print @(93,170);:GoSub spaces
Print @(93,180);:GoSub spaces
T=1

' X'S TURN

xkeyinput:
     P=Val(Inkey$)
     If P<1 Or P>9 GoTo xkeyinput
     If PK(P)<>0 Then Tone 500,500,200:Pause(200):Tone 500,500,200:GoTo xkeyinput
     PK(P)=88:GoSub display
If T=5 GoTo done

' O'S TURN

 O=158:If T>1 GoTo checkall
 If PK(5)=0 Then P=5:GoTo omove
 P=2*Int(Rnd(2)*2)+1:GoTo omove

checkall:  'First check for winning position
 If PK(1)+PK(2)=O And PK(3)=0 Then P=3:GoTo omove
 If PK(1)+PK(3)=O And PK(2)=0 Then P=2:GoTo omove
 If PK(2)+PK(3)=O And PK(1)=0 Then P=1:GoTo omove
 If PK(4)+PK(5)=O And PK(6)=0 Then P=6:GoTo omove
 If PK(4)+PK(6)=O And PK(5)=0 Then P=5:GoTo omove
 If PK(5)+PK(6)=O And PK(4)=0 Then P=4:GoTo omove
 If PK(7)+PK(8)=O And PK(9)=0 Then P=9:GoTo omove
 If PK(7)+PK(9)=O And PK(8)=0 Then P=8:GoTo omove
 If PK(8)+PK(9)=O And PK(7)=0 Then P=7:GoTo omove
 If PK(1)+PK(4)=O And PK(7)=0 Then P=7:GoTo omove
 If PK(1)+PK(7)=O And PK(4)=0 Then P=4:GoTo omove
 If PK(4)+PK(7)=O And PK(1)=0 Then P=1:GoTo omove
 If PK(2)+PK(5)=O And PK(8)=0 Then P=8:GoTo omove
 If PK(2)+PK(8)=O And PK(5)=0 Then P=5:GoTo omove
 If PK(5)+PK(8)=O And PK(2)=0 Then P=2:GoTo omove
 If PK(3)+PK(6)=O And PK(9)=0 Then P=9:GoTo omove
 If PK(3)+PK(9)=O And PK(6)=0 Then P=6:GoTo omove
 If PK(6)+PK(9)=O And PK(3)=0 Then P=3:GoTo omove
 If PK(1)+PK(5)=O And PK(9)=0 Then P=9:GoTo omove
 If PK(1)+PK(9)=O And PK(5)=0 Then P=5:GoTo omove
 If PK(5)+PK(9)=O And PK(1)=0 Then P=1:GoTo omove
 If PK(3)+PK(5)=O And PK(7)=0 Then P=7:GoTo omove
 If PK(3)+PK(7)=O And PK(5)=0 Then P=5:GoTo omove
 If PK(5)+PK(7)=O And PK(3)=0 Then P=3:GoTo omove
 If O=158 Then O=176:GoTo checkall: 'Now check to block
 If PK(8)+PK(6)+PK(3)=O And PK(9)=0 Then P=9:GoTo omove
 If PK(8)+PK(4)+PK(1)=O And PK(7)=0 Then P=7:GoTo omove
 If PK(2)+PK(6)+PK(9)=O And PK(3)=0 Then P=3:GoTo omove
 If PK(2)+PK(4)+PK(7)=O And PK(1)=0 Then P=1:GoTo omove
 If PK(6)+PK(8)+PK(7)=O And PK(9)=0 Then P=9:GoTo omove
 If PK(6)+PK(1)+PK(2)=O And PK(3)=0 Then P=3:GoTo omove
 If PK(4)+PK(2)+PK(3)=O And PK(1)=0 Then P=1:GoTo omove
 If PK(4)+PK(8)+PK(9)=O And PK(7)=0 Then P=7:GoTo omove
' smart code makes x winning impossible:
  If pk(5)+pk(9)=o And pk(3)=0 Then p=3:GoTo omove
  If pk(5)+pk(9)=o And pk(7)=0 Then p=7:GoTo omove
  If pk(5)+pk(7)=o And pk(1)=0 Then p=1:GoTo omove
  If pk(5)+pk(7)=o And pk(9)=0 Then p=9:GoTo
  If pk(1)+pk(9)=o Or pk(3)+pk(7)=o Then p=even(4):GoTo omove

getrndmove:  'get a random move for O
 P=random(9):If PK(P) GoTo getrndmove
omove:
 PK(P)=79:GoSub display
 If T=5 Then GoTo done
 T=T+1:GoTo xkeyinput

done:  'end of game
  Print " Game";
  For x=0 To 50
Tone Rnd(1)*3000+100:Pause 50:Next x
Run

display:
 If P=1 Then Print @(80,170);
 If P=2 Then Print @(106,170);
 If P=3 Then Print @(132,170);
 If P=4 Then Print @(80,130);
 If P=5 Then Print @(106,130);
 If P=6 Then Print @(132,130);
 If P=7 Then Print @(80,90);
 If P=8 Then Print @(106,90);
 If P=9 Then Print @(132,90);
 Print Chr$(PK(P))
 X=PK(1)+PK(2)+PK(3):GoSub win
 X=PK(4)+PK(5)+PK(6):GoSub win
 X=PK(7)+PK(8)+PK(9):GoSub win
 X=PK(1)+PK(4)+PK(7):GoSub win
 X=PK(2)+PK(5)+PK(8):GoSub win
 X=PK(3)+PK(6)+PK(9):GoSub win
 X=PK(1)+PK(5)+PK(9):GoSub win
 X=PK(3)+PK(5)+PK(7):GoSub win
 Return

spaces: Print CLR$(Black,White);" ";
        Print "   ";
        Print CLR$(Black,White);" ":Return

bars:
  Print CLR$(Black,White);"           ":Return

win:   'check for win
  If X=264 Then T=5:Print @(150,120) " X Wins";
  If T<5 And X=237 Then T=5:Print @(150,120) " O Wins";
  Return

Function random (z)   'random # from 1 to z
  q=Int(Rnd(1)*(z+2))
  If q>z Then q=z
  If q<1 Then q=1
  random=q
  End Function

Function even (z)    'returns random even # from 2 to z
  another:
  q=2*random(z)
  If PK(q)<>0 Then another
  even=q
  End Function