Perhaps the most complex task in creating TK-MineSweeper is actually defining the rules which make the model run like the original mineSweeper game. This section deals with this aspect of the model. It is intuitative to look at what we already have at this point before seeing how we can start to tie it all together into one coherant module.

- We have the
*mineField*list defining the appearence and dimension of the minefield - We have the
*status*list, defining whether a cell is**a)**hidden, or**b)**un-covered - We have the
*mines*list, defining whether a cell**contains**or**does not contain**a mine - We have the
*values*list, defining the values of cells in terms of how many mines surround them in an 8-connected manner - We have output template lists which define the mineField
- We have an output string which represents the minefield
- We have a triggered action which is designed to display the output string whenever the mineField changes

The playing of minesweeper can be broken down to produce a set of checks which define what actions should be taken. The following list looks in detail at an interaction with mineSweeper :

- When a cell is selected, it must lie within the range of the mineField, otherwise it is invalid

` ````
if ((currentPos > 0)&&(currentPos <= nCells)) {
CONTINUE
} else {
writeln("Choice of cell out of range - try another (1-16)");
}
```

- For a cell to be uncovered, it must be hidden ; uncovered cells cannot be re-uncovered

` ````
if (status[currentPos]==1) {
CONTINUE
} else {
writeln("Cell is already uncovered - try another (1-16)");
}
```

- If the cell is upon a mine then it's
*Game Over*!

` ````
if (mines[currentPos]==1) {
writeln("BANG ! Oops - found a mine the messy way");
} else {
CONTINUE
}
```

- If the cell is blank, we uncover 8-connected cells, otherwise, we send the value of that cell to
*mineTemplte*for display

` ````
if (values[currentPos]!="0") {
mineTemplate[currentPos] is values[currentPos]
} else {
UNCOVER 8-CONNECTED CELLS
}
```

This defines the important checks which must take place within this aspect of the model. Basically, we can simplify this in English as follows :
- If the chosen cell is out of range, then choose another
- If the chosen cell is uncovered, then choose another
- If you trod on a mine, you lose - game over
- If the cell chosen is not blank, then reveal it's value
- If the cell chosen is a blank, then recursively reveal 8-connected cells untilcells are found that are not blanks

Whilst the majority of this section is quite simple, the most tricky part concerns the plan of action when a blank cell is encountered. This is so because this leads to further uncovering of other cells, which, in turn, could lead to further uncovering. For this action, a *TKeden* operation called **todo** comes in very useful.

When executing, *TKeden* will simply execute it's current thread of events. However, if we wish to schedule certain events, then we can use the **todo list**.

The **todo list** is a list within *TKeden*, which is executed once the current thread of events has been exhausted. Hence, we get the execution of actions in a specified sequence.

Take into consideration that we have chosen a cell on the mineField , and it turns out to be a blank. Now, we must check 8-connected cells to uncover further cells until we reach cells which have surrounding mines. The following diagram illustrates the 8-connected model used in the TK-MineSweeper model :

` ````
123
4 5
678
```

So, we must check these 8-connected cells, and reveal their contents. If a cell contains some valueTaking the 8-connected diagram into consideration, we use the following references to reference the 8-connected items :

**1.**((((pos-1)%4)!=0)&&(pos>xDim))**2.**(pos>xDim)**3.**(((pos%4)!=0)&&(pos>xDim))**4.**((((pos-1)%4)!=0)&&((pos-1)>0))**5.**(((pos%4)!=0)&&(pos**6.**((((pos-1)%4)!=0)&&(pos<=((yDim-1)*xDim)))**7.**(pos<=((yDim-1)*xDim))**8.**((pos<=((yDim-1)*xDim))&&(pos>xDim))

**(((pos-1)%4)!=0)**- Take the current cell number and subtract
**1**. If the remainder after division by the length of the**X**dimension of the mineField is 0, then this cell is at the far left of the board. Hence, no 8-connected elements appear to the left of a cell which satisfies this condition. - No 8-connected cells appear to the left if false

**(pos>xDim)**- If the current cell location is larger than the
**X**dimension of the mineField, then 8-connected elements appear above the current cell, otherwise the current cell is at the top of the mineField, and hence, no 8-connected cells appear above this cell

**((pos%4)!=0)**- Take the current cell number and if the remainder after division by the length of the
**X**dimension of the minefield is**0**, then this cell is at the far right of the board. Hence, no 8-connected elements appear to the right of a cell which satisfies this condition. - No 8-connected cells appear to the right if false

**(pos<=((yDim-1)*xDim))**- If the current cell number is larger than the largest number on the last but one row of the mineField, then no 8-connected elements appear below that cell.

Armed with all of this information, we may tackle the definition of the play function. Before getting into the function itself, we need to answer the question - when do we want the model to perform our checks ?

It would seem as though the best time to perform these checks would be whenever the player changes the value of *currentPos*. Hence, we make the function, **play**, a *triggered action*.

Get ready - here comes the **play** function - copy & paste & * Accept* :

` ````
func play : currentPos {
if ((pos>0)&&(pos<=nCells)) {
if (status[pos]==1) {
status[pos] = 0;
if (mines[pos]==1) {
writeln("BANG ! Mine Here - Game Over");
mineTemplate[pos]="*";
/*revealMF();*/
} else {
if (values[pos]!="0") {
mineTemplate[pos]=values[pos];
} else {
mineTemplate[pos]=labelTemplate[6];
if ((((pos-1)%4)!=0)&&(pos>xDim)&&(mines[pos-xDim-1]!=1)) {
todo("pos is "//str(pos-xDim-1)//";");
}
if ((((pos-1)%4)!=0)&&((pos-1)>0)&&(mines[pos-1]!=1)) {
todo("pos is "//str(pos-1)//";");
}
if ((((pos-1)%4)!=0)&&(pos<=((yDim-1)*xDim))&&(mines[pos+xDim-1]!=1)) {
todo("pos is "//str(pos+xDim-1)//";");
}
if ((pos<=((yDim-1)*xDim))&&(mines[pos+xDim]!=1)) {
todo("pos is "//str(pos+xDim)//";");
}
if <
```xDim)&&(mines[pos-xDim+1]!=1)) {
todo("pos is "//str(pos-xDim+1)//";");
}
if ((pos>xDim)&&(mines[pos-xDim]!=1)) {
todo("pos is "//str(pos-xDim)//";");
}
}
}
} else {
writeln(pos, " is already uncovered - choose another cell (1-16)");
dispMF();
}
}
}
}

Within the above extract of code for the play function, where the check occurs near the top to see whether This function is designed to simply reveal all elements on the mineField when the player loses, so that the position of everything can be seen. This is a comparatively simple function, and appears below. Once this function has been defined, the commented out reference in the

` ````
func revealMF {
auto x;
for (x=1;x < nCells;x++) {
mineTemplate[x]=values[x];
if (mines[x]==1) mineTemplate[x]="*";
if (values[x]==0) mineTemplate==" ";
}
}
```

Quite simply, this function runs through all cells from cell With these functions in place, it is quite possible to have a game of TK-MineSweeper. Simply make some changes to the value of

Whilst it is interesting rambling around our TK-MineField, we still have no way of winning (even though we have a way of losing). This is mostly due to a large ommision in the implementation which is about to be included - that of the mineSweeper hero's ability to select cells which he/she suspects contains mines for defusal.

Further inclusions to the current implementation of TK-MineSweeper will introduce the ability to select defuse cells, as well as defining a way of winning the game.

Move to the ninth TK-MineSweeper page...