← back to Model Arena

data/artifacts/04692f72ef1d/hf-qwen-coder-32b.html

190 lines

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tetris</title>
<style>
body{display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#000;}
canvas{border:1px solid #fff;}
#info{text-align:center;color:#fff;font-family:Arial,sans-serif;}
#score,#lines{font-size:2em;margin-bottom:10px;}
</style>
</head>
<body>
<canvas id="game" width="300" height="600"></canvas>
<div id="info">
  <div id="score">Score: 0</div>
  <div id="lines">Lines: 0</div>
</div>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const gridSize = 30;
const gridWidth = canvas.width / gridSize;
const gridHeight = canvas.height / gridSize;
let gameInterval, score = 0, linesCleared = 0, level = 1, paused = false;
const tetrominoes = [
  [[1,1,1,1]], // I
  [[1,1],[1,1]], // O
  [[0,1,0],[1,1,1]], // T
  [[1,0,0],[1,1,1]], // L
  [[0,0,1],[1,1,1]], // J
  [[1,1,0],[0,1,1]], // S
  [[0,1,1],[1,1,0]]  // Z
];
const colors = ['#FFA500', '#FFFF00', '#8A2BE2', '#00BFFF', '#00FF7F', '#FF4500', '#FF69B4'];
let grid = Array.from({length: gridHeight}, () => Array(gridWidth).fill(0));
let currentTetromino, nextTetromino, currentPosition = {x: Math.floor(gridWidth/2) - 1, y: 0};

function drawGrid() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (let row = 0; row < gridHeight; row++) {
    for (let col = 0; col < gridWidth; col++) {
      if (grid[row][col]) {
        ctx.fillStyle = colors[grid[row][col] - 1];
        ctx.fillRect(col * gridSize, row * gridSize, gridSize, gridSize);
        ctx.strokeStyle = '#000';
        ctx.strokeRect(col * gridSize, row * gridSize, gridSize, gridSize);
      }
    }
  }
}

function drawTetromino(tetromino, position) {
  tetromino.forEach((row, y) => {
    row.forEach((value, x) => {
      if (value) {
        ctx.fillStyle = colors[value - 1];
        ctx.fillRect((position.x + x) * gridSize, (position.y + y) * gridSize, gridSize, gridSize);
        ctx.strokeStyle = '#000';
        ctx.strokeRect((position.x + x) * gridSize, (position.y + y) * gridSize, gridSize, gridSize);
      }
    });
  });
}

function checkCollision(tetromino, position) {
  for (let row = 0; row < tetromino.length; row++) {
    for (let col = 0; col < tetromino[row].length; col++) {
      if (tetromino[row][col]) {
        const newX = position.x + col;
        const newY = position.y + row;
        if (newX < 0 || newX >= gridWidth || newY >= gridHeight || (newY >= 0 && grid[newY][newX])) {
          return true;
        }
      }
    }
  }
  return false;
}

function mergeTetromino(tetromino, position) {
  tetromino.forEach((row, y) => {
    row.forEach((value, x) => {
      if (value) {
        grid[position.y + y][position.x + x] = value;
      }
    });
  });
}

function clearLines() {
  let lines = 0;
  for (let row = gridHeight - 1; row >= 0; row--) {
    if (grid[row].every(cell => cell)) {
      grid.splice(row, 1);
      grid.unshift(Array(gridWidth).fill(0));
      lines++;
      row++; // Re-check the same row after clearing
    }
  }
  return lines;
}

function rotate(tetromino) {
  const newTetromino = [];
  for (let x = 0; x < tetromino[0].length; x++) {
    const newRow = [];
    for (let y = tetromino.length - 1; y >= 0; y--) {
      newRow.push(tetromino[y][x]);
    }
    newTetromino.push(newRow);
  }
  return newTetromino;
}

function spawnTetromino() {
  currentTetromino = nextTetromino || tetrominoes[Math.floor(Math.random() * tetrominoes.length)];
  currentPosition = {x: Math.floor(gridWidth/2) - Math.ceil(currentTetromino[0].length/2), y: 0};
  nextTetromino = tetrominoes[Math.floor(Math.random() * tetrominoes.length)];
}

function gameOver() {
  clearInterval(gameInterval);
  alert('Game Over! Score: ' + score);
  location.reload();
}

function updateScore(lines) {
  const points = [0, 40, 100, 300, 1200];
  linesCleared += lines;
  score += points[lines] * level;
  document.getElementById('score').innerText = 'Score: ' + score;
  document.getElementById('lines').innerText = 'Lines: ' + linesCleared;
}

function tick() {
  if (checkCollision(currentTetromino, {x: currentPosition.x, y: currentPosition.y + 1})) {
    mergeTetromino(currentTetromino, currentPosition);
    const lines = clearLines();
    updateScore(lines);
    spawnTetromino();
    if (checkCollision(currentTetromino, currentPosition)) {
      gameOver();
    }
  } else {
    currentPosition.y++;
  }
  drawGrid();
  drawTetromino(currentTetromino, currentPosition);
}

function startGame() {
  spawnTetromino();
  gameInterval = setInterval(tick, 1000 / level);
}

document.addEventListener('keydown', function(e) {
  if (paused) return;
  switch (e.key) {
    case 'ArrowLeft':
      if (!checkCollision(currentTetromino, {x: currentPosition.x - 1, y: currentPosition.y})) {
        currentPosition.x--;
      }
      break;
    case 'ArrowRight':
      if (!checkCollision(currentTetromino, {x: currentPosition.x + 1, y: currentPosition.y})) {
        currentPosition.x++;
      }
      break;
    case 'ArrowDown':
      tick();
      break;
    case 'ArrowUp':
      const rotated = rotate(currentTetromino);
      if (!checkCollision(rotated, currentPosition)) {
        currentTetromino = rotated;
      }
      break;
    case 'p':
      paused = !paused;
      clearInterval(gameInterval);
      if (!paused) gameInterval = setInterval(tick, 1000 / level);
      break;
  }
});

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