You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.7 KiB
82 lines
1.7 KiB
5 years ago
|
# Snake Game
|
||
7 years ago
|
|
||
|
Design a snake game that is to be played in web browser.
|
||
|
|
||
|
Client: React + Redux
|
||
|
|
||
2 years ago
|
Rendering: Pixel-based graphics. Depending on the intended resolution, can divide the screen into N \* M pixels. Can dynamically calculate the size of each pixel.
|
||
7 years ago
|
|
||
2 years ago
|
Fruit: One pixel. Snake body: One pixel width made up of connected pixels.
|
||
7 years ago
|
|
||
|
Model:
|
||
5 years ago
|
|
||
|
```js
|
||
7 years ago
|
{
|
||
|
fruit: {
|
||
|
x, y
|
||
|
},
|
||
|
snake: {
|
||
|
points: [(x, y), ...] # head is at index 0
|
||
|
direction: north/south/east/west
|
||
|
}
|
||
|
speed: 500,
|
||
|
points: 0
|
||
|
}
|
||
5 years ago
|
```
|
||
7 years ago
|
|
||
5 years ago
|
```js
|
||
7 years ago
|
function update() {
|
||
|
next_loc = points[0] + (x, y) # Depends on the direction
|
||
|
if (snake.points.find(next_loc) > 0) {
|
||
|
// die
|
||
|
}
|
||
|
let pts = snake.points;
|
||
|
if (!isEqual(next_loc, fruit)) {
|
||
|
pts = points.removeLast();
|
||
|
} else {
|
||
5 years ago
|
generateFruit();
|
||
7 years ago
|
points++;
|
||
|
}
|
||
|
snake.points = [next_loc, ...pts];
|
||
|
|
||
|
// Boundary checking -> die
|
||
|
}
|
||
5 years ago
|
```
|
||
7 years ago
|
|
||
5 years ago
|
```js
|
||
|
function generateFruit() {
|
||
7 years ago
|
// Cannot generate on my own body.
|
||
|
|
||
|
// First approach: while on body, generate
|
||
|
let next_fruit_location = random_location();
|
||
|
while (snake.points.find(next_fruit_location) > 0) {
|
||
5 years ago
|
next_fruit_location = random_location();
|
||
7 years ago
|
}
|
||
5 years ago
|
fruit = next_fruit_location;
|
||
7 years ago
|
|
||
|
// Second approach: brute force
|
||
|
for (let i = 0; i < rows; i++) {
|
||
|
for (let j = 0; j < cols; j++) {
|
||
2 years ago
|
let point = { x: i, y: j };
|
||
7 years ago
|
if (snake.points.find(next_fruit_location) === -1) {
|
||
5 years ago
|
fruit = point;
|
||
7 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Third approach: brute force with random
|
||
5 years ago
|
const available_points = [];
|
||
7 years ago
|
for (let i = 0; i < rows; i++) {
|
||
|
for (let j = 0; j < cols; j++) {
|
||
2 years ago
|
let point = { x: i, y: j };
|
||
7 years ago
|
if (snake.points.find(next_fruit_location) === -1) {
|
||
|
available_points.push(point);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fruit = _.sample(available_points);
|
||
|
}
|
||
|
|
||
|
setInterval(update, speed);
|
||
5 years ago
|
```
|