- July 10, 2020
7/9/2020 CS 136 Assignment 7 https://www.student.cs.uwaterloo.ca/~cs136/current/assignments/a7/ 1/4 Question 4: Minesweeper [30 marks correctness] The video game Minesweeper ([Wikipedia], [play online]) is played on a rectangular board that contains numerous hidden mines. Unfortunately, you do not know which squares on the board are safe and which ones contain mines. You have two options on how to interact with a square: you can step on it if you think it is safe, or you can mark it if you suspect that it contains a mine. Stepping on a square that contains a mine is a fatal move and will end the game. Stepping on a safe square, however, will reveal a number between 0 and 8, which indicates how many of the eight neighbouring squares contain mines. You win the game if you have marked all mines on the board without marking any safe squares. Each game of Minesweeper consists of three phases: initialization, play loop, and resolution. 1. During initialization, the game board is set up and mines are randomly distributed on the board. Within the program, there are two version of the game board: 1. The complete board contains information about the location of mines, i.e., the solution of the game. 2. The player board is an empty version of the complete board. It represents the player’s knowledge of the board. During the play loop, the player board is populated with the results of the player’s moves. 2. The play loop consists of a series of actions from the player to game followed by output from the game to the player. The player can choose between three possible actions: (1) stepping on one square, (2) marking one square, or (3) quitting the game. 1. Stepping on a square requires two additional integers as input that indicate the column and the row. 2. Similarly, marking a square requires two additional integers as input that indicate the column and row. 3. Last, quitting the game does not require additional player input 3. There are three conditions under which the game resolves: (1) the player steps on a square with a mine, which immediately ends the game; (2) the player successfully marks all squares that contain mines without marking any that do not contain mines; (3) the player quits the game by typing Q into the command line. Your task is to implement Minesweeper! Luckily, you are not alone: you have teamed up with two co-workers and split the project three parts: the game core, the game client, and the main program. 1. The game core manages the initialization and controls access to the complete board. One of your co-workers has already implemented this module (game_core). 2. The main program manages user input and basic error-handling. One of your co- workers has already implemented this (main.c). 7/9/2020 CS 136 Assignment 7 https://www.student.cs.uwaterloo.ca/~cs136/current/assignments/a7/ 2/4 3. The game client manages the player board and ties the game core and the main program together. It is your responsibility to implement this module (game_client). There are two functions provided in the game core module that allow interaction with the complete board, mine_at and board_complete. Please see game_core.h for documentation. There are six commands available to players as input into the main program. Please see main.c for documentation. BLACK QUESTION (moderate collaboration allowed) a. Implement the functions step, mark, and print: step performes a step onto the square with coordinates (c,r). The function returns true if (c,r) contains a mine, and false if it does not. It also returns false if (col,row) as been stepped on previously or if it is currently marked. The function is also responsible for updating the player board with the correct value (for possible values, see below). mark toggles the mark on the square with coordinates (c,r). If the square is currently unmarked, mark adds a mark, if it is currently marked, markremoves the mark; if the square has been stepped on before mark does not add a mark. The function returns true if the player has successfully completed the board, and false otherwise. The function is also responsible for updating the player board with the correct value (for possible values, see below). print prints the player board. UNKNOWN squares are printed as _, MARKEDsquares as P, MINEs as X, and all other squares as their number (0-8). After printing the player board, the fucntion also prints a line of equal sign (‘=’) to visually separate multiple player boards. Note that all squares are (horizontally) separated by a space (‘ ‘) (see below for an example). Both step and mark must update the player board to reflect the new state of the manipulated square. The player board is created together with the complete boardby the game core during initialization. The player board is stored as player_boardin game_core. Please see game_core.h for more documentation. In summary, a square on the player board must have one of the following values: 0-8 indicating the numbers of mines in its eight adjacent squares, UNKNOWN, MARKED, or MINE. For reference, this is an example of a player board at the beginning, half-way through, and at the conclusion of a game (stepped on a mine at (5,1)): 7/9/2020 CS 136 Assignment 7 https://www.student.cs.uwaterloo.ca/~cs136/current/assignments/a7/ 3/4 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =============== 1 P _ _ _ _ 1 0 1 1 1 1 _ _ 1 0 0 0 0 1 P _ 1 0 0 0 0 1 3 _ 2 0 1 1 1 0 2 _ 2 0 _ P 2 1 2 _ 2 1 1 2 _ _ _ _ _ _ 0 1 _ _ _ _ _ 1 =============== 1 P 1 0 1 _ 1 0 1 1 1 1 _ X 1 0 0 0 0 1 P _ 1 0 0 0 0 1 3 _ 2 0 1 1 1 0 2 _ 2 0 _ P 2 1 2 _ 2 1 1 2 _ _ _ _ _ _ 0 1 _ _ _ _ _ 1 =============== Hints: The top-left square has the coordinate (0,0); the bottom-right square has the coordinate (width-1,height-1). While the game allows for board-sizes to be of arbitrary length, we will not test sizes larger than (20,10). Remember that user input as well as most function calls operate on 2D- input (c,r), whereas player_board is a 1D-array. You might have to re-calculate indices. It might be useful to write a helper-function for “clamping”. Clamping means to limit a value to between a given minimum and a maximum. Your colleague added the function board_debug to game_core. You can use this function to print out the complete board. Be aware that this function is for debug purposes only: all calls to it must be removed before submitting your code. For this question, the Marmoset basic tests (“public” tests) will use the provided test simple. GOLD QUESTIONS (no collaboration allowed) LANGUAGE FEATURES: For this sub-question, you may use recursion. It is possible that a player steps on a square that is not adjacent to any mines. In standard Minesweeper, the game will then step on all eight adjacent fields for the player. This is safe, as none of the adjacent square contain any mines. Note that this process is done recursively, i.e., if newly revealed square also has no adjacent mines, the process continues from there. This oftentimes leads to larger sections the board opening up, thus making it more convenient to solve the game. Below you can see the result of the command A 0 2: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =============== _ _ _ _ _ _ _ _ 1 1 1 1 _ _ _ _ 0 0 0 1 _ _ _ _ 0 0 0 1 3 _ _ _ 1 1 1 0 2 _ _ _ _ _ 2 1 2 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =============== 7/9/2020 CS 136 Assignment 7 https://www.student.cs.uwaterloo.ca/~cs136/current/assignments/a7/ 4/4 b. Implement step_adv. This function exhibits the above-described behaviour of stepping on all squares that are adjacent to 0 mines. For this implementation, you might want to extend the functionality of step from part a). For this question, the Marmoset basic tests (“public” tests) will use the provided test simple.