Skip to content

Instantly share code, notes, and snippets.

@esshka
Created October 20, 2023 19:33
Show Gist options
  • Save esshka/0e721e7ca89cb84ed5700a0ab1feb1b9 to your computer and use it in GitHub Desktop.
Save esshka/0e721e7ca89cb84ed5700a0ab1feb1b9 to your computer and use it in GitHub Desktop.
snake game state
import { makeAutoObservable } from 'mobx';
class SnakeGameStore {
// Defining the game grid size
gridSize = 10;
// Defining the snake's initial position and direction
snake = [{ x: 5, y: 5 }];
direction = { x: 0, y: 1 }; // Starts moving downwards
// Randomly place food on the grid
food = {
x: Math.floor(Math.random() * this.gridSize),
y: Math.floor(Math.random() * this.gridSize),
};
constructor() {
makeAutoObservable(this);
}
// Action to move the snake
moveSnake = () => {
// Calculate new head based on direction
const newHead = {
x: this.snake[0].x + this.direction.x,
y: this.snake[0].y + this.direction.y,
};
// Check for collisions with walls or itself
if (
newHead.x < 0 ||
newHead.y < 0 ||
newHead.x >= this.gridSize ||
newHead.y >= this.gridSize ||
this.snake.some(segment => segment.x === newHead.x && segment.y === newHead.y)
) {
// Reset the game if collision
this.resetGame();
return;
}
// Add the new head to the snake
this.snake.unshift(newHead);
// Check if snake has eaten food
if (newHead.x === this.food.x && newHead.y === this.food.y) {
this.placeFood(); // Place new food on the grid
} else {
// If not, remove the tail segment to keep the snake's length consistent
this.snake.pop();
}
}
// Action to change the direction of the snake
setDirection(x, y) {
// Prevents the snake from reversing its direction
if (-x !== this.direction.x && -y !== this.direction.y) {
this.direction = { x, y };
}
}
// Action to place food randomly on the grid
placeFood() {
this.food = {
x: Math.floor(Math.random() * this.gridSize),
y: Math.floor(Math.random() * this.gridSize),
};
}
// Action to reset the game
resetGame() {
this.snake = [{ x: 5, y: 5 }];
this.direction = { x: 0, y: 1 };
this.placeFood();
}
}
export const snakeGameStore = new SnakeGameStore();
import React from 'react';
import { observer } from 'mobx-react-lite';
import { useSnakeGame } from './useSnakeGame'; // Adjust the import path to your hook file
const cellSize = 20; // Defines the size of each grid cell in pixels
function SnakeGrid() {
const { snake, food, moveSnake } = useSnakeGame();
// Call the moveSnake function at regular intervals to make the snake move
React.useEffect(() => {
const interval = setInterval(moveSnake, 200);
return () => clearInterval(interval);
}, [moveSnake]);
return (
<div style={{
width: cellSize * 10,
height: cellSize * 10,
border: '1px solid black',
position: 'relative'
}}>
{snake.map((segment, index) => (
<div
key={index}
style={{
width: cellSize,
height: cellSize,
backgroundColor: 'green',
position: 'absolute',
left: segment.x * cellSize,
top: segment.y * cellSize,
}}
></div>
))}
<div
style={{
width: cellSize,
height: cellSize,
backgroundColor: 'red',
position: 'absolute',
left: food.x * cellSize,
top: food.y * cellSize,
}}
></div>
</div>
);
}
export default observer(SnakeGrid);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment