Models 44

Nemotron 3 Super

by NVIDIAreasoning defaultClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
35.1 s
Cost
$0.0023
Output tokens
5,668
Spent thinking
1,695 tokens
Speed
165.2 tok/s
Console errors
0
First token after
775 ms
First visible text after
16.6 s
Prompt tokens
531
Code size
12.6 KB
Finish reason
stop
Served by
DeepInfra
Model id
nvidia/nemotron-3-super-120b-a12b
Reasoning sent
model default
Max output
16,384 tokens
Generated
Nov 13, 2026

What it was asked

The prompt
Build a polished Breakout (brick breaker) game in a single HTML file using vanilla JavaScript and a <canvas>. Requirements: - A paddle controlled with the mouse and with the left/right arrow keys. - The bounce angle off the paddle depends on where the ball hits it (center = straight up, edges = sharp angle). - One level with at least 6 rows of bricks, mixing normal bricks and tougher bricks that need 2 hits and visibly crack after the first one. - Some bricks visibly carry a power-up icon; when broken they drop it, and catching it with the paddle gives either a wider paddle (10 seconds) or multi-ball (3 balls). - The ball must never pass through bricks or the paddle. - Particles when a brick breaks. - 3 lives, score displayed. Game over and victory screens with a restart option.
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 · 436 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Breakout</title>
<style>
  body{margin:0;display:flex;justify-content:center;align-items:center;height:100vh;background:#111;color:#fff;font-family:sans-serif;}
  canvas{background:#000;display:block;}
  #overlay{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;background:rgba(0,0,0,0.7);color:#fff;font-size:2rem;pointer-events:none;}
  #overlay button{margin-top:1rem;padding:0.5rem 1rem;font-size:1rem;cursor:pointer;}
</style>
</head>
<body>
<canvas id="game"></canvas>
<div id="overlay">
  <div>Click or press a key to start</div>
  <button id="startBtn">Start</button>
</div>
<script>
(() => {
  const canvas = document.getElementById('game');
  const ctx = canvas.getContext('2d');
  const WIDTH = 800;
  const HEIGHT = 600;
  canvas.width = WIDTH;
  canvas.height = HEIGHT;

  // Paddle
  const paddle = {
    x: WIDTH / 2 - 50,
    y: HEIGHT - 30,
    w: 100,
    h: 20,
    speed: 8,
    dx: 0,
    originalW: 100,
    widenTimer: 0
  };

  // Ball prototype
  function createBall() {
    return {
      x: WIDTH / 2,
      y: HEIGHT - 50,
      r: 8,
      dx: 4 * (Math.random() > 0.5 ? 1 : -1),
      dy: -4,
      speed: Math.sqrt(16 + 16) // constant speed magnitude
    };
  }
  const balls = [createBall()];

  // Bricks
  const brickInfo = {
    rows: 6,
    cols: 10,
    padding: 10,
    offsetX: 45,
    offsetY: 60,
    w: 0,
    h: 20
  };
  brickInfo.w = (WIDTH - 2 * brickInfo.offsetX - (brickInfo.cols - 1) * brickInfo.padding) / brickInfo.cols;
  let bricks = [];
  function createBricks() {
    bricks = [];
    for (let r = 0; r < brickInfo.rows; r++) {
      bricks[r] = [];
      for (let c = 0; c < brickInfo.cols; c++) {
        const hits = Math.random() < 0.2 ? 2 : 1; // 20% tough bricks
        const hasPower = Math.random() < 0.15; // 15% carry power-up
        const powerType = hasPower ? (Math.random() < 0.5 ? 'widen' : 'multi') : null;
        bricks[r][c] = {
          x: brickInfo.offsetX + c * (brickInfo.w + brickInfo.padding),
          y: brickInfo.offsetY + r * (brickInfo.h + brickInfo.padding),
          w: brickInfo.w,
          h: brickInfo.h,
          hits,
          maxHits: hits,
          hasPower,
          powerType,
          broken: false
        };
      }
    }
  }
  createBricks();

  // Power-ups
  const powerUps = [];

  // Particles
  const particles = [];

  let score = 0;
  let lives = 3;
  let started = false;
  let demoMode = true; // AI plays until user starts
  let gameState = 'playing'; // playing, over, win
  const maxPaddleAngle = Math.PI / 3; // 60 degrees

  // Input
  let mouseX = paddle.x;
  const keys = { ArrowLeft: false, ArrowRight: false };

  canvas.addEventListener('mousemove', e => {
    const rect = canvas.getBoundingClientRect();
    mouseX = e.clientX - rect.left - paddle.w / 2;
  });
  window.addEventListener('keydown', e => {
    if (e.key === 'ArrowLeft') keys.ArrowLeft = true;
    if (e.key === 'ArrowRight') keys.ArrowRight = true;
    if (!started) startGame();
  });
  window.addEventListener('keyup', e => {
    if (e.key === 'ArrowLeft') keys.ArrowLeft = false;
    if (e.key === 'ArrowRight') keys.ArrowRight = false;
  });
  document.getElementById('startBtn').addEventListener('click', startGame);

  function startGame() {
    started = true;
    demoMode = false;
    document.getElementById('overlay').style.display = 'none';
  }

  // Game logic
  function update() {
    if (gameState !== 'playing') return;

    // Demo mode AI
    if (!started && demoMode) {
      const target = balls[0].x - paddle.w / 2;
      paddle.x += (target - paddle.x) * 0.1;
      paddle.x = Math.max(0, Math.min(WIDTH - paddle.w, paddle.x));
    } else {
      // User control
      if (keys.ArrowLeft) paddle.x -= paddle.speed;
      if (keys.ArrowRight) paddle.x += paddle.speed;
      // Mouse control (clamp)
      if (started) {
        paddle.x = mouseX;
      }
      paddle.x = Math.max(0, Math.min(WIDTH - paddle.w, paddle.x));
    }

    // Widen power-up timer
    if (paddle.widenTimer > 0) {
      paddle.widenTimer -= 16; // approx ms per frame
      if (paddle.widenTimer <= 0) paddle.w = paddle.originalW;
    }

    // Update balls
    for (let i = balls.length - 1; i >= 0; i--) {
      const b = balls[i];
      b.x += b.dx;
      b.y += b.dy;

      // Wall collision
      if (b.x - b.r < 0 || b.x + b.r > WIDTH) {
        b.dx = -b.dx;
        b.x = Math.max(b.r, Math.min(WIDTH - b.r, b.x));
      }
      if (b.y - b.r < 0) {
        b.dy = -b.dy;
        b.y = b.r;
      }

      // Paddle collision
      if (
        b.y + b.r >= paddle.y &&
        b.y - b.r <= paddle.y + paddle.h &&
        b.x >= paddle.x &&
        b.x <= paddle.x + paddle.w
      ) {
        const relative = (b.x - (paddle.x + paddle.w / 2)) / (paddle.w / 2); // -1 to 1
        const angle = relative * maxPaddleAngle; // -maxAngle to +maxAngle
        const speed = Math.hypot(b.dx, b.dy);
        b.dx = Math.sin(angle) * speed;
        b.dy = -Math.cos(angle) * speed; // ensure upward
        // push ball above paddle to avoid sticking
        b.y = paddle.y - b.r;
      }

      // Brick collision
      brickLoop: for (let r = 0; r < brickInfo.rows; r++) {
        for (let c = 0; c < brickInfo.cols; c++) {
          const brick = bricks[r][c];
          if (!brick || brick.broken) continue;
          if (
            b.x + b.r > brick.x &&
            b.x - b.r < brick.x + brick.w &&
            b.y + b.r > brick.y &&
            b.y - b.r < brick.y + brick.h
          ) {
            // Determine collision side
            const deltaX = Math.abs(b.x - (brick.x + brick.w / 2)) - brick.w / 2;
            const deltaY = Math.abs(b.y - (brick.y + brick.h / 2)) - brick.h / 2;
            if (deltaX > deltaY) {
              // hit side
              b.dx = -b.dx;
              b.x += b.dx; // nudge out
            } else {
              // hit top/bottom
              b.dy = -b.dy;
              b.y += b.dy;
            }
            // Damage brick
            brick.hits--;
            if (brick.hits <= 0) {
              brick.broken = true;
              score += brick.maxHits === 1 ? 10 : 20;
              // particles
              for (let p = 0; p < 8; p++) {
                particles.push({
                  x: brick.x + brick.w / 2,
                  y: brick.y + brick.h / 2,
                  vx: (Math.random() - 0.5) * 4,
                  vy: (Math.random() - 0.5) * 4,
                  life: 30,
                  size: 2 + Math.random() * 3,
                  color: brick.maxHits === 1 ? '#ff0' : '#f90'
                });
              }
              // power-up drop
              if (brick.hasPower) {
                powerUps.push({
                  x: brick.x + brick.w / 2 - 10,
                  y: brick.y,
                  w: 20,
                  h: 20,
                  vy: 2,
                  type: brick.powerType
                });
              }
            } else {
              // first hit on tough brick -> visual change handled in draw
            }
            break brickLoop;
          }
        }
      }

      // Ball out bottom
      if (b.y - b.r > HEIGHT) {
        balls.splice(i, 1);
        if (balls.length === 0) {
          lives--;
          if (lives <= 0) {
            gameState = 'over';
          } else {
            balls.push(createBall());
          }
        }
      }
    }

    // Update power-ups
    for (let i = powerUps.length - 1; i >= 0; i--) {
      const pu = powerUps[i];
      pu.y += pu.vy;
      // paddle collision
      if (
        pu.y + pu.h >= paddle.y &&
        pu.y <= paddle.y + paddle.h &&
        pu.x + pu.w >= paddle.x &&
        pu.x <= paddle.x + paddle.w
      ) {
        if (pu.type === 'widen') {
          paddle.w = paddle.originalW * 1.5;
          paddle.widenTimer = 10000; // 10 seconds
        } else if (pu.type === 'multi') {
          // add two extra balls
          for (let j = 0; j < 2; j++) {
            const nb = createBall();
            nb.x = balls[0].x;
            nb.y = balls[0].y;
            // slight angle variation
            const angle = (Math.random() - 0.5) * Math.PI / 4;
            const speed = Math.hypot(nb.dx, nb.dy);
            nb.dx = Math.sin(angle) * speed + (Math.random() - 0.5) * 0.5;
            nb.dy = -Math.cos(angle) * speed;
            balls.push(nb);
          }
        }
        powerUps.splice(i, 1);
        continue;
      }
      if (pu.y > HEIGHT) powerUps.splice(i, 1);
    }

    // Update particles
    for (let i = particles.length - 1; i >= 0; i--) {
      const p = particles[i];
      p.x += p.vx;
      p.y += p.vy;
      p.life--;
      if (p.life <= 0) particles.splice(i, 1);
    }

    // Win condition
    const anyBricks = bricks.some(row => row.some(b => !b.broken));
    if (!anyBricks) gameState = 'win';
  }

  // Rendering
  function draw() {
    ctx.clearRect(0, 0, WIDTH, HEIGHT);
    // Paddle
    ctx.fillStyle = '#0f0';
    ctx.fillRect(paddle.x, paddle.y, paddle.w, paddle.h);
    // Balls
    ctx.fillStyle = '#fff';
    for (const b of balls) {
      ctx.beginPath();
      ctx.arc(b.x, b.y, b.r, 0, Math.PI * 2);
      ctx.fill();
    }
    // Bricks
    for (const row of bricks) {
      for (const brick of row) {
        if (brick.broken) continue;
        if (brick.maxHits === 2 && brick.hits === 1) {
          ctx.fillStyle = '#ff9900'; // cracked
        } else if (brick.maxHits === 1) {
          ctx.fillStyle = '#f00';
        } else {
          ctx.fillStyle = '#ff0';
        }
        ctx.fillRect(brick.x, brick.y, brick.w, brick.h);
        // power-up icon
        if (brick.hasPower && !brick.broken) {
          ctx.fillStyle = '#fff';
          ctx.font = '16px sans-serif';
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          const ch = brick.powerType === 'widen' ? 'W' : 'M';
          ctx.fillText(ch, brick.x + brick.w / 2, brick.y + brick.h / 2);
        }
      }
    }
    // Power-ups
    ctx.fillStyle = '#0ff';
    for (const pu of powerUps) {
      ctx.beginPath();
      ctx.arc(pu.x + pu.w / 2, pu.y + pu.h / 2, pu.w / 2, 0, Math.PI * 2);
      ctx.fill();
      ctx.fillStyle = '#fff';
      ctx.font = '14px sans-serif';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(pu.type === 'widen' ? 'W' : 'M', pu.x + pu.w / 2, pu.y + pu.h / 2);
      ctx.fillStyle = '#0ff';
    }
    // Particles
    for (const p of particles) {
      ctx.fillStyle = p.color;
      ctx.beginPath();
      ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
      ctx.fill();
    }
    // Info
    ctx.fillStyle = '#fff';
    ctx.font = '20px sans-serif';
    ctx.textAlign = 'left';
    ctx.fillText(`Score: ${score}`, 20, 30);
    ctx.fillText(`Lives: ${lives}`, 20, 60);
    // Overlays
    if (gameState === 'over') {
      ctx.fillStyle = 'rgba(0,0,0,0.7)';
      ctx.fillRect(0, 0, WIDTH, HEIGHT);
      ctx.fillStyle = '#fff';
      ctx.textAlign = 'center';
      ctx.font = '40px sans-serif';
      ctx.fillText('Game Over', WIDTH / 2, HEIGHT / 2 - 20);
      ctx.font = '20px sans-serif';
      ctx.fillText('Click or press any key to restart', WIDTH / 2, HEIGHT / 2 + 20);
    } else if (gameState === 'win') {
      ctx.fillStyle = 'rgba(0,0,0,0.7)';
      ctx.fillRect(0, 0, WIDTH, HEIGHT);
      ctx.fillStyle = '#0f0';
      ctx.textAlign = 'center';
      ctx.font = '40px sans-serif';
      ctx.fillText('You Win!', WIDTH / 2, HEIGHT / 2 - 20);
      ctx.font = '20px sans-serif';
      ctx.fillText('Click or press any key to restart', WIDTH / 2, HEIGHT / 2 + 20);
    }
    // Start message overlay (if not started)
    if (!started) {
      ctx.fillStyle = 'rgba(0,0,0,0.6)';
      ctx.fillRect(0, 0, WIDTH, HEIGHT);
      ctx.fillStyle = '#fff';
      ctx.textAlign = 'center';
      ctx.font = '30px sans-serif';
      ctx.fillText('Click or press a key to start', WIDTH / 2, HEIGHT / 2);
    }
  }

  function reset() {
    paddle.x = WIDTH / 2 - paddle.w / 2;
    paddle.w = paddle.originalW;
    paddle.widenTimer = 0;
    balls.length = 0;
    balls.push(createBall());
    createBricks();
    powerUps.length = 0;
    particles.length = 0;
    score = 0;
    lives = 3;
    started = false;
    demoMode = true;
    gameState = 'playing';
  }

  function loop() {
    update();
    draw();
    requestAnimationFrame(loop);
  }

  // Start button also resets if game over/win
  document.getElementById('startBtn').addEventListener('click', () => {
    if (gameState === 'over' || gameState === 'win') reset();
    else startGame();
  });
  window.addEventListener('keydown', e => {
    if (gameState === 'over' || gameState === 'win') reset();
  });

  reset();
  loop();
})();
</script>
</body>
</html>
</html>
Reasoning trace (1,695 tokens)
We need to produce a single HTML file containing Breakout game with all features. Must be inline CSS and JS, no external resources except allowed CDN URLs? Not needed. Use canvas.

Implementation plan:

- Canvas width maybe 800x600.
- Paddle: width variable (default 100, power-up gives 150). Height 20. Controlled by mouse movement (x) and left/right arrow keys (maybe accelerate).
- Ball: radius 8. Starting speed maybe 4 dx, -4 dy. Bounce off paddle: angle depends on relative hit position: offset = (ball.x - paddle.x - paddle.width/2) / (paddle.width/2). Then set dx = offset * maxAngleSpeed (maybe 5), dy = -Math.sqrt(speed^2 - dx^2) (ensuring upward). Ensure speed constant.

- Bricks: define rows=6, cols=10 maybe. Brick width = canvas.width/cols - padding. Height = 20. Some bricks normal (1 hit), some tough (2 hits) and show crack after first hit (maybe change color or draw cracks). Also some bricks carry power-up icon: assign randomly (maybe 20% chance) and store type (paddle widen or multi-ball). When brick breaks (hits to zero), spawn power-up falling down at some speed.

- Power-up: represented as falling rectangle or icon (maybe simple shape + letter). When paddle intersects, apply effect: for widen: increase paddle width for 10 seconds; for multi-ball: spawn 2 additional balls (total 3). Multi-ball: maintain list of balls; each ball independent but share same speed magnitude? We can just push new ball objects with same speed but random slight angle.

- Particles: when brick breaks, create few particles (e.g., 8) with random velocity and fade.

- Lives: 3. When ball falls below paddle (y > canvas.height) lose a life, reset ball(s?) For multi-ball, if any ball remains? Probably if all balls lost then lose a life and reset to one ball. Simpler: on each ball that goes out, remove it; if balls array empty, lose life and reset paddle position, create new ball.

- Game over when lives==0; victory when all bricks cleared.

- Display score, lives.

- Controls: mouse movement updates paddle target x; also left/right arrow keys to move paddle left/right by some speed.

- Start screen: show message "Click or press a key to start". On start hide message and begin game loop; also allow self-playing demo? The requirement: 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. So we need a demo mode where if not started, the AI moves paddle automatically to follow ball. When user clicks or presses key, we switch to user control. We'll implement a flag started = false; demoMode = true initially. In update, if !started, we move paddle towards ball's x (AI). Show message overlay.

- After start, we accept user input.

- Must be visible on first paint: we can draw initial state.

- Ensure no horizontal scrollbar: set canvas width/height and body margin 0; display flex center.

Implementation details:

HTML:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Breakout</title>
<style>
  body{margin:0;display:flex;justify-content:center;align-items:center;height:100vh;background:#111;color:#fff;font-family:sans-serif;}
  canvas{background:#000;display:block;}
  #overlay{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;background:rgba(0,0,0,0.7);color:#fff;font-size:2rem;pointer-events:none;}
  #overlay button{margin-top:1rem;padding:0.5rem 1rem;font-size:1rem;}
</style>
</head>
<body>
<canvas id="game"></canvas>
<div id="overlay">
  <div>Click or press a key to start</div>
  <button id="startBtn">Start</button>
</div>
<script>
```

Then JS.

We'll need variables: canvas, ctx; paddle object; balls array; bricks 2D array; powerUps array; particles array; score, lives; gameState: 'playing', 'over', 'win'; started flag; demoMode.

Initialize: createBricks() function.

Draw functions: drawPaddle, drawBall, drawBricks, drawPowerUps, drawParticles, drawInfo.

Update loop: requestAnimationFrame.

Input handling: mousemove to set paddle target x (clamp). keydown for left/right to adjust paddle velocity; also start on keydown if not started.

Start handling: clicking start button or pressing any key when not started: set started=true; hide overlay; also disable demo mode.

Demo mode: if !started, we move paddle.x towards ball.x (maybe with some lag). We'll also maybe have AI that tracks ball.

Collision detection: ball vs bricks: iterate bricks; if brick.hits>0 and ball collides (AABB), then reduce brick.hits; if hits==0 => destroy brick: add score, maybe spawn power-up if brick.hasPowerUp; create particles; set brick to null or mark destroyed.

Ball vs paddle: if ball collides with paddle (y+radius >= paddle.y && y <= paddle.y+paddle.height && x between paddle.x and paddle.x+paddle.width): compute bounce angle.

Ball vs walls: left/right/top.

Ball out bottom: remove ball from array; if balls empty => lose life, reset.

Power-up update: fall down; if collides with paddle => apply effect; remove power-up; if passes bottom => remove.

Particles update: decrease life, move, fade.

Game over/win: show overlay with message and restart button.

Restart: reset all variables.

Now implement details.

Let's code.

Potential issues: ensure ball never passes through bricks/paddle: we need to resolve collision properly: after detecting collision, adjust ball position to be outside.

Simplify: on collision, reverse velocity component appropriately (for bricks: reverse dy if hitting top/bottom, else reverse dx). Since bricks are axis-aligned and ball small, we can check which side.

Simpler: when collision, we just invert dy (if ball.y < brick.y) else invert dx; and reposition ball to avoid sticking.

But requirement: bounce angle off paddle depends on where hits it. For bricks we can keep simple vertical reversal.

Implement Brick object: {x,y,width,height,hits,maxHits,hasPowerUp,powerType}. For normal bricks hits=1,maxHits=1; tough bricks hits=2,maxHits=2; after first hit we change color to lighter or draw cracks.

We can store a cracked state: after hits==1 (original maxHits=2) we show different color.

Power-up icon: maybe just draw a letter inside brick: 'W' for widen, 'M' for multi-ball.

When brick destroyed, spawn power-up object: {x: brick.x+brick.width/2, y: brick.y, width:20, height:20, vy:2, type: brick.powerType}. Draw as a circle with letter.

Paddle widening effect: store original width, apply multiplier for duration using timer.

Multi-ball: when power-up caught, add two new balls with same speed but slight angle variation.

Implementation details for multi-ball: we push new ball objects into balls array; each ball has its own dx,dy.

When lose a life and balls empty, we reset to one ball.

Now code.

Let's write the script.