Sooooo i have an error in my code

hi so i have an error in my code and i don’t know how to fix it its in c++ and when i try to run my code it wont let me i debugged and i says “snake 4.0.exe has triggered a breakpoint.” could someone help???

Would need a lot more information than that.

1 Like

ok so here’s the code
(yes its long sorry)

#include <iostream>
#include <list>
#include <thread>
using namespace std;

#include <Windows.h>

int x, y;
enum eDirecton { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirecton dir;
int nScreenWidth = 120;
int nScreenHeight = 30;

struct sSnakeSegment
{
	int x;
	int y;
};

int main()
{
	// Create Screen Buffer
	wchar_t* screen = new wchar_t[nScreenWidth * nScreenHeight];
	for (int i = 0; i < nScreenWidth * nScreenHeight; i++) screen[i] = L' ';
	HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
	SetConsoleActiveScreenBuffer(hConsole);
	DWORD dwBytesWritten = 0;

	while (1)
	{
		// Reset to known state
		list<sSnakeSegment> snake = { {60,15},{61,15},{62,15},{63,15},{64,15},{65,15},{66,15},{67,15},{68,15},{69,15} };
		int nFoodX = 30;
		int nFoodY = 15;
		int nScore = 0;
		int nSnakeDirection = 3;
		bool bDead = false;
		

		while (!bDead)
		{
			// Frame Timing, compensate for aspect ratio of command line
			auto t1 = chrono::system_clock::now();
			switch ((chrono::system_clock::now() - t1) < ((nSnakeDirection % 2 == 1) ? 120ms : 200ms))
			{
             case 'a':
				 dir = LEFT;
				 break;
			 case 'd':
				 dir = RIGHT;
				 break;
			 case 'w':
				 dir = UP;
				 break;
			 case 's':
				 dir = DOWN;
				 break;
			}

			// ==== Logic

			// Update Snake Position, place a new head at the front of the list in
			// the right direction
			switch (nSnakeDirection)
			{
			case LEFT:
				x--;
				break;
			case RIGHT:
				x++;
				break;
			case UP:
				y--;
				break;
			case DOWN:
				y++;
				break;
			default:
				break;
			}

			// Collision Detect Snake V Food
			if (snake.front().x == nFoodX && snake.front().y == nFoodY)
			{
				nScore++;
				while (screen[nFoodY * nScreenWidth + nFoodX] != L' ')
				{
					nFoodX = rand() % nScreenWidth;
					nFoodY = (rand() % (nScreenHeight - 3)) + 3;
				}

				for (int i = 0; i < 5; i++)
					snake.push_back({ snake.back().x, snake.back().y });
			}

			// Collision Detect Snake V World
			if (snake.front().x < 0 || snake.front().x >= nScreenWidth)
				bDead = true;
			if (snake.front().y < 3 || snake.front().y >= nScreenHeight)
				bDead = true;

			// Collision Detect Snake V Snake
			for (list<sSnakeSegment>::iterator i = snake.begin(); i != snake.end(); i++)
				if (i != snake.begin() && i->x == snake.front().x && i->y == snake.front().y)
					bDead = true;

			// Chop off Snakes tail :-/
			snake.pop_back();

			// ==== Presentation

			// Clear Screen
			for (int i = 0; i < nScreenWidth * nScreenHeight; i++) screen[i] = L' ';

			// Draw Stats & Border
			for (int i = 0; i < nScreenWidth; i++)
			{
				screen[i] = L'=';
				screen[2 * nScreenWidth + i] = L'=';
			}
			wsprintf(&screen[nScreenWidth + 5], L"jcta gaming - S N A K E ! !                                                              SCORE: %d", nScore);


			// Draw Snake Body
			for (auto s : snake)
				screen[s.y * nScreenWidth + s.x] = bDead ? L'+' : L'O';

			// Draw Snake Head
			screen[snake.front().y * nScreenWidth + snake.front().x] = bDead ? L'X' : L'@';

			// Draw Food
			screen[nFoodY * nScreenWidth + nFoodX] = L'%';

			if (bDead)
				wsprintf(&screen[15 * nScreenWidth + 40], L"    PRESS 'SPACE' TO PLAY AGAIN    ");

			// Display Frame
			WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
		}

		// Wait for space
		while ((0x8000 & GetAsyncKeyState((unsigned char)('\x20'))) == 0);
	}

	return 0;
}

ok so that’s the code and when I compile and run it it says i hit a break point and bring me here

could that help???

The message is pretty clear. You are accessing an empty list.

Why is it empty? Because you only ever remove from it, you never add to the direction the snake is going in.

1 Like

ok so what should i do???

Are you following a tutorial by any chance?

1 Like

i was but i stopped cause i wanted to see if i could finish it and the controls where weird so I’m traying to change them.

Add to the list

// Update Snake Position, place a new head at the front of the list in
// the right direction
switch (nSnakeDirection)
{
case LEFT:
    x--;
    break;
case RIGHT:
    x++;
    break;
case UP:
    y--;
    break;
case DOWN:
    y++;
    break;
default:
    break;
}

This doesn’t do what the comment says, it just modifies x and y and the rest of your code doesn’t use them at all. This block is the only instance x and y are used.

1 Like

ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo i kind of get it now i see

soooooooooooooooooooooooooooo should i delete it???

sooooooooooo it still dint work im so confused :frowning:

Could you link the tutorial you are following?

1 Like

here you go https://www.youtube.com/watch?v=e8lYLYlrGLg

…hello?

Please allow for 48 hours before bumping your thread. As yours is not related to the course I’ve given you lower priority to others.


You’ve steered away quite a bit from what’s done in that tutorial which I guess explains some of the other issues I saw in your code.

I’ll try and get back to you regarding that tomorrow. I have a doctors appoint so might not be until the weekend, however. Sorry.

1 Like

ok thanks and good luck with your doctors appointment

Let’s compare some of the code. To start, since I’m not familiar with the Win32 API I had to look up what

(0x8000 & GetAsyncKeyState((unsigned char)('\x27'))) != 0;

was for. looking at the docs, GetAsyncKeyState returns a SHORT (2 bytes) where the most significant bit is set if the key is pressed since the last call and if it’s currently pressed. The least significant bit is set if it was pressed since the last time GetAsyncState was called however it states you shouldn’t rely on that behaviour. So & 0x8000 is testing to see if the first part is true. And 0x27 is for the right arrow key.

Whilst looking at the docs there’s a macro for the right arrow key VK_RIGHT so I substituted it in the code to make it easier to read. Others can be found here https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

So with that out of the way and after the initial setup of variables there’s this code

auto t1 = chrono::system_clock::now();
while ((chrono::system_clock::now() - t1) < ((nSnakeDirection % 2 == 1) ? 120ms : 200ms))

This is looping for 120ms or 200ms depending on the direction of the snake.
Within that loop you have this

// Get Input, 
bKeyRight = 0x80'00 & GetAsyncKeyState(VK_RIGHT);
bKeyLeft = 0x80'00 & GetAsyncKeyState(VK_LEFT);

if (bKeyRight && !bKeyRightOld)
{
    nSnakeDirection++;
    if (nSnakeDirection == 4) nSnakeDirection = 0;
}

if (bKeyLeft && !bKeyLeftOld)
{
    nSnakeDirection--;
    if (nSnakeDirection == -1) nSnakeDirection = 3;
}

bKeyRightOld = bKeyRight;
bKeyLeftOld = bKeyLeft;

Which first gets whether the left and right arrow key is pressed, tests whether the right arrow key is pressed and wasn’t previously pressed and adds to the direction (clockwise) if true. Same with left and deducting. It then sets the variables that store the old values (remember that whilst you can get that by checking the least significant bit of GetAsyncKeyState you shouldn’t rely on it).

Instead of that you have this

auto t1 = chrono::system_clock::now();
switch ((chrono::system_clock::now() - t1) < ((nSnakeDirection % 2 == 1) ? 120ms : 200ms))
{
    case 'a':
        dir = LEFT;
        break;
    case 'd':
        dir = RIGHT;
        break;
    case 'w':
        dir = UP;
        break;
    case 's':
        dir = DOWN;
        break;
}

This is doing a switch statement on whether or not it’s been 120ms or 200ms since t1 which is likely to always be true. This also means you’re switching on bool not char as your case statements imply it is. So that should mean dir is always left.

Next OLC has

switch (nSnakeDirection)
{
case 0: // UP
    snake.push_front({ snake.front().x, snake.front().y - 1 });
    break;
case 1: // RIGHT
    snake.push_front({ snake.front().x + 1, snake.front().y });
    break;
case 2: // DOWN
    snake.push_front({ snake.front().x, snake.front().y + 1 });
    break;
case 3: // LEFT
    snake.push_front({ snake.front().x - 1, snake.front().y });
    break;
}

which uses the calculated direction and adds to the front of the snake in that calculated direction. And as from the last post, yours just increments some ints and never adds to the list.

1 Like

ok so i did what you said i analyzed it and copied it into my code like i think you told me to BUT when I compile and run the program the snake bugs out and hits a wall immediately which ends the game.
it doesn’t show any errors tho…

this is what i added

`while (!bDead)
{
// Frame Timing, compensate for aspect ratio of command line
auto t1 = chrono::system_clock::now();
while ((chrono::system_clock::now() - t1) < ((nSnakeDirection % 2 == 1) ? 120ms : 200ms))
{
bKeyRight = 0x80’00 & GetAsyncKeyState(VK_RIGHT);
bKeyLeft = 0x80’00 & GetAsyncKeyState(VK_LEFT);

			if (bKeyRight && !bKeyRightOld)
			{
				nSnakeDirection++;
				if (nSnakeDirection == 4) nSnakeDirection = 0;
			}

			if (bKeyLeft && !bKeyLeftOld)
			{
				nSnakeDirection--;
				if (nSnakeDirection == -1) nSnakeDirection = 3;
			}

			bKeyRightOld = bKeyRight;
			bKeyLeftOld = bKeyLeft;

			// ==== Logic

			// Update Snake Position, place a new head at the front of the list in
			// the right direction
			switch (nSnakeDirection)
			{
			case 0: // UP
				snake.push_front({ snake.front().x, snake.front().y - 1 });
				break;
			case 1: // RIGHT
				snake.push_front({ snake.front().x + 1, snake.front().y });
				break;
			case 2: // DOWN
				snake.push_front({ snake.front().x, snake.front().y + 1 });
				break;
			case 3: // LEFT
				snake.push_front({ snake.front().x - 1, snake.front().y });
				break;
			}`

Privacy & Terms