← 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>