Nemotron 3 Ultra (free)
by NVIDIAReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 1 min 16 s
- Cost
- $0
- Output tokens
- 5,769
- Spent thinking
- 0 tokens
- Speed
- 77.2 tok/s
- Console errors
- 0
- First token after
- 949 ms
- First visible text after
- 949 ms
- Prompt tokens
- 517
- Code size
- 22.1 KB
- Finish reason
- stop
- Served by
- Nvidia
- Model id
nvidia/nemotron-3-ultra-550b-a55b:free- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 9, 2026
What it was asked
The prompt
Build a polished Snake game in a single HTML file using vanilla JavaScript and a <canvas>. Requirements: - A grid of at least 20×20 cells, centered on the page. - Arrow keys and WASD control the snake. Quick successive key presses must both be honored, but the snake can never reverse onto itself. - Eating food adds 10 points and grows the snake by one cell; new food never spawns on the snake. - Game over when the snake hits a wall or itself, with an overlay showing the score; Space or Enter restarts, P pauses. - Visual polish: smooth movement, a snake with a distinct head and eyes facing its direction, and a small particle burst when eating. - Display the current score and the best score of the session.
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.html · 705 lines
<!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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
overflow: hidden;
}
.game-container {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
h1 {
color: #e94560;
font-size: clamp(1.5rem, 5vw, 2.5rem);
text-shadow: 0 0 20px rgba(233, 69, 96, 0.5);
letter-spacing: 2px;
}
.score-board {
display: flex;
gap: 30px;
padding: 15px 30px;
background: rgba(0, 0, 0, 0.4);
border-radius: 12px;
border: 2px solid rgba(233, 69, 96, 0.3);
backdrop-filter: blur(10px);
}
.score-item {
display: flex;
flex-direction: column;
align-items: center;
min-width: 100px;
}
.score-label {
color: #a0a0b0;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 4px;
}
.score-value {
color: #fff;
font-size: 1.5rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
}
.score-value.high-score {
color: #e94560;
}
canvas {
background: #0a0a15;
border: 3px solid #e94560;
border-radius: 8px;
box-shadow:
0 0 30px rgba(233, 69, 96, 0.3),
inset 0 0 60px rgba(0, 0, 0, 0.5);
display: block;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(10, 10, 21, 0.95);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20px;
border-radius: 5px;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
border: 3px solid #e94560;
border-radius: 8px;
pointer-events: none;
}
.overlay.visible {
opacity: 1;
visibility: visible;
pointer-events: auto;
}
.overlay h2 {
color: #e94560;
font-size: clamp(1.5rem, 5vw, 2.5rem);
text-shadow: 0 0 20px rgba(233, 69, 96, 0.5);
}
.overlay p {
color: #c0c0d0;
font-size: 1.1rem;
}
.final-score {
color: #fff;
font-size: 2rem;
font-weight: 700;
}
.controls-hint {
color: #606070;
font-size: 0.85rem;
line-height: 1.8;
text-align: center;
}
.btn {
padding: 12px 32px;
font-size: 1rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
border: none;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background: linear-gradient(135deg, #e94560, #c73659);
color: #fff;
box-shadow: 0 4px 15px rgba(233, 69, 96, 0.4);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(233, 69, 96, 0.6);
}
.btn-primary:active {
transform: translateY(0);
}
@media (max-width: 480px) {
.score-board {
gap: 20px;
padding: 12px 20px;
}
.score-item {
min-width: 80px;
}
.score-value {
font-size: 1.25rem;
}
}
</style>
</head>
<body>
<div class="game-container">
<h1>SNAKE</h1>
<div class="score-board">
<div class="score-item">
<span class="score-label">Score</span>
<span class="score-value" id="currentScore">0</span>
</div>
<div class="score-item">
<span class="score-label">Best</span>
<span class="score-value high-score" id="bestScore">0</span>
</div>
</div>
<canvas id="gameCanvas" width="500" height="500"></canvas>
<div class="overlay" id="startOverlay">
<h2>SNAKE</h2>
<p class="controls-hint">
Arrow Keys or WASD to move<br>
Space or Enter to start<br>
P to pause
</p>
<button class="btn btn-primary" id="startBtn">Start Game</button>
</div>
<div class="overlay" id="gameOverOverlay">
<h2>GAME OVER</h2>
<p class="final-score" id="finalScore">Score: 0</p>
<p class="controls-hint">Press Space, Enter or click Restart</p>
<button class="btn btn-primary" id="restartBtn">Restart</button>
</div>
<div class="overlay" id="pauseOverlay">
<h2>PAUSED</h2>
<p class="controls-hint">Press P or Space to resume</p>
<button class="btn btn-primary" id="resumeBtn">Resume</button>
</div>
</div>
<script>
// Game Constants
const GRID_SIZE = 25;
const CELL_SIZE = 20;
const CANVAS_SIZE = GRID_SIZE * CELL_SIZE;
const INITIAL_SPEED = 120;
const SPEED_INCREASE = 2;
const MIN_SPEED = 50;
// Colors
const COLORS = {
bg: '#0a0a15',
grid: '#1a1a2e',
snakeBody: '#00d4aa',
snakeHead: '#00ffcc',
snakeEye: '#0a0a15',
snakeEyeGlow: '#00ffcc',
food: '#e94560',
foodGlow: '#ff6b6b',
particle: ['#e94560', '#00ffcc', '#ffd700', '#ff6b6b', '#00d4aa'],
text: '#ffffff'
};
// Directions
const DIRS = {
UP: { x: 0, y: -1 },
DOWN: { x: 0, y: 1 },
LEFT: { x: -1, y: 0 },
RIGHT: { x: 1, y: 0 }
};
// Game State
let snake = [];
let direction = DIRS.RIGHT;
let nextDirection = DIRS.RIGHT;
let food = { x: 0, y: 0 };
let score = 0;
let bestScore = 0;
let gameSpeed = INITIAL_SPEED;
let gameLoopId = null;
let lastMoveTime = 0;
let isGameOver = false;
let isPaused = false;
let isStarted = false;
let animationFrameId = null;
let particles = [];
// DOM Elements
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const currentScoreEl = document.getElementById('currentScore');
const bestScoreEl = document.getElementById('bestScore');
const finalScoreEl = document.getElementById('finalScore');
const startOverlay = document.getElementById('startOverlay');
const gameOverOverlay = document.getElementById('gameOverOverlay');
const pauseOverlay = document.getElementById('pauseOverlay');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const resumeBtn = document.getElementById('resumeBtn');
// Set canvas size
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
// Input handling
const keyMap = {
'ArrowUp': DIRS.UP, 'KeyW': DIRS.UP,
'ArrowDown': DIRS.DOWN, 'KeyS': DIRS.DOWN,
'ArrowLeft': DIRS.LEFT, 'KeyA': DIRS.LEFT,
'ArrowRight': DIRS.RIGHT, 'KeyD': DIRS.RIGHT
};
const oppositeDir = {
[DIRS.UP]: DIRS.DOWN,
[DIRS.DOWN]: DIRS.UP,
[DIRS.LEFT]: DIRS.RIGHT,
[DIRS.RIGHT]: DIRS.LEFT
};
function handleKeyDown(e) {
const dir = keyMap[e.code];
if (dir && dir !== oppositeDir[direction]) {
nextDirection = dir;
e.preventDefault();
}
if (e.code === 'Space' || e.code === 'Enter') {
e.preventDefault();
if (!isStarted) {
startGame();
} else if (isGameOver) {
restartGame();
} else if (isPaused) {
resumeGame();
}
}
if (e.code === 'KeyP') {
e.preventDefault();
if (isStarted && !isGameOver) {
togglePause();
}
}
}
document.addEventListener('keydown', handleKeyDown);
// Button handlers
startBtn.addEventListener('click', startGame);
restartBtn.addEventListener('click', restartGame);
resumeBtn.addEventListener('click', resumeGame);
// Canvas click to focus/start
canvas.addEventListener('click', () => {
canvas.focus();
if (!isStarted) startGame();
else if (isGameOver) restartGame();
else if (isPaused) resumeGame();
});
// Particle System
class Particle {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
this.size = Math.random() * 4 + 2;
this.speed = Math.random() * 3 + 1;
this.angle = Math.random() * Math.PI * 2;
this.life = 1;
this.decay = Math.random() * 0.02 + 0.015;
}
update() {
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
this.life -= this.decay;
this.size *= 0.98;
}
draw(ctx) {
ctx.save();
ctx.globalAlpha = this.life;
ctx.fillStyle = this.color;
ctx.shadowColor = this.color;
ctx.shadowBlur = 10;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
}
function createParticles(x, y, count = 15) {
for (let i = 0; i < count; i++) {
const color = COLORS.particle[Math.floor(Math.random() * COLORS.particle.length)];
particles.push(new Particle(x, y, color));
}
}
function updateParticles() {
particles = particles.filter(p => p.life > 0);
particles.forEach(p => p.update());
}
function drawParticles() {
particles.forEach(p => p.draw(ctx));
}
// Game Logic
function initGame() {
snake = [
{ x: 12, y: 12 },
{ x: 11, y: 12 },
{ x: 10, y: 12 }
];
direction = DIRS.RIGHT;
nextDirection = DIRS.RIGHT;
score = 0;
gameSpeed = INITIAL_SPEED;
isGameOver = false;
isPaused = false;
particles = [];
updateScoreDisplay();
spawnFood();
}
function startGame() {
if (isStarted && !isGameOver) return;
initGame();
isStarted = true;
hideAllOverlays();
lastMoveTime = performance.now();
gameLoop();
}
function restartGame() {
initGame();
hideAllOverlays();
lastMoveTime = performance.now();
gameLoop();
}
function togglePause() {
if (isGameOver) return;
isPaused = !isPaused;
if (isPaused) {
showOverlay(pauseOverlay);
cancelAnimationFrame(animationFrameId);
} else {
hideOverlay(pauseOverlay);
lastMoveTime = performance.now();
gameLoop();
}
}
function resumeGame() {
if (!isPaused) return;
isPaused = false;
hideOverlay(pauseOverlay);
lastMoveTime = performance.now();
gameLoop();
}
function gameOver() {
isGameOver = true;
isStarted = false;
cancelAnimationFrame(animationFrameId);
if (score > bestScore) {
bestScore = score;
bestScoreEl.textContent = bestScore;
}
finalScoreEl.textContent = `Score: ${score}`;
showOverlay(gameOverOverlay);
}
function showOverlay(overlay) {
overlay.classList.add('visible');
}
function hideOverlay(overlay) {
overlay.classList.remove('visible');
}
function hideAllOverlays() {
hideOverlay(startOverlay);
hideOverlay(gameOverOverlay);
hideOverlay(pauseOverlay);
}
function updateScoreDisplay() {
currentScoreEl.textContent = score;
}
function spawnFood() {
let newFood;
do {
newFood = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
} while (snake.some(seg => seg.x === newFood.x && seg.y === newFood.y));
food = newFood;
}
function moveSnake() {
direction = nextDirection;
const head = {
x: snake[0].x + direction.x,
y: snake[0].y + direction.y
};
// Wall collision
if (head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE) {
gameOver();
return false;
}
// Self collision
if (snake.some(seg => seg.x === head.x && seg.y === head.y)) {
gameOver();
return false;
}
snake.unshift(head);
// Food collision
if (head.x === food.x && head.y === food.y) {
score += 10;
updateScoreDisplay();
gameSpeed = Math.max(MIN_SPEED, gameSpeed - SPEED_INCREASE);
// Particle burst at food position
const particleX = (food.x + 0.5) * CELL_SIZE;
const particleY = (food.y + 0.5) * CELL_SIZE;
createParticles(particleX, particleY, 20);
spawnFood();
} else {
snake.pop();
}
return true;
}
// Rendering
function drawGrid() {
ctx.strokeStyle = COLORS.grid;
ctx.lineWidth = 0.5;
ctx.beginPath();
for (let i = 0; i <= GRID_SIZE; i++) {
ctx.moveTo(i * CELL_SIZE, 0);
ctx.lineTo(i * CELL_SIZE, CANVAS_SIZE);
ctx.moveTo(0, i * CELL_SIZE);
ctx.lineTo(CANVAS_SIZE, i * CELL_SIZE);
}
ctx.stroke();
}
function drawFood() {
const x = food.x * CELL_SIZE;
const y = food.y * CELL_SIZE;
const centerX = x + CELL_SIZE / 2;
const centerY = y + CELL_SIZE / 2;
const radius = CELL_SIZE / 2 - 2;
// Glow
const gradient = ctx.createRadialGradient(
centerX, centerY, 0,
centerX, centerY, radius + 4
);
gradient.addColorStop(0, COLORS.foodGlow);
gradient.addColorStop(1, 'transparent');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(centerX, centerY, radius + 4, 0, Math.PI * 2);
ctx.fill();
// Food body
ctx.fillStyle = COLORS.food;
ctx.shadowColor = COLORS.food;
ctx.shadowBlur = 15;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
// Highlight
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.beginPath();
ctx.arc(centerX - 3, centerY - 3, radius * 0.3, 0, Math.PI * 2);
ctx.fill();
}
function drawSnake() {
snake.forEach((seg, i) => {
const x = seg.x * CELL_SIZE;
const y = seg.y * CELL_SIZE;
const isHead = i === 0;
const isTail = i === snake.length - 1;
// Determine segment colors
const bodyColor = isHead ? COLORS.snakeHead : COLORS.snakeBody;
// Draw segment with rounded corners
const radius = 4;
ctx.fillStyle = bodyColor;
ctx.shadowColor = bodyColor;
ctx.shadowBlur = isHead ? 10 : 5;
// Main body
roundRect(ctx, x + 1, y + 1, CELL_SIZE - 2, CELL_SIZE - 2, radius);
ctx.fill();
ctx.shadowBlur = 0;
// Head details
if (isHead) {
drawEyes(x, y, direction);
}
// Segment highlight
ctx.fillStyle = 'rgba(255, 255, 255, 0.15)';
roundRect(ctx, x + 2, y + 2, CELL_SIZE - 4, 4, 2);
ctx.fill();
});
}
function roundRect(ctx, x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
}
function drawEyes(x, y, dir) {
const eyeSize = 3;
const eyeOffset = 5;
const centerX = x + CELL_SIZE / 2;
const centerY = y + CELL_SIZE / 2;
let leftEyeX, leftEyeY, rightEyeX, rightEyeY;
if (dir === DIRS.RIGHT) {
leftEyeX = centerX + 2; leftEyeY = centerY - eyeOffset;
rightEyeX = centerX + 2; rightEyeY = centerY + eyeOffset;
} else if (dir === DIRS.LEFT) {
leftEyeX = centerX - 2; leftEyeY = centerY - eyeOffset;
rightEyeX = centerX - 2; rightEyeY = centerY + eyeOffset;
} else if (dir === DIRS.UP) {
leftEyeX = centerX - eyeOffset; leftEyeY = centerY - 2;
rightEyeX = centerX + eyeOffset; rightEyeY = centerY - 2;
} else { // DOWN
leftEyeX = centerX - eyeOffset; leftEyeY = centerY + 2;
rightEyeX = centerX + eyeOffset; rightEyeY = centerY + 2;
}
// Eye whites
ctx.fillStyle = '#fff';
ctx.shadowColor = COLORS.snakeEyeGlow;
ctx.shadowBlur = 5;
ctx.beginPath();
ctx.arc(leftEyeX, leftEyeY, eyeSize, 0, Math.PI * 2);
ctx.arc(rightEyeX, rightEyeY, eyeSize, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
// Pupils
ctx.fillStyle = COLORS.snakeEye;
let pupilOffsetX = 0, pupilOffsetY = 0;
if (dir === DIRS.RIGHT) pupilOffsetX = 1;
else if (dir === DIRS.LEFT) pupilOffsetX = -1;
else if (dir === DIRS.UP) pupilOffsetY = -1;
else pupilOffsetY = 1;
ctx.beginPath();
ctx.arc(leftEyeX + pupilOffsetX, leftEyeY + pupilOffsetY, eyeSize * 0.5, 0, Math.PI * 2);
ctx.arc(rightEyeX + pupilOffsetX, rightEyeY + pupilOffsetY, eyeSize * 0.5, 0, Math.PI * 2);
ctx.fill();
}
function render() {
// Clear
ctx.fillStyle = COLORS.bg;
ctx.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
// Grid
drawGrid();
// Game objects
drawFood();
drawSnake();
drawParticles();
}
// Game Loop
function gameLoop(timestamp) {
if (isGameOver || isPaused) return;
const deltaTime = timestamp - lastMoveTime;
if (deltaTime >= gameSpeed) {
if (!moveSnake()) return;
lastMoveTime = timestamp;
}
render();
updateParticles();
animationFrameId = requestAnimationFrame(gameLoop);
}
// Initialize
function init() {
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
canvas.focus();
showOverlay(startOverlay);
}
init();
</script>
</body>
</html>