# Recreating the classic snake game using Vue.js

The snake game was developed and published by Gremlin Industries in 1976 and since then, many versions of this game was developed all around the world (Check out my favorite [slither.io](http://slither.io/)). 

Even though I had played this game multiple times, I had never built this game from scratch. I will show you how I went about building this (using illustrations and code snippets), and how you can build one. 

Vue.js is not a prerequisite for reading this article. The link to the code is at the end.

🎮 [Click here to play my version of the game.](https://snake-game-akshay.netlify.app/) 

### What are the requirements?
- Snake should be able to move in all four directions.
- If the snake eats an apple, the snake size and the score increases by 1.
- If the snake hits the wall or collides with itself, the game is over.
- Display the score and highest score on the screen.

### The initial setup

![initial setup screenshot](https://cdn.hashnode.com/res/hashnode/image/upload/v1608458640384/gdG-s9mvJ.png)

Our game board is an N x N grid (6 x 6 in the image above), where the snake will take up some cells in the grid and the apple will take 1 cell in the grid.

`snakeLocation`: The snake's current location will be saved in this list. This list will contain the locations of each part of the snake. Each snake part location is again a list of 2 values, the row number of the cell and the column number of the cell. The last value of `snakeLocation` is the head of the snake.

`snakeDirection`: This will be the current direction in which the snake moves. Initially, this will be set to `RIGHT`. The other possible directions are `UP`, `DOWN`, and `LEFT`.

`score` and `maxScore`: The `score` will save the score of each game and the `maxScore` will save the maximum score of all the games.

`appleLocation`: This is the list that will save the current location of the apple. This list will contain 2 values, the row number of the cell containing the apple and the column number of the cell containing the apple.

### Once the game starts

Once the game starts, we want a timer to run every N seconds and it should move the snake in each run.

![startgame.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1608746578568/JFCIBKpIF.png)

The `setInterval` will run the `moveSnake` function every `200` milliseconds.

### The snake movement

In each run, the head of the snake will move by 1 in the direction set in `snakeDirection`. So, if the `snakeDirection` is set to `RIGHT`, the snake's head will move one step to the right.

Once the snake's head moves, the rest of the snake's body will follow 1 step (illustrated below).

![snake right movement](https://cdn.hashnode.com/res/hashnode/image/upload/v1608459251828/v-x5VAFIP.png)

![down snake movement](https://cdn.hashnode.com/res/hashnode/image/upload/v1608459529090/cxY-V6ZXl.png)

![down 2 screenshot](https://cdn.hashnode.com/res/hashnode/image/upload/v1608744864123/iy_pXpDsi.png)

### The snake eats the apple

When the snake eats the apple, 2 things happen. The snake's size increases by 1 and the apple randomly change its location.

![snake ate apple screenshot](https://cdn.hashnode.com/res/hashnode/image/upload/v1608744936890/sMZRCtz1D.png)

Now, let's check the implementation of the `moveSnake` function.

### The moveSnake function

![movesnake.png function](https://cdn.hashnode.com/res/hashnode/image/upload/v1608747163036/e35uhMTRK.png)

1) The old head is passed to the `getNewSnakeHead` function and its returns the new snake's head. This new head is saved in the `newSnakeHead` variable.

The `getNewSnakeHead` function takes the old head and with respect to the direction mentioned in `snakeDirection`, updates the head, and returns the head. 

![getnewsnakehead.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1608748495559/iG-oUcrmK.png)

2) Once we have the new head, we check, if the new head touched the grid wall using the `isSnakeHeadOutOfGrid` function OR if the head collided with itself using the `isSnakeAteItself` function. 

If any of the functions return `true`, the game is over.

![gridout.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1608748936197/a8WGPuu1M.png)

3) If both the functions return `false`, that means the new snake head did not hit the wall and it did not bite itself, we move the snake.

First, we set the `newSnakeHead` in our `snakeLocation` list.

Next, we update the rest of the snake's body by moving it one step forward.

We now check if the apple is eaten by the snake and set it in the `isAppleEaten` variable.

If the apple is eaten, we do three things.

- Update the score by 1.
- Increase the size of the snake.
- Get a new location for the apple randomly using the `getRandomAppleLocation` function.

![randomappleloc.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1608749711138/AcsnG-HSD.png)
 
The `getRandomAppleLocation` function picked a new random location and then checks if this new location is on the snake using `isNewAppleLocationOnSnake` function.

Until a new apple location that is not on the snake is found, a new location gets picked (using the while loop).

### Game over

Once the game is over, everything is reset to play again. If the new score is greater than the old maximum score, the `maxScore` is set to the new `score`.

This was fun to build and I hope this was fun to read as well.

🐍[Check the code here](https://github.com/akshays94/snake-game) and 🎮 [play again.](https://snake-game-akshay.netlify.app/) 

Thanks for reading!
