Objective:
Students will display their knowledge of all course material to build a complete computer program with a real-world application.
Problem:
You are a part of an artificial intelligence design team at Queen’s, which is currently developing a software that can perform probability analysis with imperfect information. In a given scenario, the AI should be able to evaluate each decision alternative and determine which has the highest likelihood of success. This will have a variety of applications where limited information is available, such as evaluation of economic projects or natural disaster contingency planning.
Before it is ready for these purposes, however, the AI needs to be “trained” on how to make optimal decisions. To do this, the team has decided to have the software play probability-based decision-making games, where it can learn elements of risky decisions versus safe ones. You have been tasked with programming one of these games: minesweeper.
Minesweeper Rules:
The basics of the game are fairly straightforward: there are a number of mines scattered across a grid. If all “cells” that DO NOT contain mines are revealed, the AI (player) wins. If a mine is uncovered, the AI loses.
The remainder of this document will refer to a “cell”, which is a unique pair of indices on a 2-dimensional array. An index pair represents the row and the column. For example, (3, 4) is a cell, representing the 5thindex of the 4throw in the grid.
This implementation of the game will be played on a 10 x 10 grid, using 10 mines. These mines will be distributed randomly about the grid, which can be done using therandfunction. Other cells in the grid will have a numerical value that indicates the number of adjacent cells that contain a mine (including diagonals). However, this information will be secret and the AI (player) will begin by seeing only blank cells. A visualization of the actual cell values versus what the AI sees is shown below, where ‘M’ indicates a mine and ‘*’ indicates a hidden cell.
1
|
M
|
2
|
1
|
|
*
|
*
|
*
|
*
|
1
|
1
|
3
|
M
|
|
*
|
*
|
*
|
*
|
0
|
0
|
2
|
M
|
|
*
|
*
|
*
|
*
|
0
|
0
|
1
|
1
|
|
*
|
*
|
*
|
*
|
Actual Cell Values
|
|
AI Starting View
|
The AI can make 2 different moves: either check a cell, or flag a cell. There are no restrictions on what cell it can choose, though nothing will happen if the cell is not hidden.
- To check a cell, the information on that cell is revealed to the AI.
- If that cell is a mine, the AI loses the game.
- If that cell is a 0, all adjacent cells will also be revealed. If any of those cells are a 0, the process is repeated. In this way, all cells with a 0 that are “connected” to the original cell will be revealed, as well as all surrounding cells.
- To flag a cell, the asterisk is replaced by a ‘F’. While this has no real in-game effect, the AI can use it to record the position of a mine (it doesn’t matter whether the AI is right or wrong about this choice). Only a hidden cell can be flagged.
As an example,if the AI decides to check row 3 column 1 on the above grid, they would type in c 2 0,and the following cells will be revealed (the underlined cell indicates the AI’s selection). If the AI had not chosen a cell containing a 0, only that one cell would have been revealed.
A win condition is reached when all cells that do not contain mines have been revealed. An example of this is shown below (the hidden cells are highlighted, to show that cells don’t have to be flagged to win the game).
Try playing the game online (such as at this site:https://minesweeperonline.com/#150) to get a better understanding of how it works if you are unfamiliar!
Instructions:
Write a minesweeper program in C that uses the following specifications:
- Uses a 10 x 10 grid.
- Adds 10 mines into the grid using the rand function, with a seed of 2. See the rand Function Example Code for help with this.
- Each cell that does not contain a mine must contain the number of adjacent mines.
- Your code must contain the following functions.The function headers specified below cannot be altered, and the shown arguments cannot be changed. You may create additional functions if you want!
- The void functionprintGrid ()will output the current grid to the console.
- The functioncheck (int row, int col)will check the indicated cell, and reveals all necessary cells to the AI. Returns 0 if a mine was hit, and 1 otherwise.
- The void functionflag (int row, int col)will place a flag on the indicated cell if it is hidden.
- The functioncheckWin ()function will determine if the win condition has been met. Returns 1 if the game has been won, and 0 otherwise.
- The AI must be allowed to perform a check or flag move on any hidden cell. Keep in mind thatthe input given by the user is the index, and should follow standard array indexing procedure (eg., the first row is index 0).
- The updated grid must be printed to the console after every move.
- The following command prompt must be printed to the console for every move.Please note, on some systems copying and pasting the following will result in incorrect quotation marks due to Mimirs weird font:
Enter ‘c’ for check cell, ‘f’ for flag cell.
Enter command & cell row col:
- When a mine is revealed, the following message must be printed:
You hit a mine, game over.
- When the win condition has been met, the following message must be printed:
Congratulations! You win!
Your program will need to take user input for each command from the AI. Read this input with thescanffunction, using the format shown in bold in the sample output.
Comments are mandatory for this assignment. Add comments as necessary for important parts of your code, such as function calls & definitions, conditions, and calculations to explain what the program is doing.
Your output must match the sample output below as closely as possible; otherwise, the autograding software will not be able to grade your assignment, which may affect your mark.
Sample Output:
ForCLion on a windows PCthe actual values of the grid are as follows:
1 |
M |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
M |
2 |
2 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
2 |
M |
2 |
M |
M |
1 |
0 |
0 |
0 |
1 |
2 |
2 |
2 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
M |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
M |
1 |
M |
1 |
0 |
2 |
M |
2 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
2 |
M |
2 |
0 |
0 |
0 |
ForCLion on a MACthe actual values of the are as follows:
0 |
0 |
1 |
M |
M |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
2 |
2 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
M |
1 |
0 |
1 |
2 |
2 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
M |
M |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
2 |
2 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
M |
1 |
0 |
1 |
M |
2 |
1 |
1 |
1 |
1 |
1 |
2 |
1 |
2 |
2 |
M |
1 |
M |
1 |
0 |
0 |
1 |
M |
1 |
1 |
1 |
ForMimirthe actual values of the grid are as follows:
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
2 |
M |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
M |
3 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
2 |
M |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
2 |
1 |
0 |
0 |
1 |
M |
1 |
0 |
2 |
M |
2 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
2 |
M |
2 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
2 |
1 |
M |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
M |
1 |
1 |
1 |
1 |
2 |
M |
1 |
0 |
1 |
1 |
0 |
0 |
1 |
M |
2 |
1 |
1 |
0 |
0 |
0 |
The below output is from shows the initial state of the console, and the results of the AI entering a check command for the cell in the 5throw of the 4thcolumn.Note that this sample output was built in CLion and is just meant to show how the check function works generally.Each cell in the grid is separated by two spaces, “__”, when printed. Make sure each line of output text also prints a new line.
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
Enter 'c' for check cell, 'f' for flag cell.
Enter command & cell row col:c 4 3
* * 1 0 0 0 0 0 0 0
1 1 1 0 0 1 1 1 0 0
0 0 0 0 0 1 * 2 2 1
1 1 0 0 0 1 * * * *
* 1 0 0 0 1 * * * *
1 1 0 0 0 1 * * * *
0 0 0 0 0 1 * * * *
1 1 1 0 1 1 * * * *
* * 1 0 2 * * * * *
* * 1 0 2 * * * * *
Enter 'c' for check cell, 'f' for flag cell.
Enter command & cell row col:
Helpful Hints:
This project may look daunting at first; however, these tips should help you get started and keep you coding in the right direction.
- Start by setting up 2 different grids: one to hold all the mines and number values in each cell, and the other to hold the information available to the AI. Whenever you need to reveal a cell, you can then copy the contents from one grid to another!
- Keep in mind that the rand function may cause mines with overlapping coordinates. To avoid this, use a loop to make sure the cell you generate isn’t already filled.
- When counting adjacent mines, you can increment every cell that is adjacent to a mine when it gets added to the array initially.
- Similarly, your check function can recursively call itself for every adjacent cell if the current cell contains a 0. Make sure you have a way to check if the cell has already been revealed (or else face an infinite loop)!
- You can check if the win condition has been met by counting the number of cells that have not been revealed.
Submission Instructions:
You can either utilize the Mimir IDE found here to create and submit your program, or create your program using CLion and upload it here for grading. Your program file must be named “apsc143project.c” in order for your assignment to be graded. Do not include any personal information (student number, name, etc.) in your submission.
To compile and run the program in the Mimir IDE, enter the following command into the terminal:
gcc apsc143project.c -lm -o project && ./project
Refer to the assignment rubric on OnQ for a detailed breakdown of the grading criteria. Your submission must adhere to the assignment rules as outlined in the submission policy document for this course, which can also be found on OnQ. There is zero tolerance for plagiarism in this course. This autograding software will automatically flag potential cases of plagiarism, which will be reviewed by the instructors.
More information on both assignment submissions and the specific definition and repercussions of plagiarism can be found in the “Begin Here (About This Course)” module on OnQ in the “Assignments” and “Plagiarism” videos, respectively.
randFunction Example Code:
Therandfunction requires thestdlib.hlibrary. Before therandfunction can be used, the function must first be “seeded” using thesrandfunction. This seeding causes the numbers to take on specific values during the running process, which makes your program easier to grade.
Typically, therandfunction produces an integer between 0 and approximately 33 000. To make sure the random valuexis in the range we need for this project, use the formula shown below.minis the smallest possible value forx, andrangeis the total number of different values we want the program to be able to generate. For example, to generate a number between 10 and 15inclusivethe range must be 6. The formula will force the randomly generated value into the range [min,min+range– 1].
#include
int main() {
srand(2);
int x = rand() % range + min;