Structure of the Problem Requirements
In this project we will implement the code of minesweeper game in C++. Minesweeper is deceptively simple test of memory and reasoning. This project cover all the basic of minesweeper games modules and at the end save the result of each player in a file . Here is the complete source code of this project which help you in better understanding.
Source Code
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <vector>
#include <limits>
#include <iomanip>
#include <fstream>
using namespace std;
void main_menu();
void set_level();
int choose_level();
void show_score();
void show_board(vector<vector <int> >&, bool show_mies = false);
void goto_xy(int, int);
void save_score(const int&);
void save_score(const int&);
void set_boards(vector <vector <int> >&);
void set_mines(vector<vector <int> >&, const int&);
int get_input (string, const int, const int lower_limit = 0);
/**
Struct For Make Limits Of Curcor In Console...!!
left_x_limit, right_x_limit They Specify The x Co-ordinates Of The Console Between Which Cursor Can Move. Horizontally..!!
up_y_limit, down_y_limit They Specify The y Co-ordinates Of The Console Between Which Cursor Can Move Vertically...!!
*/
struct ConsoleLimits
{
int left_x_limit,
right_x_limit,
up_y_limit,
down_y_limit;
} console_limits;
/**
This Struct Is For Different Type Of Data Used In The Game...!!
1. no_of_row No. Of Rows Of The Board Display On The Screen....!!!
2. no_of_cols No. Of Columns Of The Board Display On The Screen....!!!
3. no_of_mines No. Of Mines That Will Set On The Board...!!
4. x_pos The x Co-Ordinate Of Cusor On Console...!!
5. y_pos The y Co-Ordinate Of Cusor On Console...!!
*/
struct GameData
{
int no_of_rows,
no_of_cols,
no_of_mines,
x_pos,
y_pos;
static const int mine_symbol = 0;
} game_date;
int main()
{
system("COLOR 1F");
SetConsoleTitle("Mine Sweeper Game..!!"); // Change Title Of The Console...!!
typedef vector < vector <int > > Board; // Define Own Type Of 2-D Vector...!!
do
{
// Playing Main Backgroung Music For The Game...!!
// PlaySound(TEXT("BackGround Music!_1.wav"), NULL, SND_FILENAME | SND_LOOP | SND_ASYNC);
// Calling Main Menu...!!
main_menu();
// Play Game Sound...!!
// PlaySound(TEXT("BackGround Music!.wav"), NULL, SND_FILENAME | SND_LOOP | SND_ASYNC);
// Ask From User To Slect Level...!!
set_level();
// The No Of Place That Has No Mines i.e., Opened...!!
int no_of_unmines = (game_date.no_of_rows * game_date.no_of_cols) - game_date.no_of_mines;
int row_pos = 0, // Row Postion Of Board On Which Cusor Is Currently Is....!!!
col_pos = 0, // Column Postion Of Board On Which Cusor Is Currently Is....!!!
score = 0; // Score Made By User...!!
char ch; // Charecter Entered By User....!! Valid Are (A, S, D, W, a, s, d, w)...!!
bool game_over = false; // If User Hit The Mine, Then It Will Be True...!!!
// Make A Board For Playing Game...!!
Board board(game_date.no_of_rows, vector <int > (game_date.no_of_cols));
// Set Board With Random Numbers [1, 9]
set_boards(board);
// Set Mines On Board...!!!
set_mines(board, game_date.no_of_mines);
show_board(board);
game_date.x_pos = console_limits.left_x_limit - 1;
game_date.y_pos = console_limits.up_y_limit - 1;
goto_xy(game_date.x_pos, game_date.y_pos);
while (!game_over && score < no_of_unmines)
{
goto_xy(15, console_limits.down_y_limit + 3);
cout <<setw(15) << "Row Position" << setw(15) << "Col Position\n";
goto_xy(15, console_limits.down_y_limit + 4);
cout << setw(10) << row_pos << setw(13) << col_pos << endl;
goto_xy(25, console_limits.down_y_limit + 6);
cout << "Score: " << score;
goto_xy(game_date.x_pos, game_date.y_pos);
ch = _getch();
switch (toupper(ch))
{
case 'D':
{
if (game_date.x_pos < console_limits.right_x_limit)
{
game_date.x_pos += 2;
col_pos++;
}
}
break;
case 'A':
{
if (game_date.x_pos > console_limits.left_x_limit)
{
game_date.x_pos -= 2;
col_pos--;
}
}
break;
case 'W':
{
if(game_date.y_pos > console_limits.up_y_limit)
{
game_date.y_pos -= 2;
row_pos--;
}
}
break;
case 'S':
{
if (game_date.y_pos < console_limits.down_y_limit)
{
game_date.y_pos += 2;
row_pos++;
}
}
break;
case '\r':
{
if (board[row_pos][col_pos] == 0)
{
// PlaySound(TEXT("Explosion Sound Effects.wav"), NULL, SND_FILENAME | SND_ASYNC);
game_over = true;
}
else if (board[row_pos][col_pos] != -1)
{
cout << board[row_pos][col_pos];
board[row_pos][col_pos] = -1;
score++;
}
}
break;
goto_xy(game_date.x_pos, game_date.y_pos);
}
// End Of (toupper(ch))...!!
}
// End Of (!game_over && score < no_of_unmines)...!!!
game_date.x_pos = 10, game_date.y_pos = 10;
system("CLS");
goto_xy(game_date.x_pos, game_date.y_pos);
if (!game_over && score == no_of_unmines)
{
show_board(board, true);
goto_xy(game_date.x_pos, game_date.y_pos + 3);
cout << "YOU WIN\n";
goto_xy(game_date.x_pos, game_date.y_pos + 4);
cout << "YOU SELECT ALL THE BOX THAT ARE NOT A MINE\n";
goto_xy(game_date.x_pos, game_date.y_pos + 5);
}
// End Of (!game_over && score == no_of_unmines)...!!
else if (score < no_of_unmines)
{
show_board(board, true);
goto_xy(game_date.x_pos, game_date.y_pos + 1);
cout << "GAME OVER...!!\n\n";
goto_xy(game_date.x_pos, game_date.y_pos + 2);
cout << "YOU LOSE...!!YOU HIT A MINE\n";
goto_xy(game_date.x_pos, game_date.y_pos + 3);
}
// End Of if (score < no_of_unmines)...!!
goto_xy(game_date.x_pos, game_date.y_pos + 1);
cout << "YOUR SCORE IS: " << score;
goto_xy(game_date.x_pos, game_date.y_pos + 4);
save_score(score);
system("PAUSE");
}
while (true);
return 0;
}
// End Of main()
/**
Set Mines On The Board upto num_of_mines...!!
@Preconditions
1--> 0 < num_of_mines < (rows * col) Of board...!!
@param board A 2-D int Vector On Which Mines Will Be Placed...!!
@param num_of_mies Number Of Mines That Will Be Set Up On board...!!
*/
void set_mines(vector<vector <int> >& board, const int& num_of_mines)
{
srand(time(0));
int total_rows = board.size(),
total_cols = board[0].size(),
row_location,
col_location;
for (int mine = 0; mine < num_of_mines; mine++)
{
row_location = rand () % total_rows;
col_location = rand() % total_cols;
if (board[row_location][col_location] != game_date.mine_symbol)
{
board[row_location][col_location] = game_date.mine_symbol;
}
else
mine--;
}
} // end set_mines...!!
// eNd oF void set_mines(vector<vector <int> >& board, const int& num_of_mines)
/**
Set Each Index Of Board With A Random Numbers B/W 1 AND 8 Inclusive....!!!
Preconditions:
1 --> board Size Must Be Greater Then Zero...!!
@param board A 2-D int Vecotor On Which Random Numbers Will Be Setting Up...!!
*/
void set_boards(vector <vector <int> >& board)
{
srand (time(0));
int rows = board.size(),
cols = board[0].size();
for (int row_pos = 0; row_pos < rows; row_pos++)
{
for (int col_pos = 0; col_pos < cols; col_pos++)
{
board[row_pos][col_pos] = 1 + rand() % 9;
}
}
} // end of set_board
// eND oF void set_boards(vector <vector <int> >& board)
void show_board(vector <vector <int> >& board, bool show_mines)
{
char ch = 178;
game_date.x_pos = 10;
game_date.y_pos = 3;
for (int row_pos = 0; row_pos < game_date.no_of_rows; row_pos++)
{
goto_xy(game_date.x_pos, game_date.y_pos);
for (int col_pos = 0; col_pos < game_date.no_of_cols; col_pos++)
{
if (show_mines)
{
board[row_pos][col_pos] == 0 ? cout << board[row_pos][col_pos] << " " : cout << ch << " ";
}
else
cout << ch << " ";
}
game_date.y_pos += 2;
}
}
// eNd oF void show_board()
void goto_xy(int x_pos, int y_pos)
{
COORD coord;
coord.X = x_pos;
coord.Y = y_pos;
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(h_console, coord);
}
// eND oF void goto_xy(int x_pos, int y_pos)
/**
Retrun An Integer With lower_limt < int <= upper_limit
@param str A String That Is To Be Displayed!! It Will Describes That For What Input Is Being Taking..!!
e.g., If str == "Rows", Then For Row Input Is Being Taking...!!
@param upper_limits Maximum Number User Can Enter...!!
@param lower_limt Minimum Number User Can Enter...!! By Default It Is Zero...!!
@return num An Integer With lower_limt < num <= upper_limit
*/
int get_input (string str, const int upper_limit, const int lower_limit)
{
int num;
do
{
cout << "\neNTER A nUMBER fOR " << str << " (" << (lower_limit + 1) << " " << upper_limit << ") ";
cin >> num;
if (num <= lower_limit && !cin.fail())
{
MessageBox(NULL, "iNPUT mUST bE pOSITIVE.!!\n", "eRROR..!!", MB_OK | MB_ICONERROR);
}
if (num > upper_limit && !cin.fail())
{
MessageBox(NULL, "iNPUT mUST bE iN LIMITS.!!\ntRY aGain!!", "eRROR!", MB_OK | MB_ICONERROR);
}
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
MessageBox(NULL, "iNPUT mUST bE aN iNTEGER..!!", "eRROR..!!", MB_OK | MB_ICONERROR);
}
}
while ((num <= lower_limit || num > upper_limit) && !cin.fail());
system("CLS");
return num;
}
// eND oF int get_input (string str, const int upper_limit, const int lower_limit)
int choose_level()
{
SetConsoleTitle("MINE SPEEPRER GAME -> CHOSE LEVEL..!!!");
cout << "\n\n\n\n\n\n\n\t\t|--------------------------------------------------------------------|\n"
<< "\t\t| pRESS 1 fOR LEVEL 1 (eASY mODE) |\n\n"
<< "\t\t| pRESS 2 fOR LEVEL 2 (mEDUM mODE) |\n\n"
<< "\t\t| pRESS 1 fOR LEVEL 3 (hARD mODE) |\n\n"
<< "\t\t|--------------------------------------------------------------------|\n";
int level = get_input("Level", 3);
return level;
}
// eND oF int choose_level()
void set_level()
{
int level = choose_level();
SetConsoleTitle("Mine Sweeper Game -> Chooce Level...!!");
switch (level)
{
case 1:
{
game_date.no_of_rows = 12;
game_date.no_of_cols = 15;
game_date.no_of_mines = 75;
SetConsoleTitle("MINE SWEEPER GAME -> EASY MODE....!!!");
system("MODE 50, 40");
}
break;
// End Of Case 1...!!!
case 2:
{
game_date.no_of_rows = 17;
game_date.no_of_cols = 20;
game_date.no_of_mines = 100;
SetConsoleTitle("MINE SWEEPER GAME -> MEDIUM MODE....!!!");
system("MODE 60, 50");
}
break;
// End Of Case 2...!!!
case 3:
{
game_date.no_of_rows = 22;
game_date.no_of_cols = 25;
game_date.no_of_mines = 200;
SetConsoleTitle("MINE SWEEPER GAME -> HARD MODE....!!!");
system("MODE 77, 55");
}
break;
// End Of Case 3...!!!
}
game_date.x_pos = 10;
game_date.y_pos = 3;
console_limits.left_x_limit = game_date.x_pos + 1;
console_limits.right_x_limit = console_limits.left_x_limit + game_date.no_of_cols + game_date.no_of_rows;
console_limits.up_y_limit = game_date.y_pos + 1;
console_limits.down_y_limit = console_limits.right_x_limit - 13;
}
// eND oF void set_level()
void show_score()
{
ifstream file;
file.open("Scores!.txt");
string name;
int score;
char line_end;
cout << setw(50) << "nAME" << setw(10) << " sCORE\n";
while (getline(file, name) && file >> score)
{
cout << setw(50) << name << setw(10) << score << endl;
file.get(line_end);
}
file.close();
}
// eND oF void show_score()
void save_score(const int& score)
{
ofstream file;
file.open("Scores!.txt", ios::app);
string name;
cin.ignore();
do
{
cout << "\teNTER yOUR nAME\n>>> ";
getline(cin, name);
}
while (name.length() == 0);
file << name << endl << score << endl;
file.close();
MessageBox(NULL, "sCORE sAVED", "O.K.,", MB_OK | MB_ICONMASK);
}
// eND oF void save_score(const int& score)
/**
Main Menus Of The Game...!! Runs When Game Is Start....!!
*/
void main_menu()
{
string game = "WELCOME TO MINE SWEEPER GAME\n";
system("MODE 100, 40");
Sleep(250);
cout << "\n\n\n\n";
for (int ch = 0; ch < game.length(); ch++)
{
cout << game[ch] << " ";
Sleep(500);
}
// An Infinte Loop That Will Display Main Options Of The Game...!!
// This Will Return From Funtion If User Select Choice 2, Otherwise Always Display Main Options...!!
while(true)
{
system("CLS");
cout << "\n\n\n\n\n\t\t|-----------------------------------------------------------|\n\n";
cout << "\t\t| eNTER 1 fOR vIEW sCORE |\n\n";
cout << "\t\t| eNTER 2 fOR plAY gAME! |\n\n";
cout << "\t\t|-----------------------------------------------------------|\n";
int choice = get_input("cHOICE", 2);
if (choice == 1)
{
show_score();
system("PAUSE");
}
else
return;
}
}
Outut of the Program
Minesweeper Game in C++ |
Minesweeper Game in C++ |
Minesweeper Game in C++ |
Asad Niazi is Software Engineer , Programmer, Web Developers and a young mentor of Tech Solutions Desk and Blogging Solutions . Asad Love to writes about Technology, Programming, Blogging and make money online.
0 comments:
Post a Comment