Mistake in the source code, no error, game.

Pages: 12
Hello. I am writing a small minesweeper-like game. Currently it doesent has "hints" in forms of numbers appearing, yet. Before doing this i need to fix a problem.
When i compile, without errors, whatever number i type in, it seems to not register it, it just keeps all fields as "F" as if nobody interacted with it.
Program has 2 arrays, one for display (array1) and one for mines/empty (array_mine).
I would be very gratefull if someone explained me where does the problem lays.
Here is the source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

char array1[26]{'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'}; // a 5x5 array.
int array_mine[26];

int mine_number;
int input;
int a = 0;
int b = 0;
int c = 0;
bool endgame;
bool boom;
void check();

void random()
{
 while(a <= 26)
 {
 srand(time(NULL));
 array_mine[a] = rand() % 2;
 a++;
 };
return;
}
void check()
{
while(b <= 26)
{
if(array1[b] == input)
    {
    switch(array_mine[b])
        {
    case 0:
        array1[1] = 'E';
        array_mine[b] = 3;
        break;
    case 1:
        array1[b] = 'M';
        endgame = true;
        boom = true;
        break;
        }
    }
    b++;
}
return;
}


int main()
{
 cout << "Welcome to Minesweeper."   ;
 cout << "The minefield is 5 x 5";
 cout << "F is a unknown field, E is cleared field.";
 cout << "Detect area by inserting number of field, counting left-right, top-down.";
 cout << "Ammount of mines as well as their allocation is random. It means it is possible to have 0 mines or 25 (maximum) mines. In latter case im terribly sorry if it happens.";
 cout << endl;
 cout << endl;
 while(endgame == false)
 {
 cout << array1[1] << array1[2] << array1[3] << array1[4] << array1[5] << endl;
 cout << array1[6] << array1[7] << array1[8] << array1[9] << array1[10] << endl;
 cout << array1[11] << array1[12] << array1[13] << array1[14] << array1[15] << endl;
 cout << array1[16] << array1[17] << array1[18] << array1[19] << array1[20] << endl;
 cout << array1[21] << array1[22] << array1[23] << array1[24] << array1[25] << endl;
 cin >> input;
 check();
 while (c <= 26)
 {
     if(array_mine[c] == 3 or array_mine[c] == 1)
     {
         endgame = true;
     }
     c++;
 }
}
if(boom == true)
{
    cout << "BOOM! You blew yourself up! Better luck next time :)";
}
cout << "Congratulations! You cleared the minefield!";
return 0;
}

The output is more or less (Yes, i know i forgot \n's to make things readable.):

Welcome to Minesweeper.The minefield is 5 x 5F is a unknown field, E is cleared
field.Detect area by inserting number of field, counting left-right, top-down.Am
mount of mines as well as their allocation is random. It means it is possible to
 have 0 mines or 25 (maximum) mines. In latter case im terribly sorry if it happ
ens.

FFFFF
FFFFF
FFFFF
FFFFF
FFFFF
Here you are comparing a char with an int.
It would make more sense if both were char , or both int.
if(array1[b] == input)

But since I know the ASCII code for the letter 'F' is 70, I entered 70 as the input value, and got this:
Welcome to Minesweeper.The minefield is 5 x 5F is a unknown field, E is cleared field.Detect area by inserting
 number of field, counting left-right, top-down.Ammount of mines as well as their allocation is random. It mea
ns it is possible to have 0 mines or 25 (maximum) mines. In latter case im terribly sorry if it happens.

FFFFF
FFFFF
FFFFF
FFFFF
FFFFF
70
Congratulations! You cleared the minefield!

Last edited on
Well its not that i want to compare whatever sits in cell "b" from array[b].
I want to compare the int input with number of cell
AKA
input == array[---->THIS I WANT TO COMPARE INPUT TO<-----]
Last edited on
char array1[26]{'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'}; // a 5x5 array.
Last edited on
I haven't studied the logic fully, but maybe instead of this:
if(array1[b] == input)

you should have this:
if (b == input)
Yes, it fixes it, cant believe i didnt thought about it :p.
The another problem is specified by you above. It immideatly wins. I wil try to study my code's logic and seek fix, but still i would enjoy help.
Anyone sees more logical problems ? I can't get it to auto-win when you select empty field.


EDIT:
Updated code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

char array1[26]{'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'}; // a 5x5 array.
int array_mine[26];
int mine_number;
int input;
int a = 0;
int b = 0;
int c = 0;
int d = 0;
bool endgame = false;
bool boom = false;
void check();

void random()
{
 while(a < 26)
 {
 srand(time(NULL));
 array_mine[a] = rand() % 2;
 a++;
 };
return;
}

void check()
{
while(b < 26)
{
if(b == input)
    {
    switch(array_mine[b])
        {
    case 0:
        array1[b] = 'E';
        array_mine[b] = 3;
        break;
    case 1:
        array1[b] = 'M';
        boom = true;
        break;
    default:
        array1[b] = 'W';
        break;
        }
    }
    b++;
}
b = 0;
return;
}


int main()
{
 cout << "Welcome to Minesweeper."   ;
 cout << "The minefield is 5 x 5";
 cout << "F is a unknown field, E is cleared field.";
 cout << "Detect area by inserting number of field, counting left-right, top-down.";
 cout << "Ammount of mines as well as their allocation is random. It means it is possible to have 0 mines or 25 (maximum) mines. In latter case im terribly sorry if it happens.";
 cout << endl;
 cout << endl;
 random();
 while(boom == false or endgame == false)
 {
 cout << array1[1] << array1[2] << array1[3] << array1[4] << array1[5] << endl;
 cout << array1[6] << array1[7] << array1[8] << array1[9] << array1[10] << endl;
 cout << array1[11] << array1[12] << array1[13] << array1[14] << array1[15] << endl;
 cout << array1[16] << array1[17] << array1[18] << array1[19] << array1[20] << endl;
 cout << array1[21] << array1[22] << array1[23] << array1[24] << array1[25] << endl;
 cin >> input;
 check();
 if(array1[1] != 'F' && array1[2] != 'F' && array1[3] != 'F' && array1[4] != 'F' && array1[5] != 'F' && array1[6] != 'F' && array1[7] != 'F' && array1[8] != 'F' && array1[9] != 'F' && array1[10] != 'F' && array1[11] != 'F' && array1[12] != 'F' && array1[13] != 'F' && array1[14] != 'F' && array1[15] != 'F' && array1[16] != 'F' && array1[17] != 'F' && array1[18] != 'F' && array1[19] != 'F' && array1[20] != 'F' && array1[21] != 'F' && array1[22] != 'F' && array1[23] != 'F' && array1[24] != 'F' && array1[25] != 'F')
 {
    endgame = true;
 }
     d++;
 }

if(boom == true)
{
    cout << "BOOM! You blew yourself up! Better luck next time :)";
    return 0;
}
cout << "Congratulations! You cleared the minefield!";
return 0;
}
Last edited on
A few comments.

1) You should minimize your use of globals. This is from a global (and goto) hater. :) Variables should be as local as possible. Using globals makes it difficult in a large program to keep track of where they're being used/modified. For example, lines 20-24, a should be local to random. There is no reason for it to be global.
What if you decide to add a replay feature to your game and call random again? a would no longer be initialized to zero.

2) Line 20. A for loop is a more common idiom where the number of iterations is known in advance. Your while loop does work, whith the caveat I mentioned in #1.
The advantage of the for loop is that it specifies both the initialization and termination condition of the loop variable.

3) Line 76. This is a perfect candidate for a loop. Actually, I would suggest make this a function.

4) Line 67: This is a syntax error. You can't use 'or'. A logical or condition should be expressed as (cond1) || (cond2), although I think you want an && condition here. You want to continue the game as long as the player has not gone boom AND every cell is not an 'F'.

5) Line 6. Syntax error. You're missing an equal sign.
char array1[26] = {'F', ...

6) Again a for loop is a better choice here. Also, b should be local to check. There is no reason for it to be global. You should declare and initialize it at line 30. Resetting global b to 0 and the end of the function is a poor practice. You're assuming no other code modifies b before you come back into the function.






Concerning point 4 -
No, i want that IF player lost or if he WON either way show him current situation, then the boom == true checking stuff happens, which decides whenever he won or not.

I fixed all errors you pointed out, but still, whenever i slect a point in the game, everything shows as 'M' a mine.


FFFFF
FFFFF
FFFFF
FFFFF


MFFFF
FFFFF
FFFFF
FFFFF
FFFFF

MMFFF
FFFFF
FFFFF
FFFFF
FFFFF


And on, and on.
I fixed all errors you pointed out

If you fixed the errors I pointed out, they're not reflected in your edited code.
You still have syntax errors in your edited code.

Line 6. Syntax error. You're missing an equal sign. My previous #5.
char array1[26] = {'F', ...

4) Line 67: Syntax error. There is no 'or' operator in C++. An or condition should be expressed as ((cond1) || (cond2)) note the two vertical bars (||). My previous #4.

New problems that I see:
Line 22. You're reseeding the random number generator each time through the loop.
You'll get exactly the same random number each time you call rand(). Call srand() once at the beginning of your program. Move it to line 58.

Line 67. You still have a problem with your while loop. Lets say first time through the loop you pick a cell with a mine. boom gets set to true by check. endgame will be false, so you continue with the next iteration of the loop (one of the two was false satisfying your or condition). Aren't you supposed to go boom when you pick a cell that has a mine? In fact you will continue until you've cleared all 25 cells. Only when both endgame and boom are true, do you fall through the loop and detect that boom was true and tell the user they blew themselves up. As I said before, you want an AND (&&) condition. As soon as either either boom or endgame is true, the AND condition will be false and you want to fall through.





Im sorry, forgot to attach editet code :
It now works, it just wont detect when user went onto mine, guess i can fix that myself, but other people fixes are welcome :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

char array1[26] = {'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'}; // a 5x5 array.
int array_mine[26];
int mine_number;
int input;
int a = 0;
int b = 0;
int c = 0;
int d = 0;
bool endgame = false;
bool boom = false;
void check();

void random()
{
 while(a < 26)
 {
 array_mine[a] = rand() % 2;
 a++;
 };
return;
}

void check()
{
while(b < 26)
{
if(b == input)
    {
    switch(array_mine[b])
        {
    case 0:
        array1[b] = 'E';
        array_mine[b] = 3;
        break;
    case 1:
        array1[b] = 'M';
        boom = true;
        break;
    default:
        array1[b] = 'W';
        break;
        }
    }
    b++;
}
b = 0;
return;
}


int main()
{
 srand(time(NULL));
 cout << "Welcome to Minesweeper."   ;
 cout << "The minefield is 5 x 5";
 cout << "F is a unknown field, E is cleared field.";
 cout << "Detect area by inserting number of field, counting left-right, top-down.";
 cout << "Ammount of mines as well as their allocation is random. It means it is possible to have 0 mines or 25 (maximum) mines. In latter case im terribly sorry if it happens.";
 cout << endl;
 cout << endl;
 random();
 while(boom == false || endgame == false)
 {
 cout << array1[1] << array1[2] << array1[3] << array1[4] << array1[5] << endl;
 cout << array1[6] << array1[7] << array1[8] << array1[9] << array1[10] << endl;
 cout << array1[11] << array1[12] << array1[13] << array1[14] << array1[15] << endl;
 cout << array1[16] << array1[17] << array1[18] << array1[19] << array1[20] << endl;
 cout << array1[21] << array1[22] << array1[23] << array1[24] << array1[25] << endl;
 cin >> input;
 check();
 if(array1[1] != 'F' && array1[2] != 'F' && array1[3] != 'F' && array1[4] != 'F' && array1[5] != 'F' && array1[6] != 'F' && array1[7] != 'F' && array1[8] != 'F' && array1[9] != 'F' && array1[10] != 'F' && array1[11] != 'F' && array1[12] != 'F' && array1[13] != 'F' && array1[14] != 'F' && array1[15] != 'F' && array1[16] != 'F' && array1[17] != 'F' && array1[18] != 'F' && array1[19] != 'F' && array1[20] != 'F' && array1[21] != 'F' && array1[22] != 'F' && array1[23] != 'F' && array1[24] != 'F' && array1[25] != 'F')
 {
    endgame = true;
 }
     d++;
 }

if(boom == true)
{
    cout << "BOOM! You blew yourself up! Better luck next time :)";
    return 0;
}
cout << "Congratulations! You cleared the minefield!";
return 0;
}
it just wont detect when user went onto mine

For exactly the reason I've pointed out twice already.

Move lines 83-87 to after line 75.
Why does 5*5 = 26?

it just wont detect when user went onto mine

For exactly the reason I've pointed out twice already.

Move lines 83-87 to after line 75.


Thank you, it works now :-).

Now the other thing i will have to work trough, is change of the code so the program actuall tells the player how many mines are there in vicinity.
Alright, i have came up with algorithm that checks which cell is inputted, and checks how many mines are around it, but program outputs huge number as ammount of mines. It is propably a simple mistake, but, ARRGH, i can't find this little bug. Would be much appreciated if someone helped.

Updated code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

char array1[26] = {'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'}; // a 5x5 array.
int array_mine[26];
int mine_number;
int input;
int a = 0;
int b = 0;
int c = 0;
int hint = 0;
bool endgame = false;
bool boom = false;
void check();

void random()
{
 while(a < 26)
 {
 array_mine[a] = rand() % 2;
 a++;
 };
return;
}

void check()
{
while(b < 26)
{
if(b == input)
    {
    switch(array_mine[b])
        {
    case 0:
        array1[b] = 'E';
        if(10 > b > 6 || 20 > b > 16 || 15 > b > 11)
        {
            hint = array_mine [b-6] + array_mine [b-5] + array_mine [b-4] + array_mine [b-1] + array_mine [b+1] + array_mine [b+4] + array_mine [b+5] + array_mine [b+6];
        }
        if(b == 1)
        {
            hint = array_mine [b];
        }
        if(5 > b > 1)
        {
            hint = array_mine [b-1] + array_mine [b+1] + array_mine [b+4] + array_mine [b+5] + array_mine [b+6];
        }
        if(b == 5)
        {
            hint = array_mine [b-1] + array_mine [b+4] + array_mine [b+5];
        }
        if(b == 6 || b == 11 || b == 16)
        {
            hint = array_mine [b-5] + array_mine [b-4] + array_mine [b+1] + array_mine [b+5] + array_mine [b+6];
        }
        if(b == 10 || b == 15 || b == 20)
        {
            hint = array_mine [b-6] + array_mine [b-5] + array_mine [b-1] + array_mine [b+4] + array_mine [b+5];
        }
        if(21 < b < 25)
        {
            hint = array_mine [b-6] + array_mine [b-5] + array_mine [b-4] + array_mine [b-1] + array_mine [b+1];
        }
        if(b == 25)
        {
            hint = array_mine [b-6] + array_mine [b-6] + array_mine [b-1];
        }
        if(b == 21)
        {
            hint = array_mine [b-5] + array_mine [b-4] + array_mine [b+1];
        }
        break;
    case 1:
        array1[b] = 'M';
        boom = true;
        break;
    default:
        break;
        }
    }
    b++;
}
b = 0;
return;
}


int main()
{
 srand(time(NULL));
 cout << "Welcome to Minesweeper.\n"   ;
 cout << "The minefield is 5 x 5\n";
 cout << "F is a unknown field, E is cleared field.\n";
 cout << "This minesweeper is diffrent though.\n Yes, it will display how many mines are around tile you just uncovered after each move.\n But once you make another move, that hint is gone, place for new one.\n You need to memorize hints this programm gives to you.";
 cout << "Detect area by inserting number of field, counting left-right, top-down.\n";
 cout << "Ammount of mines as well as their allocation is random. It means it is possible to have 0 mines or 25 (maximum) mines.\n In latter case im terribly sorry if it happens.\n";
 cout << endl;
 cout << endl;
 random();
 while(boom == false || endgame == false)
 {
 cout << array1[1] << array1[2] << array1[3] << array1[4] << array1[5] << endl;
 cout << array1[6] << array1[7] << array1[8] << array1[9] << array1[10] << endl;
 cout << array1[11] << array1[12] << array1[13] << array1[14] << array1[15] << endl;
 cout << array1[16] << array1[17] << array1[18] << array1[19] << array1[20] << endl;
 cout << array1[21] << array1[22] << array1[23] << array1[24] << array1[25] << endl;
 cin >> input;
 check();

 if(boom == true)
{
    cout << "BOOM! You blew yourself up! Better luck next time :)";
    return 0;
}
 if(array1[1] != 'F' && array1[2] != 'F' && array1[3] != 'F' && array1[4] != 'F' && array1[5] != 'F' && array1[6] != 'F' && array1[7] != 'F' && array1[8] != 'F' && array1[9] != 'F' && array1[10] != 'F' && array1[11] != 'F' && array1[12] != 'F' && array1[13] != 'F' && array1[14] != 'F' && array1[15] != 'F' && array1[16] != 'F' && array1[17] != 'F' && array1[18] != 'F' && array1[19] != 'F' && array1[20] != 'F' && array1[21] != 'F' && array1[22] != 'F' && array1[23] != 'F' && array1[24] != 'F' && array1[25] != 'F')
 {
    endgame = true;
 }
 cout << "There is " << hint << " mines around this tile!\n";
 cin.ignore();
 }

cout << "Congratulations! You cleared the minefield!";
return 0;
}


Sample output:


Welcome to Minesweeper.
The minefield is 5 x 5
F is a unknown field, E is cleared field.
This minesweeper is diffrent though.
 Yes, it will display how many mines are around tile you just uncovered after ea
ch move.
 But once you make another move, that hint is gone, place for new one.
 You need to memorize hints this programm gives to you.Detect area by inserting
number of field, counting left-right, top-down.
Ammount of mines as well as their allocation is random. It means it is possible
to have 0 mines or 25 (maximum) mines.
 In latter case im terribly sorry if it happens.


FFFFF
FFFFF
FFFFF
FFFFF
FFFFF
1
There is 4214785 mines around this tile!
EFFFF
FFFFF
FFFFF
FFFFF
FFFFF
 
       if(10 > b > 6 || 20 > b > 16 || 15 > b > 11)

You can't write an if statement like that. Well you can, but it's not going to do what you think it's going to do. With a value of b equal to 1, it going to get evaluated as follows:
1
2
if((10 > b) > 6 || (20 > b) > 16 || (15 > b) > 11)
if(true > 6 || true > 16 || true > 11)

Comparing a bool to an int is not a type safe operation.

It's disappointing to see that you haven't taken the suggestions made in previous posts.



Last edited on
It's disappointing to see that you haven't taken the suggestions made in previous posts.


But... i did, i think i did all of them ?

Also i don't see how "1" equals true ?
Andi didn't set b as 1 ?
AKA I don't understand what you mean, could you explain ?
But... i did, i think i did all of them ?

From several posts back. 1) "You should minimize your use of globals".
I gave you an example why in random(), that a should be local.

#3 in the same post: Current line 117 "This is a perfect candidate for a loop. Actually, I would suggest make this a function." This line is too long. It blows out the margins on my browser. The line works, it just that there's just a much cleaner way to write it.
1
2
3
4
5
6
7
8
9
10
bool check_game_over ()
{ for (int i = 1; i<26; i))
    if (array1[i] != 'F')
      return false;  // game not over 
  return true;  // game over
}
[code]
Then replace line 117-126 with
[code]
  endgame = check_game_over();


#6 from the same post. I was referring to your check function. You make the assumption that b is initialized to 0 when entering the function. Poor practice to make that assumption. If b should be 0 at the toop of the loop, then you should explicity set it to 0 before entering the loop. Also per point #1, b should be a local variable.

I've pointed out before that your while condition at line 102 should be &&. At this point, you've moved your if (boom) logic inside the loop (as suggested) with an immediate exit so you no longer need to be checking boom in the while condition. Your while should now be just:
1
2
 
while (! endgame)


You never asnwered L B's question of why you're using arrays of 26 for a 5x5 grid. I can see that you're using [1]-[25] and that's okay except that you never range check the users input. If the user inputs 0 or a number > 25, you should give the user an error message and reprompt for input.

AKA I don't understand what you mean, could you explain ?

Okay let me try again with this.
 
  if (10 > b > 6 || 20 > b > 16 || 15 > b > 11)

Is not a valid if statement even if the compiler does allow it with warnings.
(10 > b > 6) is not a valid conditional expression.
You need to understand order of operations which dictate what the compiler evaluates first. See precedence of operators here:
http://www.cplusplus.com/doc/tutorial/operators/

Taking just the (10 > b > 6 ) portion, the compiler evaluates (10 > b) first. For the sake of illustration, I assumed that b had a value of 1. Any value would have worked as an example. This results is (10 > 1), which gives a boolean result of true. The compiler then substitutes that into the next evaluation (true > 6). What does this mean? Your compiler should give you a warning that is an unsafe comparison of an int to a bool. You need to rewrite your if statement.
 
  if (((10 >b) && (b > 6)) || ... etc 








Oh, that is what you meant, i always attemp to write the code first so it works, then upgrade and upgrade it.

And i understand, thank you for explaining! I will report as soon as i re-write hints algorithm.

EDIT: I came upon something.

1
2
3
4
        if(b == 1)
        {
            hint = array_mine [b+1] + array_mine [b+5] + array_mine [b+6];
        }

Here, it is just a simple "b == 1", so there is no need for proper order of operations, and whenever i input "1" ?

Would be much appreciated for help.
Last edited on
To check for adjacency, use nested for loops , rather than 37 LOC in your case 0: clause.

I would have used a 2d array (5 by 5) instead of 1d (25).

Here is a bash at the function definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
unsigned Adjacent (const unsigned Board[][5], const unsigned BoardRow, const unsigned BoardCol) {

unsigned count =0;
for(int Row = BoardRow-1; Row < BoardRow+1; Row++) {
        //put error checking here so Row doesn't go out of bounds
        //if(condition) {
              //continue;
        //}
      for(int Col = BoardCol-1; Col < BoardCol+1;Col++){
               //put error checking here so Col doesn't go out of bounds
               //if(condition) {
                   //continue;
                //}
            if(Row == (BoardRow +1) && Col == (BoardCol+1)  ) {
               continue; //don't count the current cell
             }
             //if there is a mine count it
             if(Board[Row][Col] == 'M') {
                   count++;
             }
      }
}

return count;
}


I just typed it straight in - hopefully every thing is OK, I didn't compile or test it.

I really wish you would take AbstractionAnon's advice - in particular for loops would improve your code a lot.

As well, I personally hate constructs like line 117, with the use of && and != like that. In this case it clearly needs a for loop, but other situations I have seen a switch is much better.

Now I would also recommend you have a 5 by 5 array of unions. You have several pieces of info to be stored for each cell on the board - A Mine , or adjacency count, or nothing. A union is a type that can store 1 type of info at a particular time, but the type can be any one of those specified in the declaration of the union:

1
2
3
4
5
6
union BoardCell { //<---- the union type
char Mine;            //one of
unsigned Count;   //these
char Empty;         //at a time
} Cell;    //<---- the name of the variable              


To set all the mines use random numbers to correspond to Rows & Cols in nested for loops. Here is an example of how to set 1 mine:

1
2
3
4
5
const unsigned SIZE = 5;

union BoardCell Board[SIZE][SIZE];

Board[2][4].Cell.Mine = 'M';


The Adjacency counting should also be done with for loops, here is how to set 1 of them:

1
2
3
4
5
6
7
//there is only an adjacency count if there is no mine
if(AdjacencyCount > 0 ) {
       Board[1][3].Cell.Count = AdjacencyCount;
}
else{
       Board[1][3].Cell.Empty = ' ';
}


Don't forget to look in the reference section top left of this page, and if you have any compile errors post them in full.

Anyway, now you have lots to think about - hope all goes well.
Last edited on
Pages: 12