Skip to content

Instantly share code, notes, and snippets.

@technige
Created June 19, 2026 08:02
Show Gist options
  • Select an option

  • Save technige/9959086790fc78f0892abce85227e936 to your computer and use it in GitHub Desktop.

Select an option

Save technige/9959086790fc78f0892abce85227e936 to your computer and use it in GitHub Desktop.
JS Snake game (oneshot from Ministral-3 14B Reasoning on local llama.cpp)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snake Game</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
canvas {
background-color: #333;
border: 2px solid #666;
}
#score {
margin-top: 20px;
font-size: 24px;
}
</style>
</head>
<body>
<div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div id="score">Score: 0</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
const gridSize = 20;
let score = 0;
let snake = [
{x: 10 * gridSize, y: 10 * gridSize}
];
let food = {
x: Math.floor(Math.random() * (canvas.width / gridSize)) * gridSize,
y: Math.floor(Math.random() * (canvas.height / gridSize)) * gridSize
};
// Ensure food is not initially on the snake
while (snake.some(segment => segment.x === food.x && segment.y === food.y)) {
food = {
x: Math.floor(Math.random() * (canvas.width / gridSize)) * gridSize,
y: Math.floor(Math.random() * (canvas.height / gridSize)) * gridSize
};
}
let direction = 'RIGHT';
let gameSpeed = 100; // milliseconds
let gameRunning = true;
function drawSnake() {
ctx.fillStyle = '#4CAF50';
snake.forEach(segment => {
ctx.fillRect(segment.x, segment.y, gridSize, gridSize);
ctx.strokeStyle = '#388E3C';
ctx.strokeRect(segment.x, segment.y, gridSize, gridSize);
});
}
function drawFood() {
ctx.fillStyle = '#F44336';
ctx.beginPath();
ctx.arc(
food.x + gridSize / 2,
food.y + gridSize / 2,
gridSize / 2,
0,
Math.PI * 2
);
ctx.fill();
}
function moveSnake() {
if (!gameRunning) return;
const head = {x: snake[0].x, y: snake[0].y};
switch (direction) {
case 'UP':
head.y -= gridSize;
break;
case 'DOWN':
head.y += gridSize;
break;
case 'LEFT':
head.x -= gridSize;
break;
case 'RIGHT':
head.x += gridSize;
break;
}
if (
head.x < 0 || head.x >= canvas.width ||
head.y < 0 || head.y >= canvas.height ||
snake.some(segment => segment.x === head.x && segment.y === head.y)
) {
gameOver();
return;
}
snake.unshift(head);
if (head.x === food.x && head.y === food.y) {
score++;
scoreElement.textContent = `Score: ${score}`;
placeFood();
} else {
snake.pop();
}
}
function placeFood() {
food = {
x: Math.floor(Math.random() * (canvas.width / gridSize)) * gridSize,
y: Math.floor(Math.random() * (canvas.height / gridSize)) * gridSize
};
while (snake.some(segment => segment.x === food.x && segment.y === food.y)) {
food = {
x: Math.floor(Math.random() * (canvas.width / gridSize)) * gridSize,
y: Math.floor(Math.random() * (canvas.height / gridSize)) * gridSize
};
}
}
function gameOver() {
gameRunning = false;
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#FFF';
ctx.font = '40px Arial';
ctx.textAlign = 'center';
ctx.fillText(`Game Over! Score: ${score}`, canvas.width / 2, canvas.height / 2);
}
function changeDirection(newDirection) {
if (
(direction === 'UP' && newDirection !== 'DOWN') ||
(direction === 'DOWN' && newDirection !== 'UP') ||
(direction === 'LEFT' && newDirection !== 'RIGHT') ||
(direction === 'RIGHT' && newDirection !== 'LEFT')
) {
direction = newDirection;
}
}
document.addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowUp':
case 'w':
case 'W':
changeDirection('UP');
break;
case 'ArrowDown':
case 's':
case 'S':
changeDirection('DOWN');
break;
case 'ArrowLeft':
case 'a':
case 'A':
changeDirection('LEFT');
break;
case 'ArrowRight':
case 'd':
case 'D':
changeDirection('RIGHT');
break;
case ' ':
if (!gameRunning) {
restartGame();
}
break;
}
});
function restartGame() {
snake = [{x: 10 * gridSize, y: 10 * gridSize}];
direction = 'RIGHT';
score = 0;
scoreElement.textContent = `Score: ${score}`;
placeFood();
gameRunning = true;
ctx.clearRect(0, 0, canvas.width, canvas.height);
gameLoop();
}
function gameLoop() {
if (gameRunning) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSnake();
drawFood();
moveSnake();
}
if (gameRunning) {
setTimeout(gameLoop, gameSpeed);
}
}
gameLoop();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment