3D NOUGHTS & CROSSES

--------------------

Add a new dimension to this popular game with this program for your 48K

Spectrum from Bill Welch of Herne Hill.





This is a game played on a cubical "board" containing 27 spaces, any one of

which can be filled with a nought or a cross. The board is represented on the

screen by three conventional noughts and crosses boards placed one above the

other. The levels are labelled A, B and C and the spaces on each level are

numbered from one to nine. The object of the game is not to make the first

row of three  that is too easy for the player who goes first  but to make

more complete rows than your opponent, the computer.



When the program is RUN, the computer asks you to choose a skill level, then

draws the board and asks if you want to go first. The computer plays the 'X'

and you play the 'O'. Any row of three will count, whether horizontal,

vertical or diagonal; some of them are hard to spot at first, but you'll soon

get the hang of it. There are 49 possible rows. Examples: A1, B1 and C1 make

a row, and so do A1, B5 and C9. If you change your mind halfway through

entering a move, press any obviously wrong key and you will be able to start

your entry again.



In between each move the computer checks through all the possible rows and

counts any completed ones by making an audible blip. The blip is higher for

the computer's rows than for yours, so you can listen to your progress.



The computer is hard to beat at first, especially at level three, but it can

be done, especially if you go first! Why not try to improve the computer's

game? You can see how its strategy is organised by reading the program notes

and you could, for example, change the order in which it checks for almost

complete rows by changing the order of the numbers 1-49 in the DATA

statements at lines 1060-1080.



Variables



To save on memory use, most of the variables are only temporary, and are used

for different purposes in different parts of the program. These are the

variables which have a single constant use:



a$       Contains the character of the key last pressed when an input

          was requested.

a()     - An array containing one element for each of the 27 spaces on

          the board.

b()      An array containing one element for each of the 49 possible

          rows of three.

level    The skill level which has been selected.

posn     The number of the element of a() corresponding

          to the move which has been selected by you or the computer.

go       The number of moves which have been made.

m        An indicator of whose turn it is to move.



Other variables used are: g, f, a, b, p, q, t and no.



Memory



As listed, this program will not run on a 16K machine  it uses more than

8,300 bytes. However, it could be compressed for a 16K machine by omitting

the REM statements and perhaps using some of the standard Sinclair memory

saving methods. For example, numbers can be referred to using the VAL

function; eg. PRINT AT VAL "22",VAL "2"; and so on. Again, some of the lines

can be run together with the use of colons.



Program notes



Line 5          Calls the instructions subroutine at line 9900.

Lines 20-70     Define the 'X' and 'O' graphics characters.

                This short routine, with the appropriate DATA

                statements, can be used to define any number

                of characters up to the maximum of 21.

Lines 80-90     Initialise the arrays a() and b(), and the move

                counter, and set the screen attributes for the game.

Line 95         POKE 23658,8 sets CAPS LOCK at capitals,

                which simplifies mug-trapping. POKE 23659,1

                allows you to PRINT AT line 22.

Lines 100-175   Set up the board.

Lines 180-198   Set who is to go first. Line 190 calls an INKEY$

                subroutine at line 9500 which stores

                the key pressed in a$, Note line 194; the effect

                of the commas after a PRINT AT statement is to

                blank out half a line per comma in the current

                PAPER colour. m is set to zero when it is the

                computer's move, and one when it is your move.

                If the computer is to go first, the program jumps

                to 1000.

Lines 200-350   Ask for your move, and mug-trap the results

                (again returned in a$). An acceptable move is

                turned into a number from one to 27 and stored

                in the variable, posn, for use later when

                displaying the move on the screen The corresponding

                element of array a() is checked to see if it is empty;

                if it is, a four is inserted. (Four is used for human's

                moves, and one for the computer's moves.) The program

                then jumps to line 8000.

Lines 1000-7910 These are used for the computer's moves.

Line 1005       Lets you know that the computer is working out

                its move. After each stage of working, if the computer

                has not found an acceptable move it will add an extra

                full stop after "I'M THINKING ..." so that you can see

                how hard it has had to think!

Lines 1010-1025 If the centre space is empty, the computer will always

                choose to go there. The centre space corresponds to

                element 14 in array a(). Once a move has been chosen,

                the computer always jumps to line 8000. If the centre

                space has already been filled, the computer will move

                on to line 1030.

Line 1030       At skill level one, the computer skips the rest

                of its strategy and jumps to a routine at line 7000

                which generates a random move. Lines 1060-1080 Contain DATA

                which tells the computer the order in which

                it is to scan array b() for the next steps in its strategy.

Line 1105       At skill level two, the computer skips the next two steps

                of its strategy.

Lines 1110-1135 Each element of array b() contains the sum of

                the numbers held in three elements of array a()

                corresponding to a row of three spaces on the

                board. For example. a(1) plus a(2) plus a(3)

                corresponds to the state of the row from the

                top far left of the board (space A1) to the top

                far right (space A3). This total is stored in one

                of the elements of array b(). In this section of

                the program, the computer checks through array b()

                looking for the number '8', which represents a row

                on the board containing two 'O's and an empty space.

                If thecomputer finds such a row, it jumps to a routine

                at line 7500 which will identify the empty space so

                that the computer can put an 'X' there to block your row.

Lines 1140-1175 If you are not in a position to complete a row next move,

                the computer checks through array b() again, this time

                looking for the number '2'. This corresponds to a row on

                the board containing two Xs and a blank space. If such a

                row is found, the computer again jumps to line 7500 so

                that it can identify the empty space and complete a row

                of Xs.

Lines 1180-2010 Failing these, the computer looks for a row containing

                two blank spaces and one X. If it finds one, it will

                insert another X, threatening to complete a row on its

                next move.

Lines 2015-2055 If the computer can find none of these possibilities,

                it will check array a() in the order

                given in the DATA statement in line 2055 to

                see if any of the centre face or corner spaces

                are empty. It will make its move in the first one

                it finds. Plenty of space is left between lines

                2055 and 7000 to insert more checks if you

                want to elaborate on the computer's strategy.

Lines 7000-7030 Generate a random move in any empty space

                on the board.

Lines 7500-7800 Contain a routine used by the computer to find

                which of the spaces, in a line it has identified in

                one of its scans of array b(), is empty. On exiting

                from this routine, the temporary variable - a -

                indicates the appropriate empty element in array a().

Line 7900       Puts the computer's move into array a() and also into

                the variable - posn - for later use when displaying the move.

Lines 8000-8080 Find the correct screen address for the selected move

                and print an 'X' or 'O' as appropriate. The 'O' is a

                Graphics A and the 'X' is a Graphics B. The selected

                move is also displayed at the bottom of the screen.

Lines 8500-8745 Scan through array a() in all the combinations of three

                elements which correspond to a row of three on the board.

                In each case the sum of the three elements is stored in an

                element of array b() by means of a subroutine at line 9600.

                The temporary vartable - a - is given the value 9600 to

                shorten the repeated calls to this subroutine.

Lines 8750-8770 Increase the move counter by one and check

                for the end of the game.

Line 8810       Blanks out the message line at the bottom of the screen.

Line 8820       If m is one, it becomes zero; if zero, it becomes one.

                This indicates whether it is your move or the computer's.

                This neat line was borrowed from J.A. Enness's program,

                Squareology, in ZX Computing, Summer 1982.

Line 8830       Jumps to line 1000 if it is the computer's move next,

                or line 200 if it is your move next.

Lines 9000-9050 When the game is over, this routine counts the completed

                rows of Os and Xs by scanning array b().

Lines 9200-9480 Display the final score and suitable messages, with

                jubilant or otherwise sound effects.

                (Room for improvement here, if you're interested.)

                You are asked if you want to play again. After the POKEs

                in line 95, if you break into direct command mode without

                POKE 23659,2 (line 9460) you will get a very strange

                screen display!

Lines 9500-9540 Contain an INKEY$ subroutine which waits for a key

                to be pressed, and stores the result in a$ for return.

Lines 9600-9640 Contain the subroutine used by the section of the program

                starting at line 8500. After each move, it stores the

                state of each possible row of three in an element of

                array b(). It gives a low blip when it finds a row of Os,

                and a higher one when it finds a row of Xs. It keeps quiet

                about mixed or empty lines.

Lines 9900-9995 Contain the subroutine which displays the instructions

                and sets the skill level.