Snek Assertion Failed

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
ProofOfGravity
Posts: 5
Joined: April 23rd, 2020, 4:59 pm

Snek Assertion Failed

Post by ProofOfGravity » April 23rd, 2020, 5:06 pm

Hey All,

I am stuck on the Snek game. I was making good progress, I got to the point where I finished the snake class and sub-class segments. I have tested the engine and can get brd.drawcell() to draw something anywhere of any color on the screen. However, as I was transitioning into making the actual snake class draw the cell and do all the other fun stuff, I keep running into "assertion failed"; the particular assertion is (on my machine) line 312 in gfx, which is the assertion x>= 0. I have walked through the program a handful of times and cannot quite figure out this bug. For example, the starting location for the snake head, I have used the location variable I have made and fed it directly into brd.drawcell() and it will draw the rect no problem. I have walked through each facet of the snake class and, logically, it seems to work to me. I still couldn't get it, so I broke down and walked through the videos slowly, double checking that what I had done was similar. There were a few loops that I did a different way, but otherwise everything else seemed exactly the same. I then changed the loops to as chili has them in the videos, to see if I was thinking about them wrong, but the problem persists. I know I may not have given enough information, but please let me know if you have any ideas.

And chili, thanks for these videos and your dedication, I do not get much time to practice, but coding has been a great outlet away from regular job, especially during these times. Hope all is well.

User avatar
AleksiyCODE
Posts: 32
Joined: September 21st, 2019, 8:47 pm

Re: Snek Assertion Failed

Post by AleksiyCODE » April 23rd, 2020, 8:21 pm

Did you try using visual studio debugger? Chili has a tutorial on it https://www.youtube.com/watch?v=h2l2D0u ... ex=15&t=0s
This way you will be able to find out at what exact point ate assertion fails
I like ass

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Snek Assertion Failed

Post by albinopapa » April 23rd, 2020, 9:25 pm

As mentioned, you'll have to use the debugger, and more precisely the call stack window. Since the assertion is saying that the pixel is being drawn at a negative X position, once the assertion is triggered click on the previous call stack item and see what the values were before the call to PutPixel. You might have to keep doing this down the stack trace to find the origin of the problem.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

ProofOfGravity
Posts: 5
Joined: April 23rd, 2020, 4:59 pm

Re: Snek Assertion Failed

Post by ProofOfGravity » April 24th, 2020, 12:02 am

Thank you both so much, I really appreciate the help. I will do just that and see if I can solve it. Thanks for the point in the right direction and the helpful youtube link, hope all is well.

ProofOfGravity
Posts: 5
Joined: April 23rd, 2020, 4:59 pm

Re: Snek Assertion Failed

Post by ProofOfGravity » April 24th, 2020, 6:29 pm

Just wanted to say thanks again. After using the debugger, I found that the initial value being passed through my constructor while instantiating the "snake" class was some random garbage digits, but I was initializing the variable, so I was a bit confused at first. But, it turns out that I had the variable listed "too far" down in the header file. So, overall, I think the order of operations was instantiating the "snake" class with a variable that had not been initialized yet and was just garbage value in memory. All I did was move it to the top of the list in the header file and everything worked perfectly. Thanks again for taking the time to respond.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Snek Assertion Failed

Post by albinopapa » April 24th, 2020, 9:32 pm

Yes, that is something that can bite you in the arse if you aren't keen on how initialization works in C++.

The order members are listed in the class declaration is the order they are initialized in the class initializer list ( everything after : and before { in the constructor ). It's usually best to try avoiding having one member relying on another member being initialized first.

If the values are coming from the parameter list, just reuse the paramters instead of copying form a fellow member. This also includes copy constructor, get the values from the copy and not rely on other members.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

ProofOfGravity
Posts: 5
Joined: April 23rd, 2020, 4:59 pm

Re: Snek Assertion Failed

Post by ProofOfGravity » April 24th, 2020, 10:19 pm

That makes a ton of sense. From a "clean code" and best practices standpoint, I am wondering where you would recommend placing this in my case.

For me, I have the "game.h" file, which is where I placed a a private variable, that was a snake class variable:
private:
Location starting = { 5, 5 };

MainWindow& wnd;
Graphics gfx;
Location delta_loc = { 1, 0 };
Board brd;
Snek snake;

In the constructor for the Game class, I have it passing the the Location variable "starting" to the snake constructor for its starting location. Originally, I had the location object being instantiated below the snake class (just based on when I was writing the code at first) and, thanks to you all, is how I figured out I just needed to place it higher, so it was initialized prior to the snake being instantiated within the Game constructor. Is there a more proper place to make the variable "starting"? It initially made sense in my mind for readability sake, but now that I see what you mean about not letting this error bog me down in the future, is there a good idea of where to place this? Making a struct or class? Or perhaps instantiating the snake class directly in the .cpp file? Hopefully this question makes some sense, I feel like it confusing to try to type out sometimes. Thanks again for all your time.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Snek Assertion Failed

Post by albinopapa » April 25th, 2020, 6:52 am

Dammit, I had a lot more written, but deleted it because I didn't think it relevant.

Here's the gist of what I had:

"I know people like to organize their class members in groups, but this can be inefficient in memory usage and possibly performance because of alignment requirements. However, static and constexpr members aren't actually stored in the same location as the other members when objects are instantiated. Normally, they are just constants that get inline into the code unless you take the address of or a reference to the constexpr object. Because of this, you can put your static and static constexpr object declarations anywhere in the class. So for me the best place to put them is the top of the list since I'm usually going to use them to initialize other members like arrays or starting points.

Code: Select all

static constexpr Vec2f start_pos = { 0.f, 1.f };
static constexpr Vec2f start_vel = { 0.f, 0.f };
Vec2f position = start_pos;
Vec2f velocity = start_vel;
It makes it handy for reset() functions:

Code: Select all

void reset()
{
    position = start_pos;
    velocity = start_vel;
}
"
Well, that's about as close as I think I can get to remembering what I wrote.

Seeing as how you are on the Snek game which I think was around Beginner Ep14 or so, I don't recall if chili had covered constexpr and in class static constexpr by that point...I doubt it though.

One thing you can do is depending on your Snek constructor declaration, why not just use the in class initialization like you did with Loc starting_pos.

Code: Select all

Loc starting_pos = { 5, 5 };
Loc delta_loc = { 1, 0 };
Snek snake = Snek{ starting_pos, delta_loc };
This way you won't forget to list the objects required to initialize later objects first.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

ProofOfGravity
Posts: 5
Joined: April 23rd, 2020, 4:59 pm

Re: Snek Assertion Failed

Post by ProofOfGravity » April 26th, 2020, 4:18 pm

Oh I see, I actually didnt realize that static constexpr actually essentially made the expression inline, which makes sense. Also, that does make it super nice to avoid these mistakes in the future.

I have done some reading on other series and other tutorials in the past, so I know a little of constness, but certainly a long way to go, but this helps a ton. Thanks again for all your advice and help, especially having to re-type it a second time, now that is dedication. Hope all is well.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Snek Assertion Failed

Post by albinopapa » April 27th, 2020, 9:38 am

Yeah, a non-constexpr static member either has to be defined outside the class or if you have the compiler set to use C++17 or higher, you can explicitly declare it as inline static or static inline and define it right in the class. For constexpr members, you have to initialize it when declaring it, so it would only make sense that it would be inline, though I wish it was also implicitly static as well.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply