~ Introduction to Programming: C ~

Session 7 - Example Exam: Bombs

<<  Back to Contents Page

The following is the sample exam question given in the previous session to take away with you to attempt for this session. Read through it again before working through walkthrough sample examination that follows.

9531 – INTRODUCTORY COMPUTER PROGRAMMING: STRUCTURED ASSIGNMENT

 Topic    Games and Quizzes

 Title of this Assignment    Bombs

 Introduction

 The game of Bombs is a one-player game on a hidden grid.

 Assignment Specification

 Devise a program that will play the game "Bombs", with a single player.

 The game should be played on a grid that is 10x10 in size, using 1 to 10 down and A to J across to identify each square in the grid.

 The computer places ten bombs randomly in the grid, but which are not shown on the screen.

 The grid is then shown on the screen (blank at first). The grid should display 1 to 10 down the left hand side of the grid and A to J across the top.

 The player chooses an option from one of the following choices: R for reveal, M for Mark, U for Unmark or X to exit.

 The player types out a grid reference (e.g. A1 gives the top-left grid position, J10 gives the bottom-right). This is used to identify a square on the grid. If anything outside this range is typed, then the player is prompted to choose one of the choices (R/M/U/X) again.

 If R was chosen, then if the square contained a bomb, the player is told GAME OVER, and after pressing a key, the program exits. If the square contained nothing, then the eight squares surrounding that square are checked. If any of them contain a bomb, they should be counted, and the number of bombs surrounding the square should be placed in the revealed square.

 If M was chosen, the square is marked with an X. If U was chosen, the square is marked with a space.

 If X was chosen, then the program exits, after the user is prompted about whether they are sure they want to quit.

 Check all squares. If all squares have been revealed or marked (i.e. not a space), and all marked squares have a bomb underneath them, then display GAME OVER. WELL DONE. and after the user presses a key, end the program.

 Otherwise, loop back to clear the screen, re-display the board, and ask what the user wants to do next.

 It is recommended that you use two arrays, one for the location of the bombs, one to show the user marks / revealed squares. For example, a square marked with a digit as a character (1 to 8) would show a revealed square with the number of unrevealed bombs next to it. An X would show a marked square. A space would show an unrevealed square.

Procedure

 a)     Describe briefly in writing for a possible user

i)                    The purpose of your program

ii)                  The limitations of your program

b)     Construct (on paper) a screen layout indicating what will appear on the screen – prompts, input, output with annotations, any other messages.

c)      Describe (on paper) the main stages of the program - by means of a flowchart or an alternative technique.

d)     Produce a listing of the program.  This should have adequate comment lines and should demonstrate to the examiner that the program solves the problem set.

e)     Include in the program statements to display adequate instruction to the user of the program – e.g. prompts for data entry and appropriate error messages for invalid input.

f)        Key in and run the program, producing and using simple test data if necessary. Check that the program's output agrees with the expected results and correct any errors.

g)     Use appropriate language facilities.

Hint – Two-Dimensional Arrays

We have talked so far about single-dimension arrays – e.g.

int i[3]; i[0]=1; i[1]=2; i[2]=i[0]+i[1];

which leaves us with i[2] containing the value of 3.

However, we can reproduce a grid, which is effectively an array of an array. If you take a row on our grid as an array of ten characters (char grid_row[10]) then the whole grid can be taken as an array of rows (char grid[10][10]) which gives us 10x10 characters. To access each element in the two-dimensional array, refer to the grid position as each dimension's position (from 0 to 9) in separate square brackets. See diagram above for graphical representation of this concept.

Sample Exam - Introduction

 The following is a sample exam that you might submit. In the time given, you cannot be expected to produce 100% perfect results. Your aim is to complete at least some of each section.  Even if you cannot get your program to work exactly as you want, you can show that you know how to go through the process of analysing the problem, documenting it, structuring it correctly with comments and indentation to make it easier to understand and locate any problems, understanding the limitations and possible improvements that could be made in the program, designing the inputs and screen output, and designing / using a test plan to show that you are able to locate any problems, even if you run out of the time in which to correct those problems (in real life, such problems, or 'bugs' can be difficult to track down, and can cost a lot in terms of time and effort – a good reason to properly document and structure your program – it will make debugging very much easier).

a)     i) User's Description

 The game of "Bombs" start with a 10x10 grid of squares. Bombs are hidden underneath ten of these hundred squares.  The aim of the game is to reveal squares to see how many bombs are hidden in adjacent squares (including diagonals), and use this to judge where other bombs may be. If you choose a square with a bomb, the game is over. If you correctly mark all ten bombs without revealing them, and reveal all other squares, you win.

a)     ii) Restrictions

1.      The grid can only be 10 x 10 squares, and there can only be 10 bombs in the grid, so it is not possible to have a harder or easier game, or introduce progressively harder "levels".

2.      There is no scoring, nor high scoring.

3.      There is no facility to start the game again

4.      The display is text-based, so is less attractive than a typical commercially sold game. It can also make the jumble of Xs and digits look quite confusing.

5.      Using a space to denote a hidden grid position does not clearly show the individual grid positions

b)     Screen Display

 Given an example 10x10 grid with the following bomb positions:-

 

A

B

C

D

E

F

G

H

I

J

1

 

 

 

 

 

 

 

 

 

 

2

 

 

B

 

 

 

 

 

 

 

3

 

 

 

 

 

 

 

B

 

 

4

 

 

 

 

 

B

 

 

 

 

5

 

 

 

 

 

 

 

 

 

 

6

 

 

 

B

 

B

 

B

 

 

7

 

 

 

 

 

 

 

 

 

 

8

B

 

 

 

 

B

 

B

 

 

9

 

 

 

 

 

 

 

 

 

 

10

 

 

 

 

 

 

 

 

 

B

 Text output is shown as white text on black. Input is shown as black text on white.

Bombs Game
==========

   A B C D E F G H I J
--+-------------------
 1|
 2|
 3|
 4|
 5|
 6|
 7|
 8|
 9|
10+-------------------

Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it:
R
Enter a grid reference (eg. E10):
E5

 

E5 is clear. However, the following squares around E5 have bombs in them: D6, F6, F4. Thus, the square will be shown with a 3 in it, as there are three bombs adjacent to that square.

 

The screen may now look as follows:- 

Bombs Game
==========

   A B C D E F G H I J
--+-------------------
 1|
 2|
 3|
 4|
 5|        3
 6|
 7|
 8|
 9|
10+-------------------

Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it:
X
Are you sure you wish to quit? Y for Yes or N for No:
Y

In this example, the user has quit the program. Notice the check. If the user had pressed N, the screen would have been redisplayed with the choices displayed again.

In the following example, the user has chosen a square with a bomb on it:-

Bombs Game
==========

   A B C D E F G H I J
--+-------------------
 1|
 2|
 3|
 4|
 5|        3
 6|
 7|
 8|
 9|
10+-------------------

Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it:
R
Enter a grid reference (eg. E10):
D6
BOOM! You hit a bomb. GAME OVER. Press a key to exit. x

In the following example, all of the bombs have been marked with Xs and all other squares have been revealed. The last square to be marked is A1. The user has won the game. The display would look like this:- 

Bombs Game
==========

   A B C D E F G H I J
--+-------------------
 1|  1 1 1 0 0 0 0 0 0
 2|0 1 X 1 0 0 1 1 1 0
 3|0 1 1 1 1 1 2 X 1 0
 4|0 0 0 0 1 X 2 1 1 0
 5|0 0 1 1 2 2 3 1 1 0
 6|0 0 1 X 2 X 2 X 1 0
 7|1 1 1 1 2 2 3 2 2 0
 8|X 1 0 0 1 X 2 X 2 1

 
9|1 1 0 0 1 1 2 1 2 X
10+-------------------

Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it:
M
Enter a grid reference (eg. E10):
A1
GAME OVER. Well Done. All bombs found. Press a key. x

 

d) Stages of Program

The following is a JSP diagram representing the structure and flow of the program.

 

 N.b. it is recommended that in the exam, you write these diagrams by hand – it's a lot quicker!

 

 

e) Program Listing

 This program does pretty much exactly what is required, and follows the structure of the JSP diagram using functions for each main section of the JSP diagram.  You can follow how it splits down.  You are unlikely to find the time to be this exhaustive, but it gives you an idea of what can be done.  See below this listing for something a bit more reasonable for you to produce.

/*

** Bombs Game

** by Simon Huggins - 9th April 2002

** Introduction to Programming Course (C Element)

**

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <ctype.h>

#include <string.h>

 

 

/* Define function prototypes */

void set_up_arrays();

char main_loop();

void display_visible_array();

void get_prompt(char *prompt, int *rowpos, int *colpos);

int bomb_revealed(int row, int col);

int check_game_over();

int exit_check();

 

/* Define constants for grid size and number of bombs */

int const rows = 10, cols = 10, bombs = 10;

 

/* Define global variable arrays for visible & invisible grids */

char visible[rows][cols],invisible[rows][cols];

 

 

/* Main Loop */

 

void main() {

 

  randomize(); /* Randomize generated numbers */

  set_up_arrays(); /* Set up arrays with blanks and bombs */

 

  while (main_loop() != 'X'); /* Keeps getting user option */

 

  /* Closing message and await a keypress */

  printf("Press a key to finish. ");

  getch();

}

 

 

/* Set visible & invisible arrays to blank and

   set up bombs in invisible array */

 

void set_up_arrays() {

  /* Fill both grids with spaces */

  for (int i=0; i<rows; i++)

    for (int j=0; j<cols; j++) {

      visible[i][j] = ' ';

      invisible[i][j] = ' ';

    }

 

  /* Set up bombs in invisible array */

  for (int i=0; i<bombs; i++) {

 

    int rowpos, colpos;

    /* Loop while random cell has a bomb in it */

    do {

      rowpos = rand() % rows;

      colpos = rand() % cols;

    } while (invisible[rowpos][colpos] == 'B');

    /* Set invisible square to 'B' for bomb */

    invisible[rowpos][colpos] = 'B';

  }

}

 

 

/* Show grid, prompt for option / grid position.

   Call appropriate function according to option chosen.

   Return option chosen (or 'X' if game over).

   Called from main() function */

 

char main_loop() {

  /* Local variables [visible only in main_loop()] */

  char prompt;

  int rowpos,colpos;

 

  /* Print title and columns */

  clrscr();

  printf("Bombs Game\n==========\n\n");

  /* This would be the easy way of doing it...

  printf("   A B C D E F G H I J\n"); */

  /* ... but so that the number of letters matches the number of columns: */

  printf("   ");

  for (int i=0; i<cols; i++) printf("%c ",'A'+i);

  printf("\n");

  printf("--+-------------------\n");

  display_visible_array();

  printf("--+-------------------\n\n");

 

  /* If board has all been marked, return an 'X' to finish game

     Note chose to do this before anything else after some testing,

     otherwise final revealed square is not shown when game over */

  if (check_game_over()) return 'X';

 

  get_prompt(&prompt, &rowpos, &colpos);

 

  switch(prompt) {

    case('M') : visible[rowpos][colpos] = 'X'; break;

    case('U') : visible[rowpos][colpos] = ' '; break;

    /* If reveal returns true (non-zero) then break, otherwise

       return with an 'exit' */

    case('R') : if (bomb_revealed(rowpos,colpos)) return 'X'; else break;

    /* If user doesn't want to exit, return a non-X character */

    case('X') : if (!exit_check()) return '?';

  }

 

  return prompt;

}

 

 

 

/* Display all rows & cols if visible array on screen */

 

void display_visible_array() {

  for (int i=0; i<rows; i++) {

    printf("%2d|",i+1);

    for (int j=0; j<rows; j++)

      printf("%c ",visible[i][j]);

    printf("\n");

  }

}

 

 

/* Prompt for option, and get co-ordinate in x,y format */

 

void get_prompt(char *prompt, int *rowpos, int *colpos) {

  /* variables passsed by reference for prompt letter,

     row position, and column position */

 

  /* Keep getting option until correct key pressed */

  do {

    printf("Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it: ");

    *prompt = (char)toupper(getch());

    printf("%c\n",*prompt);

  } while ((*prompt!='R') && (*prompt!='M') &&

           (*prompt!='U') && (*prompt!='X'));

 

  /* Return if X */

  if (*prompt == 'X') return;

 

  /* Otherwise, get grid co-ordinate until valid */

  char gridletter;

  int gridnumber;

  do {

    printf("Enter a grid reference (eg. E10): ");

    flushall(); // Ensures scanf does not use same data twice

    scanf("%1c%d",&gridletter,&gridnumber);

    /* This works by taking the ASCII value of the letter

       (e.g. J would be 74) and takes the ASCII value of 'A'

        from this (which is 65) - e.g. for J, this is 65-74=9).

       Note that the first column is array element 0, so the

       tenth (J) would be 9.

    */

    *colpos = (char)(toupper(gridletter) - 'A');

    /* Alternative method (better validation) might be:-

    switch(gridletter) {

      case('A') : *colpos = 0; break;

      case('B') : *colpos = 1; break;

      case('C') : *colpos = 2; break;

      case('D') : *colpos = 3; break;

      case('E') : *colpos = 4; break;

      case('F') : *colpos = 5; break;

      case('G') : *colpos = 6; break;

      case('H') : *colpos = 7; break;

      case('I') : *colpos = 8; break;

      case('J') : *colpos = 9; break;

      default   : *colpos = -1;

    end;

    */

    *rowpos = gridnumber - 1;

 

  } while ((*rowpos < 0) || (*rowpos >= rows) ||

           (*colpos < 0) || (*colpos >= cols));

 

  /* Upon exit, rowpos, colpos and prompt will be completed */

}

 

 

/* Check to see if the current cell is a bomb.

   If not, reveals current row / col with number of surrounding bombs.

   Return 1 (true) if bomb hit, or 0 (false) otherwise */

 

int bomb_revealed(int row, int col) {

  if (invisible[row][col]=='B') {

    printf("BOOM! You hit a bomb. GAME OVER. "); return true;

  }

  int count=0;

  for (int i=row-1; i<=row+1; i++)  // for above, same & below row

    for (int j=col-1; j<=col+1; j++)  // for left, same & right column

      // Make sure that the given row / column is on the grid

      if ((i >= 0) && (i < rows) && (j >= 0) && (j < cols))

        // And if it is, add one to count if that square is a 'B'

        // Note that this checks the middle square as well as the surrounding

        // squares. This is OK, as we already know it cannot be a 'B',

        // otherwise the game would already be over!!!

        if (invisible[i][j]=='B') count++;

  // Set the visible square to be a '0' character plus the count.

  visible[row][col] = (char)('0' + count);

  return false;

}

 

 

/* Check to see if game is over. If all visible squares are

   spaces or Xs with bombs in respective invisible square,

   then game is over */

 

int check_game_over() {

  int all_marked = true, isdigit, coveredbomb, isspace;

 

  for (int i=0; i<rows; i++)

    for (int j=0; j<cols; j++) {

      isdigit = (visible[i][j] >='0') || (visible[i][j]<='9');

      coveredbomb = (visible[i][j]=='X') && (invisible[i][j]=='B');

      isspace = (visible[i][j]==' ');

      if ((!isdigit && !coveredbomb) || isspace) all_marked = false;

    }

 

  /* if everything is marked then display a message */

  if (all_marked)

    printf("GAME OVER. Well Done. All bombs found. ");

 

  return all_marked;

}

 

int exit_check() {

  char ch;

  do {

    printf("Are you sure you wish to quit? Y for Yes or N for No: ");

    ch = (char)toupper(getch()); printf("%c\n",ch);

  } while ((ch!='Y')&&(ch!='N'));

  return (ch=='Y');

}

Here's some hints about how some of it has been created:-

·         Lots of comments to explain what each section of codes does, particularly where the code represents a box in the JSP diagram

·         Constants used for row, cols and bombs.  This means that we can adjust these in one place for testing purposes without having to go through the code to find where they are used.  This would be particularly useful when testing that "game over" works properly – we could change "bombs" to 1, and rows + cols to "2" – thus making testing very much quicker. This could also be done for testing that the bomb detection part works.

·         Remember the randomize() at the beginning of the main() function. If you forget this, your game won't be very random!

·         We are using two two-dimensional arrays. We must set them up first (called set_up_arrays()) to contains spaces.  Remember that the contents of variables is unpredictable when they are first created, as they memory that was being used for those arrays could have been previously used for anything – e.g. program instructions etc.

·         Notice that there is a do...while loop around the setting of the bomb.  This takes care of the problem where we might try to place a bomb where there is already one.  This would mean there would be less bombs than we expected on the board – e.g. if we have ten bombs, but on gets put on top of another, it replaces the other bomb, so we only have nine bombs.

·         Notice that when displaying column letters, we are taking the letter 'A' and adding a number on to it – from 0 to the number of columns minus one.  What does this mean?  Well, remember that every character has an ASCII code equivalent (e.g. 'A' equates to 65). If we add zero to this, the character we get back is 'A'. If we add 1 on to it (to make 66), this equates to to the ASCII character 'B' etc. So, each character follows on in the ASCII character set, as you might expect – we can make use of this to avoid having to use a messy 'select...case' statement.

·         In the main_loop() we are using the fact that returning 'X' breaks us out of the game in various places to do just that.  For examble, if the user chose to reveal a grid position with a bomb underneath it, an 'X' is returned as the game is now over.  If the user chooses to exit from the game using the 'X' option, but the check reveals he or she has changed their mind, then an arbitrary character '?' is returned to prevent the loop from being ended.

·         In get_prompt() notice the use of passing variables by reference - *prompt is the character used to collect the option chosen, *row and *col the grid co-ordinate chosen if the 'X' option wasn't selected.  This means that variables can be passed to be changed directly, meaning that we can return three values instead of the usual one when using return to return a value.

·         Notice the use of flushall() before using the scanf() function.  This is necessary in the version of C, as if the input was incorrect, and the scanf() is run again, the buffer results may not have been cleared properly, giving unpredictable results.  This just makes sure that scanf has no keyboard input to process before it starts.

·         Notice the odd format string used in scanf. This means "read exactly one character (%1c) and place it into the gridletter variable, and then read a decimal integer number straight after (%d) and place it into the gridnumber variable. You may wonder why the 1 in %1c is necessary.  Without this, scanf expects to find white space separating the character from the number (e.g. a space or a tab).  We could put this as a restriction if we are happy to do so, or we could put the 1 before the C to say that we wish to read precisely one character.

·         Using (char) when we are converting ASCII characters to numbers and back again stops any compiler warning messages appearing – we are explicitly saying "convert the integer number back to a character again".

·         Probably the trickiest part of the program is knowing how to count the bombs around the revealed square.  This could be done in a few ways.  You could write nine lines of code to look at specific square around the grid position.  Better still, why not have a loop to go from the row before to the row after the revealed square, and another within that loop to go from the column before to the column after the revealed square. If you check each of these squares (which makes a total of nine squares, including the revealed square itself) to see if the invisible grid has a 'B' in it, and add one to a counter where this is the case, we can then use this for our bomb count.  A word of warning though – what happens when the bomb is on an outside edge of the board.  E.g. the Top-left corner.  It wouldn't be safe to check above or to the left of the bomb.  Thus, before checking, we must ensure that the square being checked is on the grid.  The actual code to do all this is only six lines long, but it sounds a lot!  Work your way through – or even better, put a breakpoint at the point where the square is being checked, and look at the values of i, j, count and invisible[i][j] to investigate what is happening.

·         To check that the game is over,  we can check every square on the board.  We can check whether the square is a digit from 0 to 9 (i.e. a revealed square), whether it is a bomb with an 'X' over it to show it has been marked by the player.  We can check to see if it is a space.
If it is a space, then the game has not been completed.  If it is neither a digit, nor a properly covered bomb, then again, the game has not been completed.  Note that the isspace option is not really necessary – we could omit it, as it is neither a digit nor a covered bomb, so would be picked out as being an incomplete square anyway.

Here's an alternative which is probably a bit closer to what you could do in the time given:-

Note that it doesn't make full use of many of the features of C, although it does demonstrate an understanding of them, which is sufficient for exam purposes.

By using constants, we can reduce the size of the board during testing and number of bombs. For example, to check if the game over part works, we might reduce the board size to 2x2 and have only 1 bomb. This reduces the time it takes to do the testing.

In this example, the A1 way of referring to cells has been abandoned.  Often, even though you cannot remember how to do exactly what is required, you may be able to do something else which is close enough to keep the program working as it should.  You should lose few marks, so long as you explain why you have done this, and give a viable alternative.

/*

** Bombs Game - Easier version

** by Simon Huggins - 9th April 2002

** Introduction to Programming Course (C Element)

**

*/

 

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <ctype.h>

#include <string.h>

 

 

/* Define function prototypes */

void set_up_arrays();

int check_game_over();

 

/* Define constants for grid size and number of bombs */

int const rows = 10, cols = 10, bombs = 10;

 

/* Define global variable arrays for visible & invisible grids */

char visible[rows][cols],invisible[rows][cols];

 

 

/* Main Loop */

 

void main() {

  /* Local variables [visible only in main()] */

  char prompt;  // hold keyboard character input

  int rowpos,colpos,count;  // chosen row / column and bomb counter

 

  randomize(); /* Randomize generated numbers */

  set_up_arrays(); /* Set up arrays with blanks and bombs */

 

  /* Main loop */

  do {

 

    /* Print title, headings & visible array contents */

    clrscr();

    printf("Bombs Game\n==========\n\n");

    printf("   0 1 2 3 4 5 6 7 8 9\n");

    printf("--+-------------------\n");

    for (int i=0; i<rows; i++) {

      printf("%2d|",i);

      for (int j=0; j<rows; j++)

        printf("%c ",visible[i][j]);

      printf("\n");

    }

    printf("--+-------------------\n\n");

 

    /* If board has all been marked, break from the loop to finish game

       Note chose to do this before anything else after some testing,

       otherwise final revealed square is not shown when game over */

    if (check_game_over()) break; //from do..while statement

 

 

    printf("Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it: ");

    prompt = (char)toupper(getch());

    printf("%c\n",prompt);

 

    /* if not exiting the loop, get the grid row and column values */

    if (prompt != 'X') {

      /* Not sure how to do A5 style reference, so using col,row format */

      printf("Enter a grid reference col,row (eg. top-right is 9,0): ");

      scanf("%d,%d",&colpos,&rowpos);

 

      /* If row and column not in range, skip to end of loop and go around again */

      if ((rowpos<0) || (rowpos>=rows) || (colpos<0) || (colpos>=cols))

        continue;

    }

 

    /* Respond to menu option */

    switch(prompt) {

      case('M') : visible[rowpos][colpos] = 'X'; break;

      case('U') : visible[rowpos][colpos] = ' '; break;

      case('R') :

      /* Check to see if the current cell is a bomb.

         If it is, displays a game over message and exits

         If not, reveals current row / col with number of surrounding bombs */

        if (invisible[rowpos][colpos]=='B') {

          printf("BOOM! You hit a bomb. GAME OVER. "); prompt='X';

        } else {

          count=0;

          for (int i=rowpos-1; i<=rowpos+1; i++)  // for above, same & below row

            for (int j=colpos-1; j<=colpos+1; j++)  // for left, same & right column

            // Make sure that the given row / column is on the grid

            if ((i >= 0) && (i < rows) && (j >= 0) && (j < cols))

              // And if it is a bomb, add one to the count of surrounding bombs

              if (invisible[i][j]=='B') count++;

          // Set the visible square to be a '0' character plus the count.

          visible[rowpos][colpos] = (char)('0' + count);

        }

        break;

 

      /* If user doesn't want to exit, use a non-X character */

      case('X') : printf("Quit? Press Y for Yes or N for No: ");

                  prompt = (char)getch(); printf("%c\n",prompt);

                  if ((prompt=='Y')||(prompt=='y')) prompt = 'X';

                  else prompt = '?';

    }

 

  } while (prompt != 'X'); /* Keeps getting user option */

 

  /* Closing message and await a keypress */

  printf("Press a key to finish. ");

  getch();

}

 

 

/* Set visible & invisible arrays to blank and

   set up bombs in invisible array */

void set_up_arrays() {

  int rowpos, colpos;

 

  /* Fill both grids with spaces */

  for (int i=0; i<rows; i++)

    for (int j=0; j<cols; j++) {

      visible[i][j] = ' ';

      invisible[i][j] = ' ';

    }

  /* Set up bombs in invisible array */

  for (int i=0; i<bombs; i++) {

      rowpos = rand() % rows;

      colpos = rand() % cols;

    invisible[rowpos][colpos] = 'B';

  }

}

 

/* Check to see if game is over. If all visible squares are

   spaces or Xs with bombs in respective invisible square,

   then game is over */

 

int check_game_over() {

 

  int isdigit, coveredbomb, isspace;

 

  for (int i=0; i<rows; i++)

    for (int j=0; j<cols; j++) {

 

      // is the grid character anything between a '0' and a '9'?

      isdigit = (visible[i][j] >='0') || (visible[i][j]<='9');

      // is the grid character a 'B' and has user put an 'X' over it correctly?

      coveredbomb = (visible[i][j]=='X') && (invisible[i][j]=='B');

      // is the visible character a space (i.e. unmarked)?

      isspace = (visible[i][j]==' ');

      /* if the grid character is a space, or if it is neither a digit nor bomb,

         then the game is incomplete */

      if ((!isdigit && !coveredbomb) || isspace) return false;

    }

 

  /* Everything is marked, so display a message */

  printf("GAME OVER. Well Done. All bombs found. ");

  return true;

}

f) Test Plan and Results

Function

Expected Results

Actual Results

Does title display OK?

Bombs Game

==========

Ok

Columns headings display correctly

A B C D E F G H I J

Ok

Ten row numbers displayed

1 through to 10

Ok

Menu option appears with prompt

Choose from: [R]eveal, [M]ark, [U]nmark or e[X]it: with cursor after the colon.

Ok

Press letters other than R, M, U, or X

Try: Q, v, 1 and @.
Expect screen to be refreshed and option to be redisplayed.

Ok

Press X and then N

Are you sure you wish to quit? prompt. When press N, scren refreshed and options redisplayed.

Ok

Press X and then Y

Are you sure prompt followed by Press A Key to Finish prompt

Ok

Press R for Reveal

Try uppercase R.

Try Lowercase r.

Try coords A0,J11,@5,K10 – All should be rejected.

Try coords A1, A10,J1,J10,E5 – all should be accepted

R and r – same result.

A0,J11,@5,K10 – prompts to enter again. A10,J1,J10,E5 – all revealed OK.

Press M for Mark

Press M and m. Try over same square twice – A5 – should show X

Both M and m accepted. X shown at A5 on screen. No change if do twice.

Press U for Unmark

Press U and u.  Try over same square twice – A5. Should show blank

Both U and u accepted. space shown at A5 on screen (X removed). No change if do twice.

Intentionally incomplete board by putting extra X in wrong place. Then correct this by revealing this X.

Set bomb to 1, rows & cols to 2.

Should stay in game awaiting response until X that is not over bomb is revealed, then game over (congratulatory message)

Hit bomb first time. Second time, worked out correct position. Put X over wrong square + over bomb and revealed other two squares. Game not over. Revealed non-bomb square. Game over with "Well Done".

Ensure bomb hit properly

Keep board setting as above. Ensure know where bomb is, and instead of putting X over it, reveal it.

Should have BOOM message and game over.

Game over – BOOM! message.