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