COMPILE c:\mpro\tictac.dpl
;WNSave existing window definitions
PUSHW
;WNDECLARE VARIABLES
DC wk me you my_squares your_squares places line col perms
DC start win player temp
DN yes comp user
;WNDEFINE AND SAVE FULL SCREEN WINDOW
WDEF S LI=0 CO=0 WI=80 DE=50
WSAVE S
START:
;WNDEFINE AND SHOW MAIN WINDOW
WDEF A LI=4 CO=28 WI=15 DE=10 PA=3 TXT=0 HI=14 FRA=2 DRA=14 SHA=s
WCLEAR A
;WNASSIGN START VALUES TO VARIABLES
CLEAR my_squares your_squares
;WNTake it in turns to start
IF start='me'
start='you'
ELSE
start='me'
ENDIF
me='X'
you='O'
win='Draw'
;WNList of possible winning lines
perms='123'+CR+'456'+CR+'789'+CR+'147'+CR+'258'+CR+'369'+CR+ &
'159'+CR+'357'
;WNList of possible squares
places='123456789'
;WNCo-ordinates of squares
TABLE A
'1=1 3'
'2=1 7'
'3=1 11'
'4=3 3'
'5=3 7'
'6=3 11'
'7=5 3'
'8=5 7'
'9=5 11'
$$
;WNAs above but vice-versa
TABLE B
'1 3=1'
'1 7=2'
'1 11=3'
'3 3=4'
'3 7=5'
'3 11=6'
'5 3=7'
'5 7=8'
'5 11=9'
$$
;WNDEFINE AND DISPLAY GRID
FILLSTR wk 'Ä' 11
WTEXT A wk LI=2
WTEXT A wk LI=4
FOR n=1 TO 5
wk='³'
IF n=2 OR
IF n=4
wk='Å'
ENDIF
WTEXT A wk LI=n CO=5
WTEXT A wk LI=n CO=9
NEXT n
;WNDISPLAY SCORES
WTEXT A 'Me' LI=7
WTEXT A 'You' LI=8
;WNSAVE DISPLAY
WSAVE A
IF start='you' THEN your_go
MY_GO:
WREST A
;WNassign my list of squares to variable
player=my_squares
;WNand check them
GOSUB check_go
;WNIf 3 squares in a line then display info panel
IFR 2 THEN end_game
;WNIf I have found a possible winning line
IFR 1
GOTO got_mine
ENDIF
;WNPretend I'm you and check your squares for a winning line
temp=my_squares
my_squares=your_squares
player=my_squares
GOSUB check_go
IFR 2 THEN end_game
my_squares=temp
;WNBlock your possible winning line
IFR 1
GOTO got_mine
ENDIF
;WNIf no possible winning lines pick a square at random
RAND n 8
n=n+1
wk=n
got_mine:
;WNSee if square is used
GOSUB check_place
;WNif it is then have another go
IFR 1 THEN my_go
;WNadd square to my list (in numeric order)
SUBSTR my_squares o wk
;WNGet co-ordinates of square
GOSUB get_place
;WNand display my 'X'
WTEXT A me LI=l CO=c TXT=14
;WNSee if I've got a winning line
player=my_squares
GOSUB check_go
;WNIf I have then show info panel
IFR 2 THEN end_game
;WNIf no more squares left show info panel
IF LEN(places)=0 THEN end_game
;WNSave display
WSAVE A
YOUR_GO:
;WNFind an empty square to start you off in
SLICE places 1 1 wk
GOSUB get_place
WA01:
;WNRestore previous display
WREST A
;WNDisplay scores
WTEXT A comp LI=7 CO=8
WTEXT A user LI=8 CO=8
;WNDisplay cursor
WTEXT A 'Û' LI=l CO=c TXT=15 PA=11
;WNWAIT FOR YOUR KEY PRESS
WAIT
;WNStop screen flicker
INVIS ON
;WNAllow escape from programme !!
IFKEY Esc THEN exit
;WNIF CURSOR KEY PRESSED ADJUST CURSOR CO-ORDINATES BUT KEEP WITHIN
;WNWINDOW CONFINES
IFKEY Down AND
IF l<5
l=l+2
ENDIF
IFKEY Up AND
IF l>1
l=l-2
ENDIF
IFKEY Left AND
IF c>3
c=c-4
ENDIF
IFKEY Right AND
IF c<11
c=c+4
ENDIF
;WNIF YOU SELECT CURRENT SQUARE
IFKEY Enter
;WNAssign cursor co-ordinates into variable
wk=l+' '+c
;WNFind out which square it is
TLU wk B wk
;WNSee if it is in use
GOSUB check_place
;WNIf it is then go round again
IFR 1 THEN wa01
;WNAdd square to your list
SUBSTR your_squares o wk
;WNDisplay your 'O'
WTEXT A you LI=l CO=c
;WNSee if you have a winning line
player=your_squares
GOSUB check_go
;WNIf you have show info panel
IFR 2 THEN end_game
;WNIf no more squares then show info panel
IF LEN(places)=0 THEN end_game
;WNSave new display
WSAVE A
;WNMy turn
GOTO my_go
ENDIF
;WNNo more valid key presses so go round again
GOTO wa01
CHECK_PLACE:
;WNWe will use return codes to pass info back to calling statement so
;WNset it it zero to start with.
SETR 0
;WNSee if place is still available
IF places CN wk
;WNIf it is then remove it from the list
FINDSTR places wk o
REPLSTR places o 1 ''
o=wk
;WNOtherwise
ELSE
;WNSet return code to 1 to indicate another choice required
SETR 1
ENDIF
RETURN
GET_PLACE:
;WNLook up co-ordinates of square
TLU wk A wk
;WNExtract line No.
GETWORD wk 1 line
l=line
;WNExtract column No.
GETWORD wk 2 col
c=col
RETURN
CHECK_GO:
;WNSave integer variable settings
PUSHIV
SETR 0
;WNFor each possible winning line
FOR n=1 TO 8
;WNSet tracking variable to zero
yes=0
;WNExtract winning combination
GETLINE perms n line
;WNCheck each number in line against players list of squares
FOR x=1 TO 3
SLICE line x 1 wk
;WNIf player matching number
IF player CN wk
;WNIncrement tracking variable
yes=yes+1
;WNRemove matched square from line
SUBSTR line x ' '
ENDIF
;WNCheck next number
NEXT x
;WNIf player has 3 squares in a row
IF yes=3
;WNSee who has won
IF player=my_squares
win='I win'
comp=comp+1
ELSE
win='You win'
user=user+1
ENDIF
;WNSet return code to trigger display of info panel
SETR 2
;WNExit the routine
GOTO check_go01
ENDIF
;WNIf its my turn and I have 2 squares in a row
IF player=my_squares AND
IF yes=2
;WNAssign remaining square No. into variable
TRIM line
wk=line
;WNIf square not already used
IF places CN wk
;WNSet return code to trigger use this square
SETR 1
;WNExit the routine
GOTO check_go01
ENDIF
ENDIF
;WNCheck next line
NEXT n
check_go01:
;WNRestore interger variable
POPIV
RETURN
END_GAME:
;WNUpdate scores
WTEXT A comp LI=7 CO=8
WTEXT A user LI=8 CO=8
;WNShow info panel
SHOWMSG LI=15 CO=26 WI=20 DE=7 PA=2 TXT=0 HI=14 FRA=2 DRA=14 SHA=s &
CEN ANY
win
''
'Another game ?'
''
'|Y|es |N|o'
$$
;WNHave another go if 'Y' or 'Enter'
IFKEY Enter OR
IFKEY 'y' THEN start
;WNQuit if 'Esc' or 'n'
IFKEY Esc OR
IFKEY 'n' THEN exit
;WNNo more valid key presses so go round again.
GOTO end_game
EXIT:
;WNRestore original screen
WREST S
;WNRestore previous window definitions
POPW
;WNEnd programme
END