Snake v1.0 final

closed account (zwA4jE8b)
I dare you to find a bug.

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
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Michael Ervin - Snake game - Windows
//Inspiration and some structural design from http://www.simonhuggins.com/courses/cbasics/course_notes/snake.htm
//The main game loop is as follows:
//	1)get user input, if valid set direction or pause
//	2)get the snakes next position
//	3)check for collisions
//	4)animate the snake (no collision - yellow, dead snake - red)
//	5)check if level should be advanced
//Sleep(10) is used in the while(true) waiting loops to keep the processor usage at or near 0%
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <conio.h>
#include <vector>
#include <Windows.h>
#include <iostream>
#include <ctime>
#include <fstream>

//Define colors not defined in windows
#define FOREGROUND_YELLOW 0x0006
#define FOREGROUND_WHITE 0x0007
#define FOREGROUND_AQUA 0x0003

struct _coordinates
{
	int _x;
	int _y;
};

//Global variables
HANDLE _handle;

int _level, _score, _highscore, _numfood, _numobstacle, _speed;
const int _rows = 30, _columns = 80;
char _grid[_rows + 2][_columns], _leveltype;
const char _right = 'd', _left = 'a', _up = 'w', _down = 's';
SMALL_RECT _size = {0, 0, 79, 32};
COORD _pos = {0,0};

//Fixed level arrays
COORD _l1[30] = {25,14,26,14,27,14,28,14,29,14,30,14,31,14,32,14,33,14,34,14,35,14,36,14,37,14,38,14,39,14,40,14,
				 41,14,42,14,43,14,44,14,45,14,46,14,47,14,48,14,49,14,50,14,51,14,52,14,53,14,54,14};
COORD _l2[52] = {26,7,26,8,26,9,26,10,26,11,26,12,26,13,26,14,26,15,26,16,26,17,26,18,26,19,
				 27,19,28,19,29,19,30,19,31,19,32,19,33,19,34,19,35,19,36,19,37,19,38,19,39,19,40,19,
				 41,19,42,19,43,19,44,19,45,19,46,19,47,19,48,19,49,19,50,19,51,19,52,19,53,19,
				 53,18,53,17,53,16,53,15,53,14,53,13,53,12,53,11,53,10,53,9,53,8,53,7};
COORD _l3[30] = {20,6,20,7,20,8,20,9,20,10,20,11,20,12,20,13,20,14,20,15,
				 40,17,40,18,40,19,40,20,40,21,40,22,40,23,40,24,40,25,40,26,
				 60,6,60,7,60,8,60,9,60,10,60,11,60,12,60,13,60,14,60,15};
COORD _l4[117] = {17,7,18,7,19,7,20,7,21,7,22,7,23,7,24,7,25,7,26,7,27,7,28,7,29,7,30,7,31,7,32,7,33,7,34,7,35,7,36,7,37,7,38,7,39,7,40,7,41,7,
				 41,8,41,9,41,10,41,11,41,12,41,13,41,14,41,15,
				 42,15,43,15,44,15,45,15,46,15,47,15,48,15,49,15,50,15,51,15,52,15,53,15,54,15,55,15,56,15,57,15,58,15,59,15,60,15,61,15,62,15,63,15,64,15,65,15,66,15,
				 17,11,18,11,19,11,20,11,21,11,22,11,23,11,24,11,25,11,26,11,27,11,28,11,29,11,30,11,31,11,32,11,33,11,34,11,35,11,36,11,37,11,
				 37,12,37,12,37,13,37,14,37,15,37,16,37,17,37,18,37,19,
				 38,19,39,19,40,19,41,19,42,19,43,19,44,19,45,19,46,19,47,19,48,19,49,19,50,19,51,19,52,19,53,19,54,19,55,19,56,19,57,19,58,19,59,19,60,19,61,19,62,19,63,19,64,19,65,19,66,19};
COORD _l5[76] = {2,7,3,7,4,7,5,7,6,7,7,7,8,7,9,7,10,7,11,7,12,7,13,7,14,7,15,7,16,7,17,7,18,7,19,7,20,7,21,7,22,7,23,7,24,7,25,7,26,7,27,7,28,7,29,7,30,7,31,7,32,7,33,7,34,7,35,7,36,7,37,7,38,7,39,7,
				 40,7,41,7,42,7,43,7,44,7,45,7,46,7,47,7,48,7,49,7,50,7,51,7,52,7,53,7,54,7,55,7,56,7,57,7,58,7,59,7,60,7,61,7,62,7,63,7,64,7,65,7,66,7,67,7,68,7,69,7,70,7,71,7,72,7,73,7,74,7,75,7,76,7,77,7};

//Snake object
struct snake
{
	int _length, _foodeaten;
	char _direction;
	bool _deadsnake;
	std::vector<_coordinates> snake_pos;

	snake(int _level):_length(4*_level), _counter(0), _direction(_right), _foodeaten(0), _deadsnake(false){}

	void init_snake(int _ystart)
	{
		snake_pos.resize(0);
		for(int i = 0; i < _length; i++)
		{
			_coordinates _new;
			_new._x = 40;
			_new._y = _ystart;
			snake_pos.push_back(_new);
		}
		snake_pos[0]._x = 40;
	};
	void next_pos()
	{
		int i;
		_old = snake_pos.back();
		
		switch (_direction)
		{
		case _right:
			for(i = _length - 1; i >= 1; i--)
				snake_pos[i] = snake_pos[i - 1];
			snake_pos[0]._x += 1;
			break;
		case _left:
			for(i = _length - 1; i >= 1; i--)
				snake_pos[i] = snake_pos[i - 1];
			snake_pos[0]._x -= 1;
			break;
		case _up:
			for(i = _length - 1; i >= 1; i--)
				snake_pos[i] = snake_pos[i - 1];
			snake_pos[0]._y -= 1;
			break;
		case _down:
			for(i = _length - 1; i >= 1; i--)
				snake_pos[i] = snake_pos[i - 1];
			snake_pos[0]._y += 1;
			break;
		}
	}
	void snake_head(int _ystart)
	{
		SetConsoleTextAttribute(_handle, FOREGROUND_YELLOW | FOREGROUND_INTENSITY);

			_pos.X = 40; _pos.Y = _ystart;
			SetConsoleCursorPosition(_handle, _pos);
			_putch('O');
	}
	void animate_snake()
	{
		if (!_deadsnake)
		{
			SetConsoleTextAttribute(_handle, FOREGROUND_YELLOW | FOREGROUND_INTENSITY);
			
			if (_counter == ((4 * _level) - 1))
			{
				_pos.X = _old._x; _pos.Y = _old._y;
				SetConsoleCursorPosition(_handle, _pos);
				_putch(' ');
			}
			else
				_counter++;

			_pos.X = snake_pos[0]._x; _pos.Y = snake_pos[0]._y;
			SetConsoleCursorPosition(_handle, _pos);
			_putch('O');
		}
		else
		{
			_pos.X = _old._x; _pos.Y = _old._y;
			SetConsoleCursorPosition(_handle, _pos);
			_putch(' ');

			SetConsoleTextAttribute(_handle, FOREGROUND_RED);
			for(int i = 0; i < _length; i++)
			{
				_pos.X = snake_pos[i]._x; _pos.Y = snake_pos[i]._y;
				SetConsoleCursorPosition(_handle, _pos);
				_putch('O');
			}
		}
	}
	void add_seg()
	{
		_coordinates _new = snake_pos.back();
		snake_pos.push_back(_new);
		_length++;
	}
protected:
	int _counter;
private:
	_coordinates _old;
};

void init_lvl(snake&, char&);
void init_lvl_rand(_coordinates&, int);
void init_lvl_fixed(_coordinates&, int&);
void intro();
void update_info();
void collision(snake&, char&);
bool self_collision(snake&);
void dead_snake(snake&);
void end_game(char&);
void read_score();
void write_score();
void clear_grid();
void pause(){char _temp;while(true){Sleep(10);if(_kbhit()){_temp = _getch();if(_temp == 'p')break;}}}

int main()
{
	//Set up console size and attributes
	_handle = GetStdHandle(STD_OUTPUT_HANDLE);
	_CONSOLE_CURSOR_INFO _cinfo = {100, false};
	SetConsoleWindowInfo(_handle, true, &_size);
	SetConsoleTitleA("Snake");
	SetConsoleCursorInfo(_handle, &_cinfo);
	srand(time(0));

	char _input = '\0';
	
	//Initialization and play again loop
	do
	{
		_level = 1;
		_score = 0;
		read_score();
		snake _snake1(_level);
	
		intro();
	
		init_lvl(_snake1, _input);

		//Main game loop
		while (_input != 'x')
		{
			if (_kbhit())
			{
				_input = _getch();
				if (_input == _up || _input == _down || _input == _right || _input == _left)
					_snake1._direction = _input;
				else if (_input == 'p')
					pause();
			}
		
			_snake1.next_pos();
			collision(_snake1, _input);
			_snake1.animate_snake();
			if (_snake1._foodeaten == _numfood)
			{
				_level++;
				_snake1._foodeaten = 0;
				init_lvl(_snake1, _input);
			}
			Sleep(_speed);
		}
		end_game(_input);
		clear_grid();
	}
	while(_input != 'n');
	return 0;
}
closed account (zwA4jE8b)
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
//Display introduction and game info
void intro()
{
	SetConsoleTextAttribute(_handle, FOREGROUND_WHITE | FOREGROUND_INTENSITY);
	
	_pos.X = 36; _pos.Y = 5;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("SNAKE v1.0");

	_pos.X = 27; _pos.Y = 6;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("(Written by: Michael Ervin)");

	_pos.X = 27; _pos.Y = 9;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("w s a d - Up Down Left Right");
	_pos.X = 33; _pos.Y = 10;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("p - Pause");

	_pos.X = 33; _pos.Y = 11;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("x - Exit");

	SetConsoleTextAttribute(_handle, FOREGROUND_AQUA | FOREGROUND_INTENSITY);
	_pos.X = 33; _pos.Y = 12;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("@");
	SetConsoleTextAttribute(_handle, FOREGROUND_WHITE | FOREGROUND_INTENSITY);
	_cprintf(" - Food");

	SetConsoleTextAttribute(_handle, FOREGROUND_RED | FOREGROUND_INTENSITY);
	_pos.X = 33; _pos.Y = 13;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("X");
	SetConsoleTextAttribute(_handle, FOREGROUND_WHITE | FOREGROUND_INTENSITY);
	_cprintf(" - Obstacle");

	SetConsoleTextAttribute(_handle, FOREGROUND_WHITE | FOREGROUND_INTENSITY);
	_pos.X = 30; _pos.Y = 16;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("Press 1 for random levels");
	
	_pos.X = 30; _pos.Y = 17;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("Press 2 for fixed levels");

	while(true)
	{
		Sleep(10);
		if (_kbhit())
		{
			_leveltype = _getch();
			if (_leveltype == '1' || _leveltype == '2')
				break;
		}
	}
}

void clear_grid()
{
	int i, j;
	for(i = 0; i < _rows + 2; i++)
		for(j = 0; j < _columns; j++)
			_grid[i][j] = ' ';

	for(i = 0; i < _rows + 2; i++)
		for(j = 0; j < _columns; j++)
		{
			_pos.X = j; _pos.Y = i;
			SetConsoleCursorPosition(_handle, _pos);
			_putch(_grid[i][j]);
		}
}

void init_lvl(snake& _sn0, char& _in)
{
	int i, j, _ystart = 16;
	_coordinates _stuff;
	_numfood = _level * 4;
	_numobstacle = _level * 3;

	//Fill grid with blanks
	for(i = 0; i < _rows; i++)
		for(j = 0; j < _columns; j++)
			_grid[i][j] = ' ';
	
	//Fill grid with borders
	for(i = 1; i < _columns - 1; i++)
	{
		_grid[0][i] = '=';
		_grid[_rows-1][i] = '=';
	}
	for(i = 0; i < _rows; i++)
	{
		_grid[i][0] = '|';
		_grid[i][_columns - 1] = '|';
	}

	//Set up for either fixed or random level type
	switch (_leveltype)
	{
	case '1':
		init_lvl_rand(_stuff, _ystart);
		_speed = 160 - (10 * _level);
		break;
	case '2':
		if (_level == 6)
			_in =  'x';
		else
			init_lvl_fixed(_stuff, _ystart);
		_speed = 165 - (15 * _level);
		break;
	}

	//Draw grid
	for(i = 0; i < _rows; i++)
		for(j = 0; j < _columns; j++)
		{
			_pos.X = j; _pos.Y = i;
			SetConsoleCursorPosition(_handle, _pos);
			if (_grid[i][j] == '@')
				SetConsoleTextAttribute(_handle, FOREGROUND_AQUA| FOREGROUND_INTENSITY);
			else
				SetConsoleTextAttribute(_handle, FOREGROUND_RED | FOREGROUND_INTENSITY);
			_putch(_grid[i][j]);
		}
	
	SetConsoleTextAttribute(_handle, FOREGROUND_AQUA| FOREGROUND_INTENSITY);
	_pos.X = 3; _pos.Y = 31;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("Level: ");

	_pos.X = 20; _pos.Y = 31;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("Score: ");

	_pos.X = 58; _pos.Y = 31;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("High Score: ");

	_sn0.init_snake(_ystart);
	_sn0.snake_head(_ystart);
	update_info();

	while(!_kbhit()){Sleep(10);}
}

void init_lvl_rand(_coordinates& _stuff, int _ystart)
{
	int i;
	//Fill grid with food and obstacles
	for(i = 0; i < _numfood; i++)
	{
		_stuff._y = (rand()%(_rows - 2)) + 1;
		if (_stuff._y == _ystart)
			i--;
		else
		{
			_stuff._x = (rand()%(_columns - 2)) + 1;
			_grid[_stuff._y][_stuff._x] = '@';
		}
	}

	for(i = 0; i < _numobstacle; i++)
	{
		_stuff._y = (rand()%(_rows - 2)) + 1;
		_stuff._x = (rand()%(_columns - 2)) + 1;
		if (_grid[_stuff._y][_stuff._x] != ' ' || _stuff._y == _ystart)
			i--;
		else
			_grid[_stuff._y][_stuff._x] = 'X';
	}
}
void init_lvl_fixed(_coordinates& _stuff, int& _ystart)
{
	int i;
	switch (_level)
	{
	case 1:
		for(i = 0; i < 30; i++)
		{
			_stuff._y = _l1[i].Y;
			_stuff._x = _l1[i].X;
			_grid[_stuff._y][_stuff._x] = 'X';
		}
		break;
	case 2:
		for(i = 0; i < 52; i++)
		{
			_stuff._y = _l2[i].Y;
			_stuff._x = _l2[i].X;
			_grid[_stuff._y][_stuff._x] = 'X';
		}
		_ystart = 21;
		break;
	case 3:
		for(i = 0; i < 30; i++)
		{
			_stuff._y = _l3[i].Y;
			_stuff._x = _l3[i].X;
			_grid[_stuff._y][_stuff._x] = 'X';
		}
		_ystart = 14;
		break;
	case 4:
		for(i = 0; i < 117; i++)
		{
			_stuff._y = _l4[i].Y;
			_stuff._x = _l4[i].X;
			_grid[_stuff._y][_stuff._x] = 'X';
		}
		_ystart = 6;
		break;
	case 5:
		for(i = 1; i < 4; i++)
		{
			for(int j = 0; j < 76; j++)
			{
			_stuff._y = _l5[j].Y * i;
			_stuff._x = _l5[j].X;
			_grid[_stuff._y][_stuff._x] = 'X';
			}
		}
		_ystart = 6;
		break;
	}

	for(i = 0; i < _numfood; i++)
	{
		_stuff._y = (rand()%(_rows - 2)) + 1;
		_stuff._x = (rand()%(_columns - 2)) + 1;
		if (_grid[_stuff._y][_stuff._x] != ' ' || _stuff._y == _ystart)
			i--;
		else
			_grid[_stuff._y][_stuff._x] = '@';
	}
}

void update_info()
{
	SetConsoleTextAttribute(_handle, FOREGROUND_YELLOW | FOREGROUND_INTENSITY);
	//Show level
	_pos.X = 10; _pos.Y = 31;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("%d", _level);

	//Show score
	_pos.X = 27; _pos.Y = 31;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("%d", _score);

	//Show highscore
	_pos.X = 70; _pos.Y = 31;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("%d", _highscore);
}

void collision(snake& _sn1, char& _in)
{
	_coordinates _check = _sn1.snake_pos[0];
	
	//Check for border collisions
	//Check self collisions
	//Check obstacle collisions
	if (_grid[_check._y][_check._x] == '=' || _grid[_check._y][_check._x] == '|' || _grid[_check._y][_check._x] == 'X' || self_collision(_sn1))
	{
		_sn1._deadsnake = true;
		update_info();
		_in =  'x';
	}
	//Check food collisions
	else if (_grid[_check._y][_check._x] == '@')
	{
		_sn1.add_seg();
		_sn1._foodeaten++;
		_score += (5 * _level);
		update_info();
	}
}

bool self_collision(snake& _sn2)
{
	for(int i = 1; i < _sn2._length - 1; i++)
		if (_sn2.snake_pos[0]._x == _sn2.snake_pos[i]._x && _sn2.snake_pos[0]._y == _sn2.snake_pos[i]._y)
			return true;
	return false;
}

//End of game procedure
void end_game(char& _in)
{
	_pos.X = (_columns / 2) - 4; _pos.Y = (_rows / 2) - 4;
	SetConsoleTextAttribute(_handle, FOREGROUND_GREEN);
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("GAME OVER");

	//Check for high score
	if (_score > _highscore)
	{
		write_score();
		_pos.X = (_columns / 2) - 8; _pos.Y = (_rows / 2) + 2;
		SetConsoleTextAttribute(_handle, FOREGROUND_GREEN);
		SetConsoleCursorPosition(_handle, _pos);
		_cprintf("New High Score: %d", _score);
	}

	//Ask for replay
	SetConsoleTextAttribute(_handle, FOREGROUND_GREEN);
	_pos.X = (_columns / 2) - 17; _pos.Y = 25;
	SetConsoleCursorPosition(_handle, _pos);
	_cprintf("Do you want to play again? (y / n)");
	while(true)
	{
		Sleep(10);
		if (_kbhit())
		{
			_in = _getch();
			if (_in == 'y' || _in =='n')
				break;
		}
	}
}

//Write highscore to file
void write_score()
{
	std::ofstream _outf("highscore.sco");
	_outf << _score;
	_outf.close();
}

//Read in highscore
void read_score()
{
	std::ifstream _inf("highscore.sco");
	if (_inf.is_open())
		_inf >> _highscore;
	else
		_highscore = 0;
	_inf.close();
}
May I ask why you choose to write this in C, or at least in a C like style? I know that Win32 is in C, but you don't have to restrict yourself just becuase of the API, I know for a fact it works good enough in C++ as well.
Last edited on
closed account (zwA4jE8b)
I just wrote it the only way I knew how. I am using conio.h because I do not understand enough about the windows console to do otherwise.

I am a fairly new programmer and really don't know the difference between c and c++ style.

I am using VS 2010 c++
Last edited on
I'm not saying that any part of your code is wrong, it compiles and runs with a few adjustments and I use wxDev-C++(mingw). As for using "conio.h", contrary to popular belief, that actually doesn't matter because header files are compiled into the executable. The only time it makes a difference is when you start to tell other people to use functions from it on forums, this is because it isn't a standard header file so it isn't always an option. This is different from suggesting a third party API because conio.h is very limited compared to something like Boost.

As for bugs, only because you dared me:

- You aren't checking if the PC this is running on is using multiple monitors. Or for that matter what resolution it's running at.

- Your "snake" struct does not have a destructor, nor does it invoke the destructor for it's vector.

- Because you're already including "windows.h" and because "Kernel32.dll" is automatically imported, you should be using "WaitForSingleObject()" instead of "Sleep()" in your pause function, this will actually be better for your goal of not spiking the processor when your game is idle. This is less of a bug an more of a design consideration though.


EDIT: Your function "end_game()" looks like it's incomplete.
Last edited on
Your "snake" struct does not have a destructor, nor does it invoke the destructor for it's vector.


Compiler generated destructor will work. >_>

Anyway, too many variables appended with '_' for no apparent reason.

And despite what Computergeek said, I'd still recommend not using conio.h simply because it isn't standard.
closed account (zwA4jE8b)
I thought about the destructor but did not know how to implement it.
how do you invoke the destructor for the vector?
@ firedraco: You are correct, I thought for some reason that he had made the instance of the snake object global but I was wrong.

@ OP: You're fixed level array's look painful, do you have future plans to dynamically generate these?
closed account (zwA4jE8b)
No, this game was made as a practice, I have never written one before.
The fixed level array was painful but fun. I thought about using iterative loops though.

I began using '_' for var names because I like the style. That is the only reason.

What would I put in the destructor if I manually implemented it? I understand destructing dynamic memory using delete.
First of all regarding the destructor, firedraco is right the default destructor will work. For some reason I thought that you initiated your "snake" object inside of main but had the declaration in the global namespace, probably because I've made that mistake so many times before. But to kick off the destructor for a vector here you go: http://www.cplusplus.com/reference/stl/vector/~vector/ it looks ridiculously simple because it is.
Last edited on
closed account (zwA4jE8b)
Instead of using conio functions, what do you recommend?

std::cin?
Usually, but if you need to get key presses instantly (like you do here), you'd probably want something like the Curses library. Or you could make your game graphical with SFML (it won't be too difficult, really) and use their functions for the keyboard.
closed account (zwA4jE8b)
Cool.
Graphical was next, I just wanted to get the structure and flow correct.
I know if this is a registered window i can just use a windows message loop to get the keystrokes.

I have downloaded sfml but have yet to use it. :P
@Computergeek01: ¿When was the last time that you explicit called a destructor?
Last edited on
@ne555: Never personally, and to tell you the truth I only found out a few weeks ago that you could. But the OP did ask. As for why you would do it I don't know, but the OP might run across a reason that I can't think of.
closed account (zwA4jE8b)
no, I was just wondering because you brought it up.

however, I have a binary search tree class that has dynamic elements, so I wrote the destructor to delete all of the elements in the tree.
However you shouldn't explicitly call it. The destructor is called automatically when the object goes out of scope or when you delete it.
The only exception that I can recall it's placement new
closed account (1yR4jE8b)
Other than using placement new, I don't see any other reason you would need to explicitly call the destructor. In my experience, that was the online time I've needed it.
Topic archived. No new replies allowed.