# Problems with understanding language

**URL:** <https://discourse.processing.org/t/problems-with-understanding-language/3016>\
**Category:** Beginners\
**Created:** [August 27, 2018, 10:25am UTC](https://discourse.processing.org/t/problems-with-understanding-language/3016 "2018-08-27T10:25:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![crab](https://avatars.discourse-cdn.com/v4/letter/c/c5a1d2/32.png) [@crab](https://discourse.processing.org/u/crab)\
**Post date:** [August 27, 2018, 10:25am UTC](https://discourse.processing.org/t/problems-with-understanding-language/3016/1 "2018-08-27T10:25:28Z")

</div>

There is code for the snake game i am trying to recreate, but it fails on line 44 after eating food with ArrayIndexOutOfBoundsException : 1  
Can anybody explain why this happens and how can i fix this?  
(only death by overlapping yourself is not coded)

```auto
void setup(){
  size(200,200);
  background(0);
  stroke(24,201,46);
  fill(24,201,46);
}
float cs = 20;
int hx = 0, hy = 0, s = 10, xs = 1, ys = 0, t, fx = floor(random(cs))*10, fy = floor(random(cs))*10, tail = 0;
int[] xt = {0,}, yt = {0,};
void keyPressed(){
  if(key == CODED){
    if (keyCode == UP && ys != 1){
      xs = 0;
      ys = -1;
    }
    if (keyCode == DOWN && ys != -1){
      xs = 0;
      ys = 1;
    }
    if(keyCode == RIGHT && xs != -1){
      xs = 1;
      ys = 0;
    }
    if (keyCode == LEFT && xs != 1){
      xs = -1;
      ys = 0;
    }
  }
}
void draw(){
  if (t == 8){
    append(xt,hx);
    append(yt,hy);
    hx+=xs*10;
    hy+=ys*10;
   if (hx >= 201){hx = 0;}
   if(hx < 0){hx = 200;}
   if (hy > 200){hy = 0;}
   if(hy < 0){hy = 200;}
    t = 0;
    background(0);
    rect(hx, hy, s, s);
    for (int i = tail; i > 0; i--){
    xt[i] = xt[i-1];
    yt[i] = yt[i-1];
    rect (xt[i],yt[i],s,s);
    }
  }
  t++;
  if(hx == fx && hy == fy){
    tail++;
    fx = floor(random(cs))*10;
    fy = floor(random(cs))*10;
  }
  stroke(255,0,0);
  fill(255,0,0);
  rect(fx, fy, s, s);
  stroke(24,201,46);
  fill(24,201,46);
}

```

Thanks for any help!

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [August 27, 2018, 11:36am UTC](https://discourse.processing.org/t/problems-with-understanding-language/3016/2 "2018-08-27T11:36:15Z")

</div>

> [@crab](#):
>
> ArrayIndexOutOfBoundsException

That means that you are trying to access an element that does not exist in your array. So if you have 4 elements in it, it means that you are trying to access the 5, 6, 7…  
I can’t see any place in your code when you are changing the size of your array.

Check out the official documentation about Array for more infos: [Array / Reference / Processing.org](https://processing.org/reference/Array.html)

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [August 27, 2018, 2:05pm UTC](https://discourse.processing.org/t/problems-with-understanding-language/3016/3 "2018-08-27T14:05:28Z")

</div>

When you eat the food, the head of the snake is in the same position as the food.

Thus, `hx` equals `fx` and `hy` equals `fy`. The h and f stand for head and food, you see?

So anyway, this block suddenly starts to happen:

```auto
  if (hx == fx && hy == fy) {
    tail++;
    fx = floor(random(cs))*10;
    fy = floor(random(cs))*10;
  }

```

What does that say? First, make the snake longer. Sounds good. Then, move the food. Okay.

But how many times does that happen? Ah ha! It happens each time draw() happens when the head is at the same position as the food.

Now the next question is, how often is the snake’s position actually updated?

It’s not easy, but if you dive into the use of the `t` variable, you’ll see that the snake is being updated every 8 frames! The giveaway is how t is updated:

```auto
void draw() { 
  if (t == 8) {
    // Snake updates... length actually increases.
    t = 0;
    // ...
  }
t++;
// Head and food collide? Tail length increases.
}

```

So here’s what’s happening.

The head of the snake collides with the food. This causes the conditions to resize the snake and move the food to be met. But that happens up to 8 times before the snake moves again. But the snake’s tail only has positions added when the snake updates! So when you eat the food, suddenly your snake is 8 longer - not 1 - but none of those 8 tails positions have been added!

In short, there is a mismatch between `tail` - the supposed length of the snake’s tail - and the length of `xt`/`yt` - the actual number of tail segments there are. Knowing this, and with a bit of code reshuffle, we can fix the problem:

```auto
float cs = 20;
int hx = 0, hy = 0;
int s = 10, xs = 1, ys = 0;
int t;
int fx = floor(random(cs))*10, fy = floor(random(cs))*10;
int[] xt = {0}, yt = {0};
boolean grow = false;

void setup() {
  size(200, 200);
  background(0);
  stroke(24, 201, 46);
  fill(24, 201, 46);
}

void draw() {
  if (t == 8) {
    append(xt, hx);
    append(yt, hy);
    if(grow){
      append(xt, hx+xs*10);
      append(yt, hy+ys*10);
      grow = false;
    }
    hx+=xs*10;
    hy+=ys*10;
    if (hx >= 201) {
      hx = 0;
    }
    if (hx < 0) {
      hx = 200;
    }
    if (hy > 200) {
      hy = 0;
    }
    if (hy < 0) {
      hy = 200;
    }
    t = 0;
    background(0);
    rect(hx, hy, s, s);
    for (int i = xt.length-1; i > 0; i--) {
      xt[i] = xt[i-1];
      yt[i] = yt[i-1];
      rect (xt[i], yt[i], s, s);
    }
  }
  t++;
  if (hx == fx && hy == fy) {
    grow = true;
    fx = floor(random(cs))*10;
    fy = floor(random(cs))*10;
  }
  stroke(255, 0, 0);
  fill(255, 0, 0);
  rect(fx, fy, s, s);
  stroke(24, 201, 46);
  fill(24, 201, 46);
}

void keyPressed() {
  if (key == CODED) {
    if (keyCode == UP && ys != 1) {
      xs = 0;
      ys = -1;
    }
    if (keyCode == DOWN && ys != -1) {
      xs = 0;
      ys = 1;
    }
    if (keyCode == RIGHT && xs != -1) {
      xs = 1;
      ys = 0;
    }
    if (keyCode == LEFT && xs != 1) {
      xs = -1;
      ys = 0;
    }
  }
}

```

Works, right? Well, no. It no longer crashes. But now the tail doesn’t grow at all! Isn’t debugging fun?

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [August 27, 2018, 2:29pm UTC](https://discourse.processing.org/t/problems-with-understanding-language/3016/4 "2018-08-27T14:29:00Z")

</div>

So why doesn’t the tail grow now? Well, it never did, did it?

The problem is that `append()` returns an array - it doesn’t assign that array to anything. Basically, whoever wrote this didn’t use `append()` properly.

There are several other problems with this code as well. But I think the biggest problem, really, is that you ALREADY HAD this code. The best thing to do would be to take this code as an example and write a BETTER VERSION yourself, from scratch.

So let’s do that. Start with an empty sketch.

```auto
void setup(){
  size(600,400);
}

void draw(){
  background(0);
}

```

This code is already better than what you started with because it is 100% bug free & you understand it completely.

For most people, the next step is to try to write code. This is the wrong approach. For good coders, the next step is to break the large problem of “MAKE A SNAKE GAME” down into smaller steps. That’s better. But for once, we’re going to jump right into thinking with Portals. No wait, Objects. Now we’re thinking with Objects.

What sort of Objects would you need to have a snake game?

You need a snake.  
You need food.  
Anything else?  
I can think of one that might be useful. A timer. That way we can avoid the weird `t` variable and how it was being used.

Let’s write those objects!

```auto
class Snake {
  // Maybe sme sort of way of storing body segments?
  int d; // Direction
  Snake() {
    d = 0;
  }
  void draw() {
  }
  void update() {
  }
  void grow() {
  }
  void onKeyPressed() {
  }
}

class Food {
  int x, y;
  Food() {
  }
  void draw() {
  }
  boolean wasEaten() {
    return false;
  }
}

class Timer {
  int time;
  int duration;
  Timer() {
    duration = 500;
    reset();
  }
  void reset() {
    time = millis() + duration;
  }
  boolean alarm() {
    if ( millis() > time ) {
      time = millis() + duration;
      return true;
    }
    return false;
  }
}

```

Why bother doing it this way?!?

This is why! Our main driving code becomes much easier to understand:

```auto
Snake snake;
Food food;
Timer timer;

void setup() {
  size(600, 400);
  snake = new Snake();
  food = new Food();
  timer = new Timer();
}

void draw() {
  background(0);
  if ( timer.alarm() ) {
    snake.update();
    if ( food.wasEaten() ) {
      snake.grow();
    }
  }
  food.draw();
  snake.draw();
}

void keyPressed() {
  snake.onKeyPressed();
}

```

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [August 27, 2018, 2:55pm UTC](https://discourse.processing.org/t/problems-with-understanding-language/3016/5 "2018-08-27T14:55:54Z")

</div>

Anyway, all you have to do next is fill in those classes.

This is what I came up with:

```auto
// Useful arrays to decode/use direction.
int[] dx = {1, 0, -1, 0};
int[] dy = {0, 1, 0, -1};
int[] dk = { RIGHT, DOWN, LEFT, UP };

class Snake {
  int x, y; // Current head position.
  ArrayList<PVector> tail; // Other segments.
  int d; // Direction of movement;
  boolean isGrowing = false;
  Snake() {
    d = 0;
    tail = new ArrayList();
  }
  void draw() {
    fill(50,200,50);
    stroke(150,200,50);
    rect(x,y,20,20);
    for( int i = 0; i < tail.size(); i++){
      rect(tail.get(i).x,tail.get(i).y,20,20);
    }
  }
  void update() {
    tail.add( new PVector(x,y,d) );
    if( isGrowing ){
      isGrowing = false;
    } else {
      tail.remove(0);
    }
    x += 20*dx[d];
    y += 20*dy[d];
    x += width;
    y += height;
    x %= width;
    y %= height;
  }
  void grow() {
    isGrowing = true;
  }
  void onKeyPressed() {
    for( int i = 0; i < dk.length; i++){
      if( key == CODED && keyCode == dk[i] ){
        d = i;
      }
    }
  }
}

class Food {
  int x, y;
  Food() {
    newPosition();
  }
  void draw() {
    fill(255,0,0);
    stroke(200,0,200);
    ellipse(x+10,y+10,20,20);
  }
  boolean wasEaten(int ox, int oy) {
    if ( x == ox && y == oy ) {
      newPosition();
      return true;
    }
    return false;
  }
  void newPosition() {
    x = 20 * int(random(width/20));
    y = 20 * int(random(height/20));
  }
}

class Timer {
  int time;
  int duration;
  Timer() {
    duration = 100;
    reset();
  }
  void reset() {
    time = millis() + duration;
  }
  boolean alarm() {
    if ( millis() > time ) {
      time = millis() + duration;
      return true;
    }
    return false;
  }
}

// --- Main driving code follows. Notice how simple its logic is to understand!

Snake snake;
Food food;
Timer timer;

void setup() {
  size(600, 400);
  snake = new Snake();
  food = new Food();
  timer = new Timer();
}

void draw() {
  background(0);
  if ( timer.alarm() ) {
    snake.update();
    if ( food.wasEaten( snake.x, snake.y ) ) {
      snake.grow();
    }
  }
  food.draw();
  snake.draw();
}

void keyPressed() {
  snake.onKeyPressed();
}

```

Using a dynamic structure (an ArrayList) for storing the body segments makes handling the tail a lot easier.

Anyway, this is a MUCH better snake game example to learn from.
