At first some CSS stuff. For this game I juggled with classes which contain different background images for table cells.
Now to the actual script. At first there are the usual declarations of global variables.
If it is the computer's turn, this variable is
. It's used to block further actions from the player.
the colors of both parties
if the player wants to see the flip counts
is an empty cell,
is a white disc,
is a black disc
contains possible legal moves
A matrix of values to evaluate the worth of positions on the board for the A.I.
The edges are most important because they cannot be taken by the other player anymore. The fields next to the edges are the worst ones, because those usually lead to the other player getting the edge. The fields on the boarder have higher values than those in the middle, because the latter ones change their owner frequently.
the two variables to count the discs currently on the board
The following function initializes the game. It clears all discs from the board, resets the arrays of possible moves and places the 4 starting discs.
function is invoked when the player presses the
button. It calls
, checks the current possibilities, hides the button, and either calls the A.I. if it plays black or shows the flipcount for the player (if he wished so).
The following function checks, if there are any possible moves at the moment.
places the player's disc and initiates the computer's move.
Of course a move is only possible, if there is no disc currently on this field.
Also the move has to be part of the
disallow further actions until the computer finished his move
put the disc
flips the discs between the new placed disc and discs already on the board
clears the flipcounts
Finally the new possibilities for the computer are checked.
If a move is possible, the A.I. is called.
Otherwise the player can put another disc, if he has possible moves. If even that is not the case, the game is over.
If the game is over, there's some stuff written on the board and the
button is shown again.
does the same, except that it doesn't switch the graphics
The following function is used to make changes to a certain position on the board.
parameter is used for the flipcounts. Those of course are only shown if it's the player's turn, i.e. if
is used to clear a field.
The other colors are for white and black. The following part either flips a disc or puts a new one. After the rotating animation is played, it's also replaced by a static image.
Now the discs for both parties are counted.
What follows is quite a huge function. This is for determining the legal possible moves for either player. Those are added to the
At first this array has to be reset.
Afterwards the color of the opponent is determined.
Now for each disc of
there are some checks.
The row and column of the current disc are calculated.
Now the current row is checked for empty fields. Of course the current field and also the adjacent fields are left out.
If an empty field is found it's checked if all the fields between the selected field and the empty one belong to the opponent. If this is the case
is incremented and the fields are added to
, if not both variables are reset and the next empty field is checked.
The same procedure for the discs in the same column...
Accordingly for diagonal lines...
Finally the heart of the game, the artificial intelligence. I tried to make it as simple but effective as possible. Of course you can somewhat trick it if you know which moves it prefers, so if you still want to enjoy the game, go ahead to the HTML part at the bottom. However if you still want to know how it works, go on.
The best moves are always those where the opponent cannot move in the next turn (this way you can also find out possible wipe-outs). So at first it's checked, if such moves exist. To do that, the
function from above is used. After flipping all the necessary discs for one possible move the
function is called for the player and afterwards
checks, if the player has any legal moves. If he doesn't, this move is instantly added to the computer's choice.
If no moves were found yet the next target are the edges.
If there's still no success, check the fields on the boarders except for those adjacent to the edges. Those are of the same importance under the circumstance, that the edge is already occupied, so this is checked directly afterwards.
If still no move was found, the third row and column from the outside is checked and the fields diagonally adjacent to the edges, if the edge is already conquered.
You know the deal... no move found yet, so look further. This time for the second row and column from the outside...
... the horizontal and vertical adjacent fields to the edges, no matter if the edge is conquered or not...
... and finally the diagonally adjacent fields. Now all fields were checked.
Now the computer has to choose the best move from those that were found out. During the first 10 moves those are decided by chance. This way the computer may choose moves that leave him with far less discs on the board than his opponent. During the beginning of the game this can be a mobility advantage. Also the decision by chance makes the AI more flexible, because it doesn't choose the same moves for the same opening again and again.
Later it chooses the move with the highest difference between the now won values and the possible values of the best couter move the opponent can take. This is the point where the
array from the beginning becomes important.
Still there can be more than one move of the same importance. So finally a move is chosen by chance.
Finally the possibilities for the player are checked. If he can move the control is given to him, if not the AI calls itself again after 2 seconds. However if the AI cannot move itself the game is over.
What's still missing is the HTML part. We need two counters for the current amount of discs on the board:
Also the board itself has to be created.
And finally the
button as well as the radio buttons to choose the color and if help should be displayed or not.
The last thing to do is to initialize the game.