SQUAREOLOGY (16K ZX81)
by J A Enness
from ZX Computing 1, Summer 1982, pages 124-126

J A Enness, Poole, Dorset, has written a well-documented program which plays a
game based on the old favourite where two players take turns to link dots in a
matrix, with each player trying to avoid placing a line in such a manner as to
allow the other to complete a square. If a player completes a square, it is
marked for the player, who then gets a second turn.

In this version the player plays against the computer, and a pattern of lines
is drawn up to start the game off at a more interesting level. The matrix is 12
x 9 dots giving 195 possible moves, the score and "whose turn", etc is printed
below. The pattern choice is not random in any manner and the same choice of
pattern number will result in the same pattern.

The patterns 1-9 will fill up 60 or so moves in the matrix and then return to
"Your move". Patterns from A-Z may or may not start with "Your move", and some
squares may be "claimed" by the pattern. These will be marked with an "/" in
the centre and are not counted on the score. If 0 is the choice of pattern then
no pattern will be produced and the game will start with "Your move".

After taking your move the computer will react "My move" followed by "Search".
The search routine then checks all 195 possible moves to see if it can claim
any squares. If it can, it will complete the square and start again with "My
move". Unfortunately the search takes approximately 12 seconds. This routine
may be altered to a FAST mode by inserting a new line 153 FAST followed by a
new line at 167 SLOW.

This means that the screen will blank out for a couple of seconds during the
search, which in my opinion is not so good. If the search is unsuccessful the
word "Search" is followed by an "X" after which it makes its choice of move.
This is reasonably fast and normally takes only a second or two depending on
the complexity of the situation. It does this by the simple reasoning: if one
of its choices is impractical then it will not take that move into account
again.

When the grid becomes so full that it is impossible to move without giving any
squares away, the program is not able to take into account how many squares you
can claim from its move. For this reason the computer scores two points for
every square it takes.

The ultimate object being not only to win, but to beat the computer 88 to 0,
which is almost impossible. If, however, you beat it by 50 points (which is
very difficult), the coveted "Congratulations" line prints up. The BREAK key
will stop the program at any time. (This can be useful for sampling the
patterns by simply: BREAK, RUN, another choice of pattern number.) Working out
where the computer is going to move next has been deliberately made difficult
to follow after its first couple of moves.


THE PROGRAM

Lines 2-10 set up the instructions. Note:- Double words, (eg. fora) are
separated by the end of one line and the beginning of the next.

Line 12 goes to an INKEY$ trap. (Sub 400.) The program will not continue until
a key is pressed. The value of the key is recorded in Z$. Not used in this case.

Lines 16-26 set up the variables. A:- Keeps a record of the 195 possible moves.
V:-Records the score. C:-Defines "whose move". F:-Starts the computer's turn
position. G:-Indicates if there are any safe moves left. I:-Is used to search/
modify the data in A.

Lines 28-52 set up the display grid etc.

Lines 54-60 set up D which is used for the pattern routine.

Lines 62-64 set up "My score", "Your score". These look better in inverse
characters. Sub 420 simply blanks out the line at 19, 0; and sets the next
print position again for this line.

Lines 66-72 sort out whose move. (The pattern starts at 220. The "My move"
starts at 150.)

Lines 74-100 set up all the variables and traps for "Your moves" choice. X =
Value for the position across the grid. This can be from 0 to 11. (0 for A, 1
for B and C, 2 for D and E etc.) This, together with information of whether an
odd or even line number down, sorts out the print position. This arrangement
prevents illegal entries on the dots or in the middle of the squares. Y = the
up/ down position.

Line 102 goes to the last line of Sub 470 to get the odd or even number which
is stored in E. E=0 for even, 1 for odd.

Lines 104-106 again prevents illegal entries and prevents entering a move
already taken.

Lines 108-110 store and print a move.

Line 112 Q = The number of sides to be taken into account in Sub 440. Sub 430
simply zeros J, K, L and M in Sub 440 these variables change to 1 if any of the
four directions possible from a position has Q number of sides altogether (eg
in this case Q = 4 thus any four sides in any four directions will let J, K, L
or M at least equal 1).

Lines 118-126 If the four sides of a square are present, then the program will
go to various parts of subroutine 480. This routine works out by J, K, L or M,
the direction of the print statement, which will 'black' the squares and insert
an "*" a " -" or a "/" depending upon whose move claimed the square. This
simply takes the value of whose turn (in C) adds 22 and prints the CHR$. U is
simply used to help simplify the print statements.

Line 128 If there is no pattern or winning move then let C = ABS (C-1). This
changes the player's turns. If C=1 it becomes 0 and vice versa.

Lines 130-134 sort out the score. If all 88 squares are taken then the game
finishes at line 144 where pressing any key starts another game. Otherwise line
136 starts the next turn by jumping back to line 64.

Lines 150-166 Starts the search routine during "My turn" using part of Sub 440,
only this time Q = 3. If L or M = 1 then its found a three-sided square. In
this case line 200-210 loop around until the missing side position is found.
Since "My turn" looks directly at a position (I) and doesn't choose X, Y
co-ordinates then sub routine 470 supplies X, Y, and E, it then jumps back into
the original program at Line 106 having worked out its move.

Lines 168-196 constitute the computer's turn if the search for three sides is
unsuccessful. This will choose any untaken position other than one which will
make up more than two sides in any square. (Q = 2 this time.) It starts at
position two (I) and jumps in steps of 60, to find a suitable position. If I >
195 then let I = I -193 keeps this within the "A" boundary. This tests each
number from 2 to 195 without repeating, looking reasonably at random. Once 195
is reached G = 1 and Q = 4 allowing the next available position to be taken.
This time at line 196 we return to the main program 104, to allow a little
longer to display the "My moves" choice (line 194). (X * 2 + 37 + E) works out
the relevant letter.

Note: If you wish to set up the pattern fast then insert line 221 FAST and line
69 SLOW.


[The magazine listing contains a couple of errors. The lines affected should
be as follows:

   118 LET U=X*2+4
   162 IF L=1 OR M=1 THEN GOTO 200

Note that the original code for line 162 works ok since it checks 'L OR M=1'
but the clear intention is that the line should have been checking for
'L=1 OR M=1'.

The display when the computer is making its move can be improved through the
addition of a space in the following line:

   168 PRINT " X";

The game allows some illegal entries. For example, entering B3 will insert a
grey square at C3, and entering C4 will insert a grey square at B4. These
illegal entries can be prevented by adding the following lines:

    79 LET EX=INT (CODE Z$/2+0.5)*2-CODE Z$
   105 IF E=EX THEN GOTO 64
]