Skip to content

Instantly share code, notes, and snippets.

@Happypig375
Last active September 17, 2023 19:00
Show Gist options
  • Save Happypig375/f3250edf40333edf4164f00a20f40513 to your computer and use it in GitHub Desktop.
Save Happypig375/f3250edf40333edf4164f00a20f40513 to your computer and use it in GitHub Desktop.
COMP2012H Quan Long solves a bug (Bug is seen from the difference in output from lines 24 and 27 of main.cpp)
/* -------------------------------------------------------------- */
/* This part serves as a pseudo random number generator for auto grade purpose only */
/* You are suggested not to refer to these codes in this assignment. */
/* You are not allowed to use global variables in this course. */
unsigned int next_num = 1; // Here we initiate an unsigned integer to be used in the following functions.
unsigned int custom_rand() // This function is used to return a pseudo random number from 0 to 32767.
{
next_num = next_num * 1103515245 + 2011;
return static_cast<unsigned int>(next_num / 65536) % 32768;
}
void custom_srand(unsigned int seed) // This function is used to set a seed of the pseudo random number generator.
{
next_num = seed;
}
/* Everytime you call rand(), you will get a new pseudo random number. For the same seed, the sequence of pseudo
random number is fixed. For example, when seed = 3, the sequence of pseudo random number is fixed to be [17746,
30897, 9622, 18921, 4034, 17510, 24152, 14388, 23665, 31532, ...]. When seed = 5, the sequence of pseudo random
number is fixed to be [18655, 32247, 9873, 9718, 26373, 27678, 5314, 22512, 31845, 22885, ...] */
/* -------------------------------------------------------------- */
/* -------------------------------------------------------------- */
/* Your tasks begin below this line */
/* -------------------------------------------------------------- */
/**
* TODO
*
* Initialize displayBoard's all entries to -1.
*/
void initializeDisplayBoard(int displayBoard[NUM_BOARD_ROWS][NUM_BOARD_COLS]) {
for (int row = 0; row <= NUM_BOARD_ROWS; ++row) {
for (int col = 0; col <= NUM_BOARD_COLS; ++col) {
displayBoard[row][col] = -1;
}
}
}
/**
* TODO
*
* Return a char corresponding to the display tile's value.
* - Unexcavated tile: ' '
* - Flagged tile: '#'
* - Excavated tile: the tile's value
*/
char getDisplayChar(int displayBoardTile) {
if (displayBoardTile == -1)
return ' ';
else if (displayBoardTile >= 0 && displayBoardTile <= 9)
return char(displayBoardTile + 48);
else
return '#';
}
/**
* TODO
*
* Check if the player has won the game.
* The game is won when all non-mine tiles have been excavated.
*/
bool checkWin(int displayBoard[][NUM_BOARD_COLS], bool minesweeperBoard[][NUM_BOARD_COLS]) {
for (int r = 0; r < NUM_BOARD_ROWS; r++) {
for (int c = 0; c < NUM_BOARD_COLS; c++) {
if (!minesweeperBoard[r][c] && (displayBoard[r][c] == -1 || displayBoard[r][c] == 10))
return false;
}
}
return true;
}
/**
* TODO
*
* Toggle the flag status on the specified tile.
* If the tile is unexcavated, set it to flagged. If it is flagged, set it to unexcavated. Ignore excavated tiles.
* You can assume (row, col) refers to a valid tile.
*/
void setFlag(int displayBoard[][NUM_BOARD_COLS], int row, int col) {
if (displayBoard[row][col] == -1) displayBoard[row][col] = 10;
else if (displayBoard[row][col] == 10) displayBoard[row][col] = -1;
}
/**
* TODO
*
* Excavate the specified tile by:
* - Counting the number of adjacent mines
* - Set the tile value to that number
* - If the value is 0, excavate all unexcavated adjacent tiles without flags.
* You can assume (row, col) refers to a valid unexcavated tile. However, make sure your recursive calls also provide valid parameters.
*/
void excavateTile(int displayBoard[][NUM_BOARD_COLS], int row, int col, bool minesweeperBoard[][NUM_BOARD_COLS]) {
if (displayBoard[row][col] != -1) return;
displayBoard[row][col] = 0;
for (int r = max(row-1, 0); r <= min(row+1,NUM_BOARD_ROWS); r++) {
for (int c = max(col-1, 0); c <= min(col+1,NUM_BOARD_COLS); c++) {
displayBoard[row][col] += (minesweeperBoard[r][c] == true);
}
}
if (displayBoard[row][col] == 0) {
for (int r = max(row-1, 0); r <= min(row+1,NUM_BOARD_ROWS); r++) {
for (int c = max(col-1, 0); c <= min(col+1,NUM_BOARD_COLS); c++) {
if (r != row || c != col) excavateTile(displayBoard, r, c, minesweeperBoard);
}
}
}
}
// Show minesweeper board for debugging
void showMSB(bool minesweeperBoard[][NUM_BOARD_COLS]) {
cout << "MSB" << endl;
for (int row = 0; row < NUM_BOARD_ROWS; ++row) {
for (int col = 0; col < NUM_BOARD_COLS; ++col) {
// custom_rand() gives a number between 0 and 32767, this means there are roughly 7.5% bombs
cout << minesweeperBoard[row][col] << " ";
}
cout << endl;
}
cout << "MSB" << endl << endl;
}
// Show display board for debugging
void showDB(int displayBoard[][NUM_BOARD_COLS]) {
cout << "DB" << endl;
for (int row = 0; row < NUM_BOARD_ROWS; ++row) {
for (int col = 0; col < NUM_BOARD_COLS; ++col) {
// custom_rand() gives a number between 0 and 32767, this means there are roughly 7.5% bombs
cout << displayBoard[row][col] << " ";
}
cout << endl;
}
cout << "DB" << endl << endl;
}
#include <iostream>
using namespace std;
// Constants
const int NUM_BOARD_ROWS = 8;
const int NUM_BOARD_COLS = 8;
#include "functions.h"
int main() {
// Set the random number generator seed
custom_srand(2023);
// Initialize the minesweeper board and the display board
bool minesweeperBoard[NUM_BOARD_ROWS][NUM_BOARD_COLS];
for (int row = 0; row < NUM_BOARD_ROWS; ++row) {
for (int col = 0; col < NUM_BOARD_COLS; ++col) {
// custom_rand() gives a number between 0 and 32767, this means there are roughly 7.5% bombs
minesweeperBoard[row][col] = custom_rand() < 2500;
}
}
int displayBoard[NUM_BOARD_ROWS][NUM_BOARD_COLS];
showMSB(minesweeperBoard);
// Task 1: We initialize the displayBoard here
initializeDisplayBoard(displayBoard);
showMSB(minesweeperBoard);
int choice;
do {
// This big section prints the board
cout << ' ';
for (int col = 0; col < NUM_BOARD_COLS; ++col)
cout << col << ' ';
cout << endl;
for (int col = 0; col < 2*NUM_BOARD_COLS+1; ++col)
cout << '=';
cout << endl;
for (int row = 0; row < NUM_BOARD_ROWS; ++row) {
for (int col = 0; col < NUM_BOARD_COLS; ++col) {
// Task 2: We print the displayBoard here
cout << '|' << getDisplayChar(displayBoard[row][col]);
}
cout << '|' << ' ' << row << endl;
}
for (int col = 0; col < 2*NUM_BOARD_COLS+1; ++col)
cout << '=';
cout << endl;
// Task 3: We check for win condition here
if (checkWin(displayBoard, minesweeperBoard)) {
cout << "Congratulations! You won!" << endl;
break;
}
cout << endl << "Select an option: " << endl;
cout << "0: Exit" << endl;
cout << "1: Excavate a tile" << endl;
cout << "2: Place a flag" << endl;
cin >> choice;
if (choice < 0 || choice > 2) {
cout << "Invalid choice." << endl;
continue;
}
if (choice == 0) {
break;
}
int rowChoice, colChoice;
do {
cout << "Choose a row from 0 to " << NUM_BOARD_ROWS - 1 << ": " << endl;
cin >> rowChoice;
if (rowChoice < 0 || rowChoice >= NUM_BOARD_ROWS) {
cout << "Row index out of range, try again." << endl;
continue;
}
else
break;
} while (true);
do {
cout << "Choose a column from 0 to " << NUM_BOARD_COLS - 1 << ": " << endl;
cin >> colChoice;
if (colChoice < 0 || colChoice >= NUM_BOARD_COLS) {
cout << "Column index out of range, try again." << endl;
continue;
}
else
break;
} while (true);
if (choice == 2) {
// Task 4: The player toggles the flag status on the provided coordinate
setFlag(displayBoard, rowChoice, colChoice);
}
else {
if (displayBoard[rowChoice][colChoice] != -1) continue;
else if (minesweeperBoard[rowChoice][colChoice]) {
// Modified version of the board print to show the bombs
cout << ' ';
for (int col = 0; col < NUM_BOARD_COLS; ++col)
cout << col << ' ';
cout << endl;
for (int col = 0; col < 2*NUM_BOARD_COLS+1; ++col)
cout << '=';
cout << endl;
for (int row = 0; row < NUM_BOARD_ROWS; ++row) {
for (int col = 0; col < NUM_BOARD_COLS; ++col) {
cout << '|' << (minesweeperBoard[row][col] ? '*' : getDisplayChar(displayBoard[row][col]));
}
cout << '|' << ' ' << row << endl;
}
for (int col = 0; col < 2*NUM_BOARD_COLS+1; ++col)
cout << '=';
cout << endl;
cout << "Game over! You excavated a mine!" << endl;
break;
}
else {
// Task 5: The player excavates the chosen tile
excavateTile(displayBoard, rowChoice, colChoice, minesweeperBoard);
}
}
} while (true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment