Minesweeper - C
The other day I was tutoring a freshman programmer program his first minesweeper text game in C++. Here is the resulting code.
#include <iostream>
#include<cstdlib>
#include<ctime>
const int DIMX = 6;
const int DIMY = 6;
const int MINES = 6;
const int MINE = -1;
const char COVERED = 'X';
const char UNCOVERED = ' ';
const char FLAG = 'F';
int state[DIMX][DIMY];
char display[DIMX][DIMY];
void init(); // initialize game states
int countSorroundingMines(int x, int y); // helper function used by init
void reveal(int x, int y);
void player(); // handle player input
void setFlag();
void uncover();
void print(); // print the minefield
void cheat(); // print out the mines
bool isWin();
bool isLose();
bool playNewGame();
int main() {
ใใใใstd::cout << "Welcome to MineSweeper!" << std::endl;
ใใใใinit();
ใใใใbool playing = true;
ใใใใwhile(playing) {
ใใใใใใใใprint();
ใใใใใใใใplayer();
ใใใใใใใใif(isWin()) {
ใใใใใใใใใใใใstd::cout << "You Win!" << std::endl;
ใใใใใใใใใใใใplaying = false;
ใใใใใใใใ} else if(isLose()) {
ใใใใใใใใใใใใstd::cout << "You Lose!" << std::endl;
ใใใใใใใใใใใใplaying = false;
ใใใใใใใใ}
ใใใใใใใใif(!playing) {
ใใใใใใใใใใใใplaying = playNewGame();
ใใใใใใใใใใใใif(playing) {
ใใใใใใใใใใใใใใใใinit();
ใใใใใใใใใใใใ}
ใใใใใใใใ}
ใใใใ}
ใใใใstd::cout << "Exiting Minesweeper!" << std::endl;
ใใใใreturn 0;
}
void init() {
ใใใใstd::cout << "New Game!" << std::endl;
ใใใใ// set display to "uncovered"
ใใใใfor(int y = 0; y < DIMY; y++) {
ใใใใใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใใใใใdisplay[x][y] = COVERED;
ใใใใใใใใ}
ใใใใ}
ใใใใ// initialize mines
ใใใใsrand(time(0));
ใใใใfor(int i = 0; i < MINES; i++) {
ใใใใใใใใbool placed = false;
ใใใใใใใใwhile(!placed) {
ใใใใใใใใใใใใint x = rand() % DIMX;
ใใใใใใใใใใใใint y = rand() % DIMY;
ใใใใใใใใใใใใif(state[x][y] != MINE) { // check mine not set
ใใใใใใใใใใใใใใใใplaced = true;
ใใใใใใใใใใใใใใใใstate[x][y] = MINE;
ใใใใใใใใใใใใ}
ใใใใใใใใ}
ใใใใ}
ใใใใ// place hint numbers
ใใใใfor(int y = 0; y < DIMY; y++) {
ใใใใใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใใใใใstate[x][y] = countSorroundingMines(x, y);
ใใใใใใใใ}
ใใใใ}
}
bool playNewGame() {
ใใใใbool selected = false;
ใใใใwhile(!selected) {
ใใใใใใใใchar choice;
ใใใใใใใใstd::cout << "Play another game? Y or N" << std::endl;
ใใใใใใใใstd::cin >> choice;
ใใใใใใใใif(choice == 'N' || choice == 'n') {
ใใใใใใใใใใใใreturn false;
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else if(choice == 'Y' || choice == 'y') {
ใใใใใใใใใใใใreturn true;
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else {
ใใใใใใใใใใใใstd::cout << "That is not a valid choice!" << std::endl;
ใใใใใใใใ}
ใใใใ}
}
void reveal(int x, int y) {
ใใใใif(x >= 0 && x < DIMX && y >= 0 && y < DIMY) { // check that x and y are valid
ใใใใใใใใif(display[x][y] == UNCOVERED) {
ใใใใใใใใใใใใreturn;
ใใใใใใใใ}
ใใใใใใใใdisplay[x][y] = UNCOVERED;
ใใใใใใใใif(state[x][y] == MINE || state[x][y] != 0) {
ใใใใใใใใใใใใreturn;
ใใใใใใใใ}
ใใใใใใใใreveal(x - 1, y - 1);
ใใใใใใใใreveal(x, y - 1);
ใใใใใใใใreveal(x + 1, y - 1);
ใใใใใใใใreveal(x - 1, y);
ใใใใใใใใreveal(x + 1, y);
ใใใใใใใใreveal(x - 1, y + 1);
ใใใใใใใใreveal(x, y + 1);
ใใใใใใใใreveal(x + 1, y + 1);
ใใใใ} else {
ใใใใใใใใreturn;
ใใใใ}
}
/*
[x-1, y-1][x, y-1][x+1, y-1]
[x-1, y ][x, y ][x+1, y ]
[x-1, y+1][x, y+1][x+1, y+1]
*/
int countSorroundingMines(int x, int y) {
ใใใใif(state[x][y] == MINE) {
ใใใใใใใใreturn MINE;
ใใใใ}
ใใใใint num = 0;
ใใใใif(x > 0 && y > 0) { // top left
ใใใใใใใใif(state[x - 1][y - 1] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(y > 0) { // top
ใใใใใใใใif(state[x][y - 1] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(x < DIMX - 1 && y > 0) { // top right
ใใใใใใใใif(state[x + 1][y - 1] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(x > 0) { // left
ใใใใใใใใif(state[x - 1][y] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(x < DIMX - 1) { // right
ใใใใใใใใif(state[x + 1][y] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(x > 0 && y < DIMY - 1) { // bottom left
ใใใใใใใใif(state[x - 1][y + 1] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(y < DIMY - 1) { // bottom
ใใใใใใใใif(state[x][y + 1] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใif(x < DIMX - 1 && y < DIMY - 1) { // bottom right
ใใใใใใใใif(state[x + 1][y + 1] == MINE) {
ใใใใใใใใใใใใnum++;
ใใใใใใใใ}
ใใใใ}
ใใใใreturn num;
}
bool isWin() {
ใใใใbool win = true;
ใใใใfor(int y = 0; y < DIMY; y++) {
ใใใใใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใใใใใwin &= ((display[x][y] == UNCOVERED && state[x][y] != MINE) ||
ใใใใใใใใใใใใใใใใใใใใ((display[x][y] == COVERED || display[x][y] == FLAG) && state[x][y] == MINE));
ใใใใใใใใ}
ใใใใ}
ใใใใreturn win;
}
bool isLose() {
ใใใใfor(int y = 0; y < DIMY; y++) {
ใใใใใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใใใใใif (display[x][y] == UNCOVERED && state[x][y] == MINE) {
ใใใใใใใใใใใใใใใใreturn true;
ใใใใใใใใใใใใ}
ใใใใใใใใ}
ใใใใ}
ใใใใreturn false;
}
void player() {
ใใใใstd::cout << "Commands: R => reveal square, F => set flag, C => cheat, N => New Game" << std::endl;
ใใใใbool selected = false;
ใใใใwhile(!selected) {
ใใใใใใใใchar choice;
ใใใใใใใใstd::cin >> choice;
ใใใใใใใใif(choice == 'R' || choice == 'r') {
ใใใใใใใใใใใใuncover();
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else if(choice == 'F' || choice == 'f') {
ใใใใใใใใใใใใsetFlag();
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else if(choice == 'C' || choice == 'c') {
ใใใใใใใใใใใใcheat();
ใใใใใใใใ} else if(choice == 'N' || choice == 'n') {
ใใใใใใใใใใใใinit();
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else {
ใใใใใใใใใใใใstd::cout << "Invalid Choice!" << std::endl;
ใใใใใใใใ}
ใใใใ}
}
void uncover() {
ใใใใbool selected = false;
ใใใใwhile(!selected) {
ใใใใใใใใint x;
ใใใใใใใใint y;
ใใใใใใใใstd::cout << "Input X (1 - " << (DIMX) << ")" << std::endl;
ใใใใใใใใstd::cin >> x;
ใใใใใใใใstd::cout << "Input Y (1 - " << (DIMY) << ")" << std::endl;
ใใใใใใใใstd::cin >> y;
ใใใใใใใใx--;
ใใใใใใใใy--;
ใใใใใใใใif(x >= 0 && x < DIMX && y >= 0 && y < DIMY) {
ใใใใใใใใใใใใreveal(x, y); // call recursive reveal algorithm
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else {
ใใใใใใใใใใใใstd::cout << "(X,Y) Values out of range!" << std::endl;
ใใใใใใใใ}
ใใใใ}
}
void setFlag() {
ใใใใbool selected = false;
ใใใใwhile(!selected) {
ใใใใใใใใint x;
ใใใใใใใใint y;
ใใใใใใใใstd::cout << "Input X (1 - " << (DIMX) << ")" << std::endl;
ใใใใใใใใstd::cin >> x;
ใใใใใใใใstd::cout << "Input Y (1 - " << (DIMY) << ")" << std::endl;
ใใใใใใใใstd::cin >> y;
ใใใใใใใใx--;
ใใใใใใใใy--;
ใใใใใใใใif(x >= 0 && x < DIMX && y >= 0 && y < DIMY) {
ใใใใใใใใใใใใdisplay[x][y] = FLAG;
ใใใใใใใใใใใใselected = true;
ใใใใใใใใ} else {
ใใใใใใใใใใใใstd::cout << "(X,Y) Values out of range!" << std::endl;
ใใใใใใใใ}
ใใใใ}
}
void cheat() {
ใใใใstd::cout << "Cheating is bad!" << std::endl;
ใใใใstd::cout << " ";
ใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใstd::cout << (x + 1) << " ";
ใใใใ}
ใใใใstd::cout << std::endl << "";
ใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใstd::cout << "";
ใใใใ}
ใใใใstd::cout << std::endl;
ใใใใfor(int y = 0; y < DIMY; y++) {
ใใใใใใใใstd::cout << (y + 1) << " ";
ใใใใใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใใใใใif(state[x][y] == MINE) {
ใใใใใใใใใใใใใใใใstd::cout << "@ ";
ใใใใใใใใใใใใ} else {
ใใใใใใใใใใใใใใใใif(state[x][y] == 0) {
ใใใใใใใใใใใใใใใใใใใใstd:: cout << " ";
ใใใใใใใใใใใใใใใใ} else {
ใใใใใใใใใใใใใใใใใใใใstd:: cout << state[x][y] << " ";
ใใใใใใใใใใใใใใใใ}
ใใใใใใใใใใใใ}
ใใใใใใใใ}
ใใใใใใใใstd::cout << std::endl;
ใใใใ}
}
void print() {
ใใใใstd::cout << " ";
ใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใstd::cout << (x + 1) << " ";
ใใใใ}
ใใใใstd::cout << std::endl << "";
ใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใstd::cout << "";
ใใใใ}
ใใใใstd::cout << std::endl;
ใใใใfor(int y = 0; y < DIMY; y++) {
ใใใใใใใใstd::cout << (y + 1) << " ";
ใใใใใใใใfor(int x = 0; x < DIMX; x++) {
ใใใใใใใใใใใใif(display[x][y] == COVERED || display[x][y] == 'F') { // is it tile still uncovered
ใใใใใใใใใใใใใใใใstd::cout << display[x][y] << " ";
ใใใใใใใใใใใใ} else { // display the state
ใใใใใใใใใใใใใใใใif(state[x][y] == MINE) {
ใใใใใใใใใใใใใใใใใใใใstd::cout << "@ ";
ใใใใใใใใใใใใใใใใ} else {
ใใใใใใใใใใใใใใใใใใใใif(state[x][y] == 0) {
ใใใใใใใใใใใใใใใใใใใใใใใใstd:: cout << " ";
ใใใใใใใใใใใใใใใใใใใใ} else {
ใใใใใใใใใใใใใใใใใใใใใใใใstd:: cout << state[x][y] << " ";
ใใใใใใใใใใใใใใใใใใใใ}
ใใใใใใใใใใใใใใใใ}
ใใใใใใใใใใใใ}
ใใใใใใใใ}
ใใใใใใใใstd::cout << std::endl;
ใใใใ}
}
Sample Output: