← back to Model Arena

data/artifacts/04692f72ef1d/qwen3-14b.html

267 lines

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Tetris</title>
  <style>
    body {
      background: #000;
      color: #fff;
      font-family: sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
      margin: 0;
    }
    canvas {
      border: 2px solid #fff;
      background: #111;
    }
    #info {
      margin-top: 10px;
      font-size: 16px;
    }
    #next {
      margin-top: 10px;
      font-size: 14px;
      white-space: pre;
    }
  </style>
</head>
<body>
  <canvas id="tetris" width="240" height="400"></canvas>
  <div id="info">Score: 0 | Level: 1</div>
  <div id="next">Next:</div>
  <script>
    const canvas = document.getElementById("tetris");
    const context = canvas.getContext("2d");
    const scale = 20;
    const rows = canvas.height / scale;
    const columns = canvas.width / scale;
    const scoreDisplay = document.getElementById("info");
    const nextDisplay = document.getElementById("next");

    const colors = [
      null,
      "#FF0D72",
      "#0DC2FF",
      "#0DFF72",
      "#F538FF",
      "#FF8E0D",
      "#FFE138",
      "#3877FF",
    ];

    const tetrominoes = [
      [ [1,1,1,1] ], // I
      [ [1,1,1], [0,1,0] ], // T
      [ [1,1,0], [0,1,1] ], // S
      [ [0,1,1], [1,1,0] ], // Z
      [ [1,1,1], [1,0,0] ], // J
      [ [1,1,1], [0,0,1] ], // L
      [ [1,0,0], [1,1,1] ], // O
    ];

    let score = 0;
    let level = 1;
    let dropCounter = 0;
    let dropInterval = 1000;
    let lastTime = 0;
    let gameOver = false;
    let pause = false;

    let playingField = createMatrix(columns, rows);
    let currentPiece = createPiece(randomPiece());
    let nextPiece = createPiece(randomPiece());
    let piecePosition = { x: 0, y: 0 };

    function createMatrix(w, h) {
      const matrix = [];
      while (h--) {
        matrix.push(new Array(w).fill(0));
      }
      return matrix;
    }

    function createPiece(type) {
      if (!tetrominoes[type]) return;
      return tetrominoes[type].map(row => row.slice().map(col => col ? colors[type] : 0));
    }

    function randomPiece() {
      return Math.floor(Math.random() * tetrominoes.length);
    }

    function drawMatrix(matrix, offset) {
      matrix.forEach((row, y) => {
        row.forEach((value, x) => {
          if (value !== 0) {
            context.fillStyle = value;
            context.fillRect((x + offset.x) * scale, (y + offset.y) * scale, scale, scale);
          }
        });
      });
    }

    function draw() {
      context.fillStyle = "#000";
      context.fillRect(0, 0, canvas.width, canvas.height);
      drawMatrix(playingField, { x: 0, y: 0 });
      drawMatrix(currentPiece, piecePosition);
      drawNextPiece();
    }

    function merge(playingField, piece, offset) {
      piece.forEach((row, y) => {
        row.forEach((value, x) => {
          if (value !== 0) {
            playingField[y + offset.y][x + offset.x] = value;
          }
        });
      });
    }

    function collide(playingField, piece, offset) {
      for (let y = 0; y < piece.length; y++) {
        for (let x = 0; x < piece[y].length; x++) {
          if (piece[y][x] !== 0 &&
              (playingField[y + offset.y] &&
               playingField[y + offset.y][x + offset.x]) !== 0) {
            return true;
          }
        }
      }
      return false;
    }

    function rotate(matrix, dir) {
      for (let y = 0; y < matrix.length; y++) {
        for (let x = 0; x < y; x++) {
          [matrix[x][y], matrix[y][x]] = [matrix[y][x], matrix[x][y]];
        }
      }
      if (dir > 0) {
        matrix.forEach(row => row.reverse());
      } else {
        matrix.reverse();
      }
    }

    function playerDrop() {
      piecePosition.y++;
      if (collide(playingField, currentPiece, piecePosition)) {
        piecePosition.y--;
        merge(playingField, currentPiece, piecePosition);
        currentPiece = nextPiece;
        nextPiece = createPiece(randomPiece());
        piecePosition = { x: 0, y: 0 };
        if (collide(playingField, currentPiece, piecePosition)) {
          gameOver = true;
        }
        clearRows();
      }
    }

    function clearRows() {
      let rowsCleared = 1;
      outer: for (let y = playingField.length - 1; y > 0; y--) {
        if (playingField[y].every(cell => cell !== 0)) {
          rowsCleared++;
          for (let yy = y; yy > 0; yy--) {
            playingField[yy] = playingField[yy - 1].slice();
          }
          y++;
        } else {
          break outer;
        }
      }
      if (rowsCleared > 1) {
        score += rowsCleared * 100 * level;
        level = Math.floor(score / 1000) + 1;
        dropInterval = 1000 - (level * 50);
      }
      updateScore();
    }

    function updateScore() {
      scoreDisplay.textContent = `Score: ${score} | Level: ${level}`;
    }

    function drawNextPiece() {
      nextDisplay.textContent = "Next:\n";
      nextPiece.forEach(row => {
        nextDisplay.textContent += row.map(cell => cell ? "■" : " ").join(" ") + "\n";
      });
    }

    function playerMove(dir) {
      piecePosition.x += dir;
      if (collide(playingField, currentPiece, piecePosition)) {
        piecePosition.x -= dir;
      }
    }

    function playerRotate(dir) {
      const prevRotation = currentPiece;
      rotate(currentPiece, dir);
      if (collide(playingField, currentPiece, piecePosition)) {
        currentPiece = prevRotation;
      }
    }

    function update(time = 0) {
      const deltaTime = time - lastTime;
      lastTime = time;
      dropCounter += deltaTime;
      if (dropCounter > dropInterval && !gameOver && !pause) {
        playerDrop();
        dropCounter = 0;
      }
      draw();
      if (!gameOver) {
        requestAnimationFrame(update);
      }
    }

    function resetGame() {
      playingField = createMatrix(columns, rows);
      score = 0;
      level = 1;
      dropInterval = 1000;
      gameOver = false;
      pause = false;
      currentPiece = createPiece(randomPiece());
      nextPiece = createPiece(randomPiece());
      piecePosition = { x: 0, y: 0 };
      updateScore();
      update();
    }

    document.addEventListener("keydown", event => {
      if (gameOver) {
        if (event.key === "Enter") {
          resetGame();
        }
        return;
      }
      if (event.key === "ArrowLeft") {
        playerMove(-1);
      } else if (event.key === "ArrowRight") {
        playerMove(1);
      } else if (event.key === "ArrowDown") {
        playerDrop();
      } else if (event.key === "ArrowUp") {
        playerRotate(1);
      } else if (event.key === " ") {
        playerDrop();
      } else if (event.key === "Escape") {
        pause = !pause;
      }
    });

    update();
  </script>
</body>
</html>