# Snake project

Completed example (<https://codepen.io/arkev/pen/pDdoL?editors=0010>)

<https://codepen.io/davmarksman/pen/YzVvmBL>

## Instructions

#### 1. Create canvas

```markup
<canvas id="canvas" width="400" height="400"></canvas>
```

#### 2. Check created correctly. Explain variables. Case is important

```javascript
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = 400;
const height = 400;
// other way of declaring variable is let. will explain later

ctx.fillStyle = "white";
ctx.fillRect(0, 0, width, height);
ctx.strokeStyle = "black";
ctx.strokeRect(0, 0, width, height);
```

#### 3. Function

```javascript
function drawBoard(){
  // alert("Hello");
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, width, height);
  ctx.strokeStyle = "black";
  ctx.strokeRect(0, 0, width, height);
}

drawBoard();
```

#### 4. Paint a cell. Demo in Paint what will do

* Resize canvas
* Draw 2d shape. Line type and fill

```javascript
 const cw = 10; // cell width
 
 function paintCell(x, y){
		ctx.fillStyle = "blue";
		ctx.fillRect(x*cw, y*cw, cw, cw);
		ctx.strokeStyle = "white";
		ctx.strokeRect(x*cw, y*cw, cw, cw);
	}
	
	
paintCell(3,2);
```

![Explain Coordinate system and how it matches up to pixels](/files/-Mg6V982AlIwUUWZ5Cmv)

#### 4.5 Checkpoint

```javascript
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = 400;
const height = 400;
const cw = 10;
let snake;
let game_loop = null;
let dir;
let food;

function drawBoard(){
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, width, height);
  ctx.strokeStyle = "black";
  ctx.strokeRect(0, 0, width, height);
}

function paintCell(x, y){
  ctx.fillStyle = "blue";
  ctx.fillRect(x*cw, y*cw, cw, cw);
  ctx.strokeStyle = "white";
  ctx.strokeRect(x*cw, y*cw, cw, cw);
}

function paint(){
   drawBoard();
}

function init(){
    createSnake();
    createFood();
    dir = "right";

  	if(typeof game_loop != "undefined") clearInterval(game_loop);
		game_loop = setInterval(paint, 200);
}

function createFood()
{
  // todo later
}


function createSnake()
{
  // start here
}

init();
```

#### 5. Create a snake

Explain for loop (instead of manually typing, computer count) and arrays

![](/files/-Mg6cG_0qk5eO85mvVl4)

```javascript
	let snake;  // let as will change
	
	function createSnake()
	{
		let length = 5; //Length of the snake
		snake_array = []; //Empty array to start with
		for(let i = length-1; i>=0; i--)
		{
			//This will create a horizontal snake starting from the top left
			snake_array.push({x: i, y:0});
		}
	}
	
```

#### 6. Draw snake

```javascript
function drawSnake()
{
    for(let i=0; i<snake.length; i++)
    {
        paintCell(snake[i].x, snake[i].y);
    }
}

// add to paint
drawSnake();
```

#### 7. Lets make the snake move

![](/files/-Mg6cKNoiO_ISZ26YUR_)

```javascript
let dir;
let game_loop;

function moveSnake()
{ 
  var newX = snake[0].x;
  var newY = snake[0].y;
  
  if(dir == "right") newX++;
  else if(dir == "left") newX--;
  else if(dir == "up") newY--;
  else if(dir == "down") newY++;
  
  var tail = snake.pop(); //pops out the last cell
	tail.x = newX; 
  tail.y = newY;
	snake.unshift(tail); //puts back the tail as the first cell
}

function paint(){
  drawBoard();
  moveSnake();
  paint_cell(food.x, food.y);
  drawSnake();
}

function init(){
    createSnake();
    dir = "right";

  	if(typeof game_loop != "undefined") clearInterval(game_loop);
		game_loop = setInterval(paint, 200);
}


init();
```

#### 8. Lets make the snake move in different directions

```javascript
function changeDirection(event){
  const key = event.keyCode;
  
	//We will add another clause to prevent reverse gear
  if(key == "37" && dir != "right"){
    dir = "left";
  } else if(key == "38" && dir != "down"){
    dir = "up";
  } else if(key == "39" && dir != "left"){
    dir = "right";
  } else if(key == "40" && dir != "up"){
    dir = "down";
  }
}

document.addEventListener("keydown", changeDirection);
```

#### 9. Lets End the game if you hit a boundary

There are two cases in which the game can end:

* The head of the snake collides with its body.
* The head of the snake collides with the canvas boundary.

```javascript
function hasGameEnded(){
  if(snake[0].x < 0){
    return true;
  } else if(snake[0].x > width/cw){
    return true;
  } else if(snake[0].y < 0){
    return true;
  } else if(snake[0].y > height/cw){
    return true;
  }
  
  return false;
}

// add this inside paint()
  if(hasGameEnded()){
    	//restart game
			init();
			return;
  }
  
```

#### 10. Lets add food

```javascript
let food;

function createFood()
{
	food = {
		x: Math.round(Math.random()*(width-cw)/cw), 
		y: Math.round(Math.random()*(height-cw)/cw), 
	};
}


//
paintCell(food.x, food.y);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tbhp.gitbook.io/thebeta/lesson-plans/5.-snake-project.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
