I'm a high school student and, as a homework, i have to develop a console (MS-DOS) version of Minesweeper. For the grid where the game is played, I used a two-dimensional array and I'm stuck on the function which puts the mines (which i represent with -2) in random boxes and determines how many mines are adjacent to every box. This last part is giving me some trouble, because it takes about 2 minutes from start to finish for the "hard" mode of the game (32x18 array with 99 mines). Here is the function I have written:
void InsMine(int mat[32][18]){
int i, r, c, j, k, contatore;
for(i=0;i<n_mine;i++){
do{
srand(time(NULL));
r=minimo + rand() % massimo-1;
c=minimo + rand() % massimo_c-1;
}
while(mat[r][c]==-2||mat[r][c]==-1);
mat[r][c]=-2;
}
for(j=1;j<=massimo;j++){ //for che scorre la matrice (colonne)
for(k=1;k<=massimo_c;k++){ //for che scorre la matrice (righe)
contatore=0;
if(mat[j][k]!=-2){
if(mat[j-1][k]==-2){
contatore++;
}
if(mat[j-1][k+1]==-2){
contatore++;
}
if(mat[j][k+1]==-2){
contatore++;
}
if(mat[j+1][k+1]==-2){
contatore++;
}
if(mat[j+1][k]==-2){
contatore++;
}
if(mat[j+1][k-1]==-2){
contatore++;
}
if(mat[j+1][k-1]==-2){
contatore++;
}
if(mat[j-1][k-1]==-2){
contatore++;
}
mat[j][k]=contatore;
}
}
}
}
The first for places the mines in random squares, while the second for determines how many mines are adjacent to a given box and saves the value in that box. The code is written in Italian, so here's a little translation: "massimo" means maximum, "minimo" is minimum and "contatore" is counter and I use it to count how many mines are adjacent to a given square. If you could help me to understand how to optimize better this part I'd be very grateful, as I really can't wrap my head around it.
Here is every piece of code I've written so far:
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
using namespace std;
int righe_mat, colonne_mat, n_mine, minimo, massimo, massimo_c;
void InsMine(int mat[32][18]);
void RiempiMat(int mat[32][18]);
void StampaMat(int mat[32][18]);
int main()
{
int scelta;
int PosNum[32][18], Scoperte[32][18];
do{ //scelta difficoltà da parte dell'utente
cout << "Scegliere il livello di difficolta' (1=facile, 2=medio, 3=difficile): ";
cin >> scelta;
switch(scelta){ //modifica variabili globali in base alla difficoltà scelta
case 1:
righe_mat=11;
colonne_mat=11;
n_mine=10;
minimo=1;
massimo=9;
massimo_c=9;
break;
case 2:
righe_mat=18;
colonne_mat=18;
n_mine=40;
minimo=1;
massimo=16;
massimo_c=16;
break;
case 3:
righe_mat=32;
colonne_mat=18;
n_mine=99;
minimo=1;
massimo=30;
massimo_c=16;
break;
default:
cout << "Scelta non valida, ripetere selezione" << endl;
}
}
while(scelta!=1&&scelta!=2&&scelta!=3);
RiempiMat(PosNum);
RiempiMat(Scoperte);
InsMine(PosNum);
cout << endl << endl;
StampaMat(PosNum);
}
void RiempiMat(int mat[32][18]){
int i, j, k, o, m, n;
for(i=0;i<colonne_mat;i++){
mat[0][i]=-1;
}
for(j=0;j<colonne_mat;j++){
mat[righe_mat-1][j]=-1;
}
for(k=0;k<righe_mat;k++){
mat[k][0]=-1;
}
for(o=0;o<righe_mat;o++){
mat[o][colonne_mat-1]=-1;
}
for(m=1;m<colonne_mat-1;m++){
for(n=1;n<righe_mat-1;n++){
mat[n][m]=0;
}
}
}
void InsMine(int mat[32][18]){
int i, r, c, j, k, contatore;
for(i=0;i<n_mine;i++){
do{
srand(time(NULL));
r=minimo + rand() % massimo-1;
c=minimo + rand() % massimo_c-1;
}
while(mat[r][c]==-2||mat[r][c]==-1);
mat[r][c]=-2;
}
for(j=1;j<=massimo;j++){ //for che scorre la matrice (colonne)
for(k=1;k<=massimo_c;k++){ //for che scorre la matrice (righe)
contatore=0;
if(mat[j][k]!=-2){
if(mat[j-1][k]==-2){
contatore++;
}
if(mat[j-1][k+1]==-2){
contatore++;
}
if(mat[j][k+1]==-2){
contatore++;
}
if(mat[j+1][k+1]==-2){
contatore++;
}
if(mat[j+1][k]==-2){
contatore++;
}
if(mat[j+1][k-1]==-2){
contatore++;
}
if(mat[j+1][k-1]==-2){
contatore++;
}
if(mat[j-1][k-1]==-2){
contatore++;
}
mat[j][k]=contatore;
}
}
}
}
void StampaMat(int mat[32][18]){
int i, j;
for(i=0;i<colonne_mat;i++){
for(j=0;j<righe_mat;j++){
cout << mat[j][i] << " |";
}
cout << endl;
}
cout << endl << endl << endl;
}
The cout in main is basically asking to choose the difficulty of the game (1=easy, 9x9 array and 10 mines, 2=medium, 18x18 array and 40 mines, 3=hard, 32x18 array and 99 mines). I use the switch to set the value of some global variables: righe_mat and colonne_mat represent the size of the array (x;y), n_mine represents the number of mines and massimo and minimo are used to set the range in which the mines can be placed. The function RiempiMat() fills both the arrays (1 used to save where the mines are and how many of them are adjacent to each box and 1 used to save which square the user sees and which the user doesn't see yet) with 0s and -1s (the border) and StampaMat() just prints both the arrays.
I apologise for my English, as I'm Italian and English is not my first language. Thanks in advance for the kind help, Matteo