game picking up values from outside the array

Looking for some guidance again for my minesweeper game. Currently it's working corrently inside the array, it's when I enter coordinate on the edges of the grid it's venturing outside the array and finding mines.

I've got some idea of what's needed, but I've been told it's a bit of a headache to get it working fulling. Left side needs to be if row <2 and >7 do this, column is <2 and >7. and the four coners contain both column and row.




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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
  	#include <iostream>
	#include <conio.h>
	#include <algorithm>
	#include <ctime>
	#include <string>
	#include <climits>
	using namespace std; 

	const int n = 8; //used to pass parramaters for beginner minefield
	int Row;
	int counter;	
	int Column;
	char choice;
	char gameGrid[8][8];
	

//------------------------------------Class for game board -------------------------------------------
	class gameBoard
	{
		public:

		void pop_gameGrid()
		{
			for (int j = 0; j < 8; j++)
			{
				for (int i = 0; i < 8; i++)
					{
						gameGrid[j][i]=0;
					}
			}
		}

		void draw_gameGrid(){
			
		int counter=1;
		int line = 1;
		cout << "  1  2  3  4  5  6  7  8\n";
		for (int j = 0; j < 8; j++)
		{
			cout << line;
			line++;
			for (int i = 0; i < 8; i++)
			{
				cout << "[" << gameGrid[j][i] << "]";
			}
			cout<<endl;
		}	
		}	
	
		void drawBeginner(int beginnerMField[][n])
	{
	
		int counter=1;
		int line = 1;
		cout << "  1  2  3  4  5  6  7  8\n";
		for (int j = 0; j < 8; j++)
		{
			cout << line;
			line++;
			for (int i = 0; i < 8; i++)
			{
				cout << "[" << beginnerMField[j][i] << "]";
			}
			cout<<endl;
		}
	
	}
	
	// randomises 10 mines (9) into an array 8 x 8(beginner board) 
	void mineBeginner(int beginnerMField[][n])
	{
			int x = 0;
		
			srand ((unsigned int)(time(0)));
			for(int x=0; x<8; x++){
		
				for(int j=0;j<8; j++){
					
					int values1=rand()%8;
					int values2=rand()%8;
			 		int temp = beginnerMField[x][j];
					beginnerMField[x][j]=beginnerMField[values1][values2];
					beginnerMField[values1][values2]=temp;		
				}
		}
		
			for(int x=0; x<8; x++)
			{
				for(int j=0;j<8;j++)
				{
					//cout<<beginnerMField[x][j];	
				}
					//cout<<endl;
			}
			
		
	}
	};
//-----------------------------End game board class -------------------------------------------------	
//---------------------------------Class for Move functions------------------------------------------	
	class move
	{
		public:
	 	
		void Move(int beginnerMField[][n])
		
		{
			counter = 48;
		if(beginnerMField[Row-2][Column-2] == 9 ) // North West
			
			{
				counter ++;
			}
		if(beginnerMField[Row-2][Column-1] == 9 ) // North
			{
				counter ++;
			}
		if(beginnerMField[Row-2][Column] == 9 ) // North East
			{
				counter ++;
			}
		if(beginnerMField[Row-1][Column-2] == 9 ) // West
			{
				counter ++;
			}
		if(beginnerMField[Row-1][Column] == 9 )  // East
			{
				counter ++;
			}
		if(beginnerMField[Row][Column] == 9 ) // South East
			{
				counter ++;
			}
		if(beginnerMField[Row][Column-1] == 9 ) // South
			{
				counter ++;
			}
		if(beginnerMField[Row][Column-2] == 9 ) // South West
			{
				counter ++;
			}
		
		gameGrid[Row-1][Column-1]=counter;
		gameBoard GameGrid;
		GameGrid.draw_gameGrid();
		}
		
		void playerbeginner(int beginnerMField[][n]){
		
		bool alive = true;
		string answer;
		
		while(alive){
		
		        
		    cout << "Enter Row number: "<<endl;
		    cin >> Row;
		    cout << "Enter Column number: "<<endl;
		    cin >> Column;
		    
		    cout << "[" << Row << "][" << Column << "]" << "\n";
		    cout <<beginnerMField[Row-1][Column-1] << "\n";
		    
		    move move1;
			move1.Move(beginnerMField);
		}
		
				
		        
		        
		if(beginnerMField[Row-1][Column-1] == 9){
			alive = false;
	        system("CLS");
	        cout<<"			BOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM"<<endl;
	        cout<<"						  GAME OVER"<<endl;
	        cout <<"					  Play again? Type Yes or No"<<endl;
	        cin>>answer;
	        		
	        if(answer == "Yes"  ){
	        		
				}
	        		if(answer == "No" ){
	        			
	        		
					}
			}
			}
		
		
	};
//-------------------------------------------------End Counting array squares around move-----------------------------------------------------------------------------------------
	
//--------------------------------------------------------------------Menu Starts----------------------------------------------------------------------------	
	
	class menu
	{
	public:
		
	void Menu(int beginnerMField[][n]){
		
	int selection;

	cout << "********************************MINESWEEPER*************************************\n\n";
	cout << "1. Play Beginner Game\n" << "2. Play Intermediate Game\n" << "3. Play Advanced Game\n" << "4. Show Score Board\n" << "5. Quit Game\n\n\n";
	cout << "Please enter your selection: ";
	cin >> selection;
	cout << endl;

	switch (selection)
	{
	case 1:
		cout << "Play Beginner Game\n";
		cout << "\n";
		system("CLS");
	
		gameBoard mineBeginner1;
		mineBeginner1.mineBeginner(beginnerMField);
	
		gameBoard GameGrid;
		GameGrid.pop_gameGrid();
		GameGrid.draw_gameGrid();
	
		gameBoard Drawbeginner1;
		Drawbeginner1.drawBeginner(beginnerMField);

		move Move1;
		Move1.playerbeginner(beginnerMField);	
		break;

	case 2:
		cout << "Play Intermediate Game\n";
		cout << "\n";
		system("CLS");
		
		break;
	case 3:
		cout << "Play Advanced Game\n";
		cout << "\n";
		system("CLS");
		
		break;
	
	case 4:
		cout << "Show Score Board\n";
		cout << "\n";
		break;
	
	case 5:
		cout << "Goodbye.\n";
		break;
	
	default: cout << selection << "is not a valid menu item.\n";
	
		cout << endl;
	}
	}
};
//---- End menu----

	
int main(){
	bool alive = true;
		int beginnerMField[][n] = {
							{0,0,9,0,0,9,0,0},
							{0,0,9,0,0,9,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,0,0,0,9,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,0,9,0,0,0,0}
		};
		
		
		menu Menu1;
		Menu1.Menu(beginnerMField);
		
}


Last edited on
closed account (SECMoG1T)
Hello... so i'd just defined a simple function above your main for checking out of range coordinates.

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
int getPos()
{
    int val = 0;
    std::cin>>val;

    while(val<1 || val>9)
    {
        std::cout<<"out of range retry: ";
        std::cin>>val;
    }

    return val;
}

///and used it like this

while(alive)
{
    cout << "Enter Row number 1-9: "<<endl;
    Row = getPos();
		    
    cout << "Enter Column number 1-9: "<<endl;
    Column = getPos();

    cout << "[" << Row << "][" << Column << "]" << "\n";
    cout <<beginnerMField[Row-1][Column-1] << "\n";

    Move move1;
    move1._move(beginnerMField);
}

Last edited on
hey thanks for the reply I've tried adding that code but it's still finding mines outside of the grid.

https://ibb.co/eO3ZKn
closed account (SECMoG1T)
ooh sorry i assumed that you had out of grid errors ... i think now i understand you problem
"you are finding mines within the grid,at coords where they aren't supposed to be"... i'll update shotly
Got your code to compile in gcc by commenting out the spurious reference to conio.h and by changing the class "move" to "moveVX" in order to avoid a conflict.

sh: CLS not found
.....arghh!

Since you're assuming an MSDOS environment, you can output vt100 codes (commonly called ANSI graphics) to clear the screen and avoid the system statement entirely..

// system("CLS");
cout << char(27) << "[2J" << char(27) << "[f";

Also there's no edge detection when the user looks at an edge piece. There's two ways around this:
1: Complicate the program by checking the validity of every single reference
2: Complicate the array by make the array an extra space wider (make sure to initialize the edge pieces, just don't use them in input or output), preventing glitches when the program goes over the edge.

oh, try some colored text too, esc[33m will make forground text yellow. esc[37m white, etc.. use esc[43m to make the background yellow, or use both the 3 (foreground) and 4 (background) at once with a color value 0-7 .. for example, esc[3047m results in black text on white background ... you can make your bombs be red *'s for example. Give it that 1979 feel!

ooh sorry i assumed that you had out of grid errors ... i think now i understand you problem
"you are finding mines within the grid,at coords where they aren't supposed to be"... i'll update shotly


Yea, I think it's picking up 9's outside of the actual array and adding them into the counter.


Cheers for the reply:

as for conio.h it's the way we've been taught to stop the window closing once it's ran the programme by using _getch();


the edge detection is the bit I'm working on now, just trying to figure out the best way of doing it.


-- edit --
I've also just realised by if statement for them hitting a mine doesn't work now I've put everything into classes.
Last edited on
I ran into the edge detection issue when I was coding a cellular automa program (wire world) - it's a common problem with array data. I opted to make the array larger for the sole reason that I wanted to keep the computation of the cellular automa as tight as possible so it would run fast. That's obviously not an issue in a minesweeper game, but I figured I'd mentioned the option anyway.

I ran an input simulation:
(echo 1; for X in 1 2 3 4 5 6 7 8 ; do for Y in 1 2 3 4 5 6 7 8 ; do echo $X ; echo $Y ; done ; done) | ./minesweeper.exe | less
and found another error in your code - you are printing nulls in the brackets when there's nothing detected yet.

I wrapped the cout line causing the problems within an if statement:
1
2
3
4
5
                        if (gameGrid[j][i]) {
                                cout << "[" << gameGrid[j][i] << "]";
                                } else {
                                cout << "[ ]";
                                }
Last edited on
closed account (SECMoG1T)
ooh i went away... just came back, anyhow i've looked at your code and i have tried to correct the errors, i have redefined and renamed some function well i needed that to understand your code ... i hope you'll understand it, check and seee if you can improve your prior 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include <iostream>
	#include <conio.h>
	#include <algorithm>
	#include <ctime>
	#include <string>
	#include <climits>

	using namespace std;

	const int n = 8; //used to pass parramaters for beginner minefield
	int Row     = 0;
	int counter = 0;
	int Column  = 0;
	char choice = 0;
	int gameGrid[8][8]; ///changed to int


//------------------------------------Class for game board -------------------------------------------
class gameBoard
{
    public:

    void init_gameGrid() ///renamed
    {
        for (int j = 0; j < 8; j++)
        {
            for (int i = 0; i < 8; i++)
                {
                    gameGrid[j][i]=0;
                }
        }
    }

    void draw_gameGrid() ///
    {
        int line = 1;

        cout << "  1  2  3  4  5  6  7  8\n";
        for (int j = 0; j < 8; j++)
        {
            cout << line++;
            for (int i = 0; i < 8; i++)   ///redefined this loop
            {
                if(gameGrid[j][i] > 0)
                  cout << "[" << gameGrid[j][i] << "]";
                else
                  cout<<"[ ]";
            }
            cout<<endl;
        }
    }

    void drawBeginnerBoard(int beginnerMField[][n])
    {
        int line = 1;
        cout << "  1  2  3  4  5  6  7  8\n";
        for (int j = 0; j < 8; j++)
        {
            cout << line++;
            for (int i = 0; i < 8; i++)
            {
                cout << "[" << beginnerMField[j][i] << "]";
            }
            cout<<endl;
        }

   }

// randomises 10 mines (9) into an array 8 x 8(beginner board)
    void shuffleBoard(int beginnerMField[][n]) ///renamed
    {
        srand ((unsigned int)(time(0)));

        for(int x=0; x<8; x++)
        {

            for(int j=0;j<8; j++)
            {

                int xCoord = rand()%8;
                int yCoord = rand()%8;
                int temp    = beginnerMField[x][j];
                beginnerMField[x][j] = beginnerMField[xCoord][yCoord];
                beginnerMField[xCoord][yCoord] = temp;
            }
        }
    }
};
//-----------------------------End game board class -------------------------------------------------
//---------------------------------Class for Move functions------------------------------------------


class Move
{
    public:

    int getPos() ///new function
    {
        int val = 0;
        std::cin>>val;

        while(val<1 || val>9)
        {
            std::cout<<"out of range retry: ";
            std::cin>>val;
        }

        return val;
    }

    bool validCoords(int _row,int _col)///checks if [_row,_col] are within the grid // new func
    {
        if((_row < 0 || _row > 7) || (_col < 0 || _col > 7))
            return false;

        return true;
    }

    bool gotMine(int board[][n],int _row, int _col) /// return true if the coords have a mine //new func
    {
        return (board[_row][_col] == 9);
    }

    void checkMines(int beginnerMField[][n]) ///renamed nad redifined function Move
    {
        int _MinesFound = 0;
        int _NeighbrCellsOffset[8][2]  = {{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,+1},{-1,0}};

        for(int i =0; i<8; i++)
        {
            int _neigx = _NeighbrCellsOffset[i][0];//neighbor cell row
            int _neigy = _NeighbrCellsOffset[i][1];//neighbor cell column

           if(validCoords((Row+_neigx),(Column+_neigy)) && gotMine(beginnerMField,(Row+_neigx),(Column+_neigy)))
            ++_MinesFound;
        }

        gameGrid[Row][Column] = _MinesFound;
        Gboard.draw_gameGrid();
    }

    void playerbeginner(int beginnerMField[][n]) ///working now
    {
        bool alive = true;

        while(alive)
        {

            cout << "Enter Row number 1-9: "<<endl;
            Row    = getPos()-1;
            cout << "Enter Column number 1-9: "<<endl;
            Column = getPos()-1;

            cout << "[" << Row+1 << "][" << Column+1 << "]" << "\n";
            cout <<beginnerMField[Row][Column] << "\n";

            Move move1;
            move1.checkMines(beginnerMField);

            if(gotMine(beginnerMField,Row,Column))
            {
                char answer= ' ';
                system("CLS");
                cout<<"	  BOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM"<<endl;
                cout<<"		     		GAME OVER"<<endl;
                cout<<"	            Play again? Type Y or N"<<endl;
                cin>>answer;

                if(answer == 'Y' || answer == 'y')
                {
                    Gboard.shuffleBoard(beginnerMField);
                    Gboard.init_gameGrid();
                    Gboard.draw_gameGrid();
                    Gboard.drawBeginnerBoard(beginnerMField);
                }

                else
                    alive = false;
            }
        }
    }

    private:
        gameBoard Gboard;    ///put this here
};
//-------------------------------------------------End Counting array squares around move-----------------------------------------------------------------------------------------

//--------------------------------------------------------------------Menu Starts----------------------------------------------------------------------------

	class menu
	{
	public:

	void Menu(int beginnerMField[][n]){

	int selection;

	cout << "********************************MINESWEEPER*************************************\n\n";
	cout << "1. Play Beginner Game\n" << "2. Play Intermediate Game\n" << "3. Play Advanced Game\n" << "4. Show Score Board\n" << "5. Quit Game\n\n\n";
	cout << "Please enter your selection: ";
	cin >> selection;
	cout << endl;

	switch (selection)
	{
	case 1:
		cout << "Play Beginner Game\n";
		cout << "\n";
		system("CLS");

		gameBoard Gboard; ///one gameboard is enough
		Gboard.shuffleBoard(beginnerMField);
		Gboard.init_gameGrid();
		Gboard.draw_gameGrid();
		Gboard.drawBeginnerBoard(beginnerMField);

		Move Move1;
		Move1.playerbeginner(beginnerMField);
		break;

	case 2:
		cout << "Play Intermediate Game\n";
		cout << "\n";
		system("CLS");

		break;
	case 3:
		cout << "Play Advanced Game\n";
		cout << "\n";
		system("CLS");

		break;

	case 4:
		cout << "Show Score Board\n";
		cout << "\n";
		break;

	case 5:
		cout << "Goodbye.\n";
		break;

	default: cout << selection << "is not a valid menu item.\n";

		cout << endl;
	}
	}
};
//---- End menu----


int main(){
	bool alive = true;
		int beginnerMField[][n] = {
							{0,0,9,0,0,9,0,0},
							{0,0,9,0,0,9,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,0,0,0,9,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,9,0,0,0,0,0},
							{0,0,0,9,0,0,0,0}
		};


		menu Menu1;
		Menu1.Menu(beginnerMField);

}
Cheers for the replies, much appriciated.

you are printing nulls in the brackets when there's nothing detected yet.

The idea behind this was so I actually had an ascii value to change to a number for the counter, my old grid was messing up if I didn't have a value already inside.

I'll take a look at the code and see if I can understand what's going on. I've just ran it and now it's only printing the co-ordinates with mines around ie anything greater than 1 (0's don't get printed into the grid), so I'll have a look at that also.
Topic archived. No new replies allowed.