Witam,
na studiach mam do wykonania projekt z programowania obiektowego - grę saper. Napisałem już część kodu, lecz nie umiem poradzić sobie z odkrywaniem odpowiednich pól po wprowadzeniu koordynat.
Funkcją discover(int a, int b)
próbuję przepisywać do tablicy odkrytych pól odpowiednie wartości, ale przepisuje tylko jedną - tą wybraną :/
Kod:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
const char BOMB = '*';
const char FLAG = 'f';
const char DISCOVERED = ' ';
const char EMPTY = '0';
const char MAX = '9';
class Board {
public:
Board();
Board(int size_x, int size_y) : x(size_x), y(size_y) {
board = new char **[y];
for (int i = 0; i < y; i++) {
board[i] = new char *[x];
}
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
board[i][j] = new char;
*(board[i][j]) = '0';
}
}
discovered_board = new char **[y];
for (int i = 0; i < y; i++) {
discovered_board[i] = new char *[x];
}
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
discovered_board[i][j] = new char;
*(discovered_board[i][j]) = ' ';
}
}
}
void display_board() {
if (x > 10)cout << " ";
else cout << " ";
for (int i = 0; i < y; i++) {
if (i < 10) cout << " ";
cout << " " << i;
}
cout << endl;
for (int j = 0; j < x; j++) {
cout << " " << j;
if (j < 10 && x > 10) cout << " ";
for (int i = 0; i < y; i++) {
cout << " " << *(board[i][j]);
}
cout << endl;
}
}
void display_discovered_board() {
if (x > 10)cout << " ";
else cout << " ";
for (int i = 0; i < y; i++) {
if (i < 10) cout << " ";
cout << " " << i;
}
cout << endl;
for (int j = 0; j < x; j++) {
cout << " " << j;
if (j < 10 && x > 10) cout << " ";
for (int i = 0; i < y; i++) {
if (*(discovered_board[i][j]) != '*') {
cout << " " << *(discovered_board[i][j]);
} else cout << " " << " ";
}
cout << endl;
}
}
bool discover(int a, int b) {
for (int ychange : {-1, 0, 1}) {
int iy = b + ychange;
if (iy >= 0 && iy < b)
for (int xchange : {-1, 0, 1}) {
int ix = a + xchange;
if (ix >= 0 && ix < a)
if (board[iy][ix] != &BOMB && board[iy][ix] < &MAX){
discovered_board[ix][iy] = board[ix][iy];
discover(ix, iy);
return true;
}
}
}
}
void prep_gameboard(int x, int y) {
board[y][x] = (char *) &BOMB;
}
void bomb_counter() {
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
if (board[i][j] == &BOMB) {
for (int ychange : {-1, 0, 1}) {
int iy = i + ychange;
if (iy >= 0 && iy < y)
for (int xchange : {-1, 0, 1}) {
int ix = j + xchange;
if (ix >= 0 && ix < x)
if (board[iy][ix] != &BOMB)
(*(board[iy][ix]))++;
}
}
}
}
}
}
friend class Mines;
private:
char ***discovered_board;
char ***board;
int x, y;
};
class Mines{
public:
Mines(Board &var, int mines) : mines(mines) {
int x, y;
arr_x_pos = new int[mines];
arr_y_pos = new int[mines];
for(int i = 0; i < mines; i++){
do {
x = rand() % var.x;
y = rand() % var.y;
}while(existance(x, y));
arr_x_pos[i] = x;
arr_y_pos[i] = y;
}
}
bool existance(int x, int y){
for(int i = 0; i < mines; i++){
if(x == arr_x_pos[i] && y == arr_y_pos[i]) return true;
}
return false;
}
int get_x_pos(int i){
return arr_x_pos[i];
}
int get_y_pos(int i){
return arr_y_pos[i];
}
virtual int mines_amount(int board_size) = 0;
friend class Board;
private:
int *arr_x_pos;
int *arr_y_pos;
int mines;
};
class LevelEasy : public Mines{
public:
LevelEasy(Board &var, int board_size) : Mines::Mines(var, mines_amount(board_size)){
};
int mines_amount(int board_size) override {
return (int) board_size * 0.05;
}
};
class LevelMedium : public Mines{
public:
LevelMedium(Board &var, int board_size) : Mines::Mines(var, mines_amount(board_size)){
};
int mines_amount(int board_size) override {
return (int) board_size * 0.1;
}
};
class LevelHard : public Mines{
public:
LevelHard(Board &var, int board_size) : Mines::Mines(var, mines_amount(board_size)){
};
int mines_amount(int board_size) override {
return (int) board_size * 0.15;
}
};
class LevelExtreme : public Mines{
public:
LevelExtreme(Board &var, int board_size) : Mines::Mines(var, mines_amount(board_size)){
};
int mines_amount(int board_size) override {
return (int) board_size * 0.2;
}
};
int main() {
int x, y;
cout << "Hello! This is simple minesweeper game writen in C++ with classes." << endl;
cout << "Please type dimensions of your game first horizontal [from 1 to 99], next vertical [from 1 to 99] <Maximal dimensions depends on your screen resolution>" << endl;
cin >> y >> x;
while(x < 1 || x > 99 || y < 1 || y > 99){
cout << "You've given wrong parameters, please, change them" << endl;
cin >> y >> x;
}
cout << "Your minesweeper game will have " << x << " units height and " << y << " units width" << endl;
Board gameboard(x, y);
cout << "Now, please type in number of difficulty level you want to play:" << endl << "1.Easy [5% of playground filled with bombs]" << endl << "2.Medium [10% of playground filled with bombs" << endl << "3.Hard [15% of playground filled with bombs]" << endl << "4.Extreme [20% of playground filled with bombs]" << endl;
int task;
cin >> task;
while(task > 4 || task < 1){
cout << "You picked wrong difficulty level" << endl;
cin >> task;
}
Mines* mines;
switch(task) {
case 1:
mines = new LevelEasy(gameboard, x*y);
break;
case 2:
mines = new LevelMedium(gameboard, x*y);
break;
case 3:
mines = new LevelHard(gameboard, x*y);
break;
case 4:
mines = new LevelExtreme(gameboard, x*y);
break;
default:
cout << "You did not pick any difficulty level" << endl;
break;
}
int diff = mines->mines_amount(x*y);
cout << "You'll have " << diff << " bombs randomly placed on the playground" << endl;
for(int i = 0; i < diff; i++){
gameboard.prep_gameboard(mines->get_x_pos(i), mines->get_y_pos(i));
}
gameboard.bomb_counter();
cout << endl;
gameboard.display_board();
cout << endl;
bool win = true;
int a, b;
// do {
cin >> a >> b;
gameboard.discover(a,b);
gameboard.display_discovered_board();
// }while(win);
return 0;
}