Here's the code:


This is the output when I compile:

Sketch uses 13086 bytes (42%) of program storage space. Maximum is 30720 bytes. Global variables use 1456 bytes (71%) of dynamic memory, leaving 592 bytes for local variables. Maximum is 2048 bytes.

Everything runs smoothly until getNextFood(), Line 194. I try to make a LinkedList of integers from 0 to 255 (since I am using a 16x16 LED grid). However, my list only fills up to about 39, then the rest are set to zero. I suspected that I was out of memory, so I tried optimizing a few things and was able to get to 42. I changed all the ints to bytes in the getNextFood function and got up to 61, but that broke my program somehow (inf loop).

Any suggestions on how to fix this? If I can get this list to fit, the program is basically done, I have nothing else to add assuming it works as intended.

Also, why I am running out of RAM in the first place? Can someone explain which parts of the program are gobbling up those bytes during runtime (because I would expect the integer list to take up around 512 bytes leaving 80 bytes left, so why I am getting cut off around 40 integers or 80 bytes?)


Edit1: People have pointed out that linked lists take up a lot of space. I am using this library because the way the program is designed, I needed to make an array that could change size. I needed to be able to add and remove elements. Maybe there is a better way to do it, I don't know. I thought about making a single 16x16 array for the whole thing and using a different number for each type of piece. I don't know how I would do the snake movement in that case though, because each piece is "connected" to the one in front of it. If anyone knows of a similar library that would save space I'd be happy to try it. Also there might be a way for me to avoid using the tempSnake list.

Edit2: Per Paul's suggestion, I rewrote the code using a single 16x16 array to represent the entire game board, removing the need for LinkedList. However, it seems I am still falling short, unless there is something else wrong with my code. The program resets when I try to generate the food tiles. https://pastebin.com/ZU4hX477

  • 2
    Stack Exchange sites are really reserved for problems that can be concisely stated on the question page itself. You'll need to reduce your scope to something you can present without relying on a link. Why are you using a linked list in the first place? That will be extraordinarily costly on a system like this. You should use a simple array - but unless you have brightness control even that is excessive, probably you want a bit-mapped array with only 1 bit per pixel. You may also want to consider a more suitable platform like an ARM MCU with more memory, some work with the Arduino IDE. – Chris Stratton May 6 '18 at 17:13
  • 1
    If you are short on RAM, you should try to avoid making full copies of the lined lists. Also, you wrote //implement modulus for position: this operator is already implemented in C++, and you can write newRow = (newRow+1)%16, etc. But note that the numbers should be unsigned in order to get the desired behavior. – Edgar Bonet May 6 '18 at 17:49
  • Do you really need the complexity and bloat of linked lists? – Majenko May 6 '18 at 18:14
  • 1
    Using the F macro for Serial.print would shave off a few bytes. Serial.println(F(“example”)); – Gerben May 6 '18 at 20:31
  • You don't need a linked list to determine the neighbors of grid squares; that's a fairly simple math operation with some limits at the edges. Crudely speaking left is index-1, right is index+1, up is index-16, down is index+16, etc then you check the edge limits. Having a linked list for the snake itself is vaguely reasonable, though instead of an actual linked list perhaps what you should have is a fixed-length array of the index-differences to the next segment. – Chris Stratton May 6 '18 at 21:18

16x16 = 256

So there are 256 possible places to put a piece of snake. The max length of the snake will be 256 (fill the board completely).

So if we take an array of bytes (0-255) that is 256 bytes long we could completely map the snake.

Every step you move (unless if the snake just ate some food) you put it's head forward one step, and remove the last part.

So if we make the new head the value of "snakeLength" and do each piece of the body -1 every round. We will get this "decaying" effect.

For example:

[ 6][5][4] (all -1, head down) [ 5][4][3]
[ 0][0][3]                     [ 6][0][2]
[ 0][1][2]                     [ 0][0][1]

This probably isn't the most efficient method (especially not if you scale it up), but in this case the logic would be very easy.

If the head collides with a position that is not 0, it'll be game over. For the food/apple you could use an x/y value.

If a space is not 0, do it -1.

The upside of this is that you don't allocate memory runtime and you know exactly how many you use. This setup should also make it easier for you to avoid "copying" the whole list all the time, you can basically loop through the array and do -1 for all but those who are 0.

  • I like this idea, for the food what do you mean by x/y value? Like just storing the row and column of the food somewhere? I was thinking to use some negative number like -1. – user6615434 May 6 '18 at 20:09
  • Great idea. You could reserve the value 255 for fruit, and add a check to see that it’s not 255 before decrementing. Maybe reserve 254 for walls. 253 for a teleport q-; – Gerben May 6 '18 at 20:24
  • Still running out of RAM, LOL! 225 bytes available at compile time, crashes when generating new food tiles... pastebin.com/ZU4hX477 – user6615434 May 6 '18 at 23:13
  • Hmm, you should use bytes (8bit/1byte values), if you do -1, you'll either use an integer (2bytes) or have a range of -128 to +128 – Paul May 7 '18 at 10:37
  • Hmm, check the variable 'int foodSquares[numZeros] = { 0 };' which uses 255x 2bytes. As well as your gameboard is using int instead of byte (which is half the size). – Paul May 7 '18 at 10:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.