\ Program: Tic-Tac-Toe \ Author: James Matthews. \ \ Description: \ This is a Forth implementation of TTT with very simple AI. \ It happens to be my first Forth program, so please bear with \ my coding. Written for Generation5: \ http://library.advanced.org/18242/ CR CR .( TicTacToe - by James Matthews. ) CR .( Written for Generation5 [http://library.advanced.org/18242] ) CR .( Starting tictactoe...) \ Constants 0 CONSTANT NOTHING 1 CONSTANT HUMAN 2 CONSTANT COMPUTER \ Variables VARIABLE LASTEMPTY \ Last empty space in loop. VARIABLE NUMENEMY \ Number of enemies in the line. VARIABLE HORIZONTAL \ Check horizontal or vertical? VARIABLE OPENSPACE \ Last open space on board...bad AI. VARIABLE MOVED \ Have we moved? VARIABLE WON \ Has someone won the game? \ Initializes the board. CREATE BOARD \ Create the board! 9 CELLS ALLOT \ Allot 9 (3x3) cells. \ Various board functions. : BOARDOFFSET ( n -- addr ) CELLS BOARD + ; : SETBOARD ( ) BOARDOFFSET ! ; : BOARDAT ( ) BOARDOFFSET @ ; \ Draw the board : DRAWBOARD ( -- ) cr cr ." Board:" cr \ Print message. 3 3 \ Put row/col on stack. 0 ?DO CR DUP \ Outer loop (col) 0 ?DO \ Inner loop (row) I J 3 * + \ Calculate array index. DUP BOARDAT HUMAN = IF ." [X]" SPACE THEN DUP BOARDAT COMPUTER = IF ." [O]" SPACE THEN BOARDAT NOTHING = IF ." [ ]" SPACE THEN LOOP LOOP DROP CR ; : COMPUTERMOVE ( ) FALSE MOVED ! \ We haven't moved yet. \ Always try for centre if possible. 4 BOARDAT NOTHING = IF COMPUTER 4 SETBOARD ELSE -1 OPENSPACE ! TRUE HORIZONTAL ! \ Check horizontal first. 2 0 ?DO \ Repeat once. 3 0 ?DO CR \ Loop through cells. -1 LASTEMPTY ! \ Reinitialize lastempty. 0 NUMENEMY ! \ Ditto. 3 0 ?DO \ Loop through cells. \ Are we checking horizontally or vertically? HORIZONTAL @ TRUE = IF I J 3 * + DUP \ Calculate horizontally. ELSE J I 3 * + DUP \ Calculate vertically. THEN BOARDAT HUMAN = IF 1 NUMENEMY +! THEN DUP BOARDAT NOTHING = IF LASTEMPTY ! ELSE DROP THEN LOOP \ If it DOESN'T EQUAL -1. LASTEMPTY @ -1 = 0= IF LASTEMPTY @ OPENSPACE ! THEN NUMENEMY @ 2 = IF \ Can we block this? LASTEMPTY @ -1 = 0= IF COMPUTER LASTEMPTY @ SETBOARD TRUE MOVED ! THEN THEN NUMENEMY @ 3 = IF \ Aw, dude, we lost. CR ." You won!" \ Print message. TRUE WON ! \ Win flag. -1 OPENSPACE ! \ To print 'Game Over' message. THEN LOOP FALSE HORIZONTAL ! \ Now, check vertical. LOOP OPENSPACE @ -1 = IF CR ." Game over." TRUE WON ! \ No one has won, but end of game. ELSE MOVED @ FALSE = IF COMPUTER OPENSPACE @ SETBOARD THEN THEN THEN ; : TTTMOVE ( n1, n2 -- moves) 1 - SWAP 1 - 3 * + DUP DUP 8 > IF CR ." Bad row or column! Please re-enter... " DROP ELSE BOARDAT @ NOTHING = IF HUMAN SWAP SETBOARD DRAWBOARD COMPUTERMOVE WON @ FALSE = IF DRAWBOARD THEN ELSE CR ." Piece exists there. Please re-enter..." DROP THEN THEN ; : RUN ( -- ) PAGE CR ." You are X, the computer is O. " CR ." To move, type [ROW] [COL] TTTMOVE " DRAWBOARD ; CR .( Start the game by typing RUN...)