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!