Lab 3 Part 2: Mine Sweeper Lite
Overview
Mine Sweeper is a popular "time wasting" game that exist on almost all PC. The purpose of the game can be summarized in just one sentence: "Find the bomb, but dont step on it!". This lab attempts to implement a cut-down version of this game.
Getting Started
The playing area of the mine sweeper is represented by a 2D array. Initially, all squares are covered (hidden). A number of bombs are randomly planted in some of the squares. To provide hints that bomb(s) are nearby, a non-bomb square will contain a number specifying the number of bombs in the immediate 8 adjacent squares. The example below should give you some ideas:
0 |
1 |
2 |
3 | 4 | 5 | 6 | 7 | |
0 | 0 | 0 | 0 | 0 | 0 | 1 | B | B |
1 | 0 | 1 | 1 | 1 | 0 | 1 | 3 | B |
2 | 0 | 1 | B | 1 | 0 | 0 | 1 | 1 |
3 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 1 | 1 | 2 | 1 | 1 |
7 | 0 | 0 | 0 | 1 | B | 2 | B | 1 |
A game of mine sweeper proceeds by letting the user to chose a square to open. Depending of the type of squares, one of the following actions will be taken:
1. If the square is a Bomb, the game ends.
2. If the square is a Empty square, it will be revealed and
the surrounding 8 neighbors will be uncovered in exactly the same fashion.
3. If the square is a Numbered square, it will be revealed.
Before we proceeds to give you some examples, you should see that there are quite a number of different type of squares to be represented. For each type of squares, we will need to be able to show whether it is hidden or uncovered/revealed. So, to simplify the representation, an integer array is used for the mine sweeper, with the following specification:
10 :
An uncovered empty square
9 :
An uncovered bomb
1 to 8 : An uncovered number square
0 :
A hidden empty square
-1 to -8 : A hidden number square
-9 : A hidden
bomb
There is a nice property about this representation: anything positive is a uncovered square, and inversely, anything lesser or equal to zero is hidden.
To make the playing area to look nicer on the screen, when the board is
printed, the following rules are used:
For hidden square: 'X'
For uncovered number square: Just the number
For uncovered bomb: 'B'
For uncovered empty square: '.'
Now, lets see some example:
Initially, 5 bombs are randomly planted in a 5 x 5 playing area:
Actual Array:
0 |
1 |
2 |
3 | 4 | |
0 | -9 | -2 | -1 | 0 | 0 |
1 | -2 | -9 | -1 | 0 | 0 |
2 | -1 | -1 | -1 | -1 | -1 |
3 | -1 | -1 | -2 | -9 | -9 |
4 | -1 | -9 | -2 | -2 | -2 |
On Screen:
0 |
1 |
2 |
3 | 4 | |
0 | X | X | X | X | X |
1 | X | X | X | X | X |
2 | X | X | X | X | X |
3 | X | X | X | X | X |
4 | X | X | X | X | X |
User chose to open the square (4,0)
Actual Array:
0 |
1 |
2 |
3 | 4 | |
0 | -9 | -2 | -1 | 0 | 0 |
1 | -2 | -9 | -1 | 0 | 0 |
2 | -1 | -1 | -2 | -1 | -1 |
3 | -1 | -1 | -2 | -9 | -9 |
4 | 1 | -9 | -2 | -2 | -2 |
On Screen:
0 |
1 |
2 |
3 | 4 | |
0 | X | X | X | X | X |
1 | X | X | X | X | X |
2 | X | X | X | X | X |
3 | X | X | X | X | X |
4 | 1 | X | X | X | X |
Only the square (4,0) is uncovered because it is a number square.
User chose to open the square (0,4)
Actual Array:
0 |
1 |
2 |
3 | 4 | |
0 | -9 | -2 | 1 | 10 | 10 |
1 | -2 | -9 | 1 | 10 | 10 |
2 | -1 | -1 | 2 | 1 | 1 |
3 | -1 | -1 | -2 | -9 | -9 |
4 | 1 | -9 | -2 | -2 | -2 |
On Screen:
0 |
1 |
2 |
3 | 4 | |
0 | X | X | 1 | . | . |
1 | X | X | 1 | . | . |
2 | X | X | 2 | 1 | 1 |
3 | X | X | X | X | X |
4 | 1 | X | X | X | X |
9 squares are revealed.
User chose to open the square (0,0)
Actual Array:
0 |
1 |
2 |
3 | 4 | |
0 | 9 | -2 | 1 | 10 | 10 |
1 | -2 | -9 | 1 | 10 | 10 |
2 | -1 | -1 | 2 | 1 | 1 |
3 | -1 | -1 | -2 | -9 | -9 |
4 | 1 | -9 | -2 | -2 | -2 |
On Screen:
0 |
1 |
2 |
3 | 4 | |
0 | B | X | 1 | . | . |
1 | X | X | 1 | . | . |
2 | X | X | 2 | 1 | 1 |
3 | X | X | X | X | X |
4 | 1 | X | X | X | X |
Since the user "steps" on the bomb, the game is ended. For marking purpose, the board is then revealed (all tiles uncovered).
Actual Array:
0 |
1 |
2 |
3 | 4 | |
0 | 9 | 2 | 1 | 10 | 10 |
1 | 2 | 9 | 1 | 10 | 10 |
2 | 1 | 1 | 2 | 1 | 1 |
3 | 1 | 1 | 2 | 9 | 9 |
4 | 1 | 9 | 2 | 2 | 2 |
On Screen:
0 |
1 |
2 |
3 | 4 | |
0 | B | 2 | 1 | . | . |
1 | 2 | B | 1 | . | . |
2 | 1 | 1 | 2 | 1 | 1 |
3 | 1 | 1 | 2 | B | B |
4 | 1 | B | 2 | 2 | 2 |
Bits and Pieces
Since this is already the third lab, you will be given lesser help. Dont forget that you are allowed to define other functions or modify any of the following functions to aid your coding.
int IsValid(int row, int column);
Purpose:
Checks whether row and column are in the range 0 to SIZE-1
Input: Row (an integer
representing the row number)
Column (an integer representing the column number)
Output: 1 (True. The row and
column are well defined)
0 (False. Either the row or column is out of range)
Remark: You can choose NOT to
implement or use this function.
void InitMap(int Map[][SIZE], int nBomb);
Purpose:
Initialize the map, including planting bomb(s) and updating number square.
Input: Map (the 2d array
that represents the playing area)
nBomb (Number of bomb to be planted)
Output: None.
Remark: The coordinate for the bomb
is chosen randomly. Make sure the square contains no
bomb before planting.
int OpenAt(int Map[][SIZE], int row, int
column);
Purpose:
A recursive function to open the square in the playing area.
Input: Map (the 2d array
that represents the playing area)
Row (the row number)
Column (the column number)
Output: -1 (A bomb
is revealed)
N (the number of squares revealed)
void UncoverAll(int Map[][SIZE]);
Purpose:
Reveal all the squares in the playing area.
Input: Map (the 2d array
that represents the playing area)
Output: None.
void PrintArray(int Map[][SIZE]);
Purpose:
Print the playing area according to the rules stated.
012......
0 XXXXXX...
1
2
.
.
.
Input: Map (the 2d array
that represents the playing area)
Output: None.
Remark: No spaces between each of the
column. To lighten the workload of this lab. This
function is GIVEN in the skeleton code. If you find the implementation
inadequate
in anyway, you are allowed to modify or replace it.
Putting it together
With the help of the functions above, you can now design the main function. The basic steps is given as follows:
Basic Steps:
1. Ask the user for the number of bombs
2. Initialize the Map with the number
of bombs stated.
3. Keep doing until the user entered
an invalid coordinate or a bomb is revealed
a. Ask
coordinate
b. Open the
square at the coordinate
c. Print the
new map
c. Report the
number of squares opened if no bomb is revealed.
4. Uncover all the squares
5. Print the Map
Refer to the sample output section for output format.....
Skeleton Code
#include <stdio.h> #define SIZE 10 //The following functions are given int Reading(char[]); void PrintArray(int Map[][SIZE]); // Here are the functions you need to implement void InitMap(int Map[][SIZE], int nBomb); int OpenAt(int Map[][SIZE], int row, int column); void UncoverAll(int Map[][SIZE]); int main() { //Starts your code here. return 0; } int Reading(char msg[]) { int input; printf(msg); scanf("%d",&input); return input; } void InitMap(int Map[][SIZE], int nBomb) { } int OpenAt(int Map[][SIZE], int row, int column) { } void UncoverAll(int Map[][SIZE]) { } void PrintArray(int a[][SIZE]) { int i,j; printf(" "); for (i = 0; i < SIZE; i++){ printf("%d",i); } printf("\n"); for (i = 0; i < SIZE; i++){ printf("%d ",i); for (j = 0; j < SIZE;j++){ if (a[i][j] <= 0){ //Hidden Tile printf("X"); } else { if (a[i][j] < 9){ //Number Tile printf("%d",a[i][j]); } else if (a[i][j] == 9){ //Bomb printf("B",a[i][j]); } else { //Empty Tile printf("."); } } } printf("\n"); } printf("\n"); }
Sample Output
Note: User Input is in bold.
Number of Bomb(s): 12 0123456789 0 XXXXXXXXXX 1 XXXXXXXXXX 2 XXXXXXXXXX 3 XXXXXXXXXX 4 XXXXXXXXXX 5 XXXXXXXXXX 6 XXXXXXXXXX 7 XXXXXXXXXX 8 XXXXXXXXXX 9 XXXXXXXXXX Row (invalid to exit) : 0 Column (invalid to exit) : 0 0123456789 0 ......1XXX 1 .....12XXX 2 ....12XXXX 3 11..1XXXXX 4 X2212XXXXX 5 XXXXXXXXXX 6 XXXXXXXXXX 7 XXXXXXXXXX 8 XXXXXXXXXX 9 XXXXXXXXXX 29 Squares Opened Row (invalid to exit) : -1 Column (invalid to exit) : 0 Map Uncovered. 0123456789 0 ......112B 1 .....12B21 2 ....12B21. 3 11..1B21.. 4 B221211... 5 2B2B1..111 6 11211112B1 7 .....1B322 8 ..111123B1 9 ..1B1.1B21 Program Terminated. Bye Bye! Sample Output 2 Number of Bomb(s): 15 0123456789 0 XXXXXXXXXX 1 XXXXXXXXXX 2 XXXXXXXXXX 3 XXXXXXXXXX 4 XXXXXXXXXX 5 XXXXXXXXXX 6 XXXXXXXXXX 7 XXXXXXXXXX 8 XXXXXXXXXX 9 XXXXXXXXXX Row (invalid to exit) : 0 Column (invalid to exit) : 0 0123456789 0 ....1XXXXX 1 ....1XXXXX 2 ....2XXXXX 3 11..2XXXXX 4 X2213XXXXX 5 XXXXXXXXXX 6 XXXXXXXXXX 7 XXXXXXXXXX 8 XXXXXXXXXX 9 XXXXXXXXXX 24 Squares Opened Row (invalid to exit) : 9 Column (invalid to exit) : 9 0123456789 0 ....1XXXXX 1 ....1XXXXX 2 ....2XXXXX 3 11..2XXXXX 4 X2213XXXXX 5 XXXXXXXXXX 6 XXXXXXXXXX 7 XXXXXXXXXX 8 XXXXXXXXXX 9 XXXXXXXXX1 1 Squares Opened Row (invalid to exit) : 9 Column (invalid to exit) : 0 0123456789 0 ....1XXXXX 1 ....1XXXXX 2 ....2XXXXX 3 11..2XXXXX 4 X2213XXXXX 5 XXXXXXXXXX 6 1122XXXXXX 7 ...1XXXXXX 8 ..12XXXXXX 9 ..1XXXXXX1 15 Squares Opened Row (invalid to exit) : 4 Column (invalid to exit) : 0 0123456789 0 ....1XXXXX 1 ....1XXXXX 2 ....2XXXXX 3 11..2XXXXX 4 B2213XXXXX 5 XXXXXXXXXX 6 1122XXXXXX 7 ...1XXXXXX 8 ..12XXXXXX 9 ..1XXXXXX1 Boom! Ouch! Map Uncovered. 0123456789 0 ....11212B 1 ....1B3B21 2 ....23B21. 3 11..2B31.. 4 B2213B2... 5 2B2B211111 6 11222212B1 7 ...1B2B322 8 ..122223B1 9 ..1B1.1B21 Program Terminated. Bye Bye!