tetlis.html
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #1e1e1e;
    flex-direction: column;
}
canvas {
    border: 1px solid #fff;
}
#gameOverMessage {
    display: none;
    color: white;
    font-size: 24px;
    text-align: center;
    margin-top: 20px;
}
// テトリスの基本的な要素
const canvas = document.getElementById(“gameCanvas”);
const ctx = canvas.getContext(“2d”);
const gameOverMessage = document.getElementById(“gameOverMessage”);
// 定義
const rows = 20;
const cols = 10;
const blockSize = 30;
const colors = [“#FF5733”, “#33FF57”, “#3357FF”, “#FF33F6”, “#F7FF33”, “#33FFF7”, “#F733FF”];
let board, tetromino, gameInterval, gameOver;
// テトリミノの形
const shapes = [[[1, 1, 1, 1]], // I[[1, 1], [1, 1]], // O[[0, 1, 1], [1, 1, 0]], // S[[1, 1, 0], [0, 1, 1]], // Z[[1, 0, 0], [1, 1, 1]], // L[[0, 0, 1], [1, 1, 1]], // J[[0, 1, 0], [1, 1, 1]] // T
];
function initializeGame() {
    board = Array.from({ length: rows }, () => Array(cols).fill(0));
    gameOver = false;
    gameOverMessage.style.display = “none”;
    spawnTetromino();
    if (gameInterval) clearInterval(gameInterval);
    gameInterval = setInterval(update, 500);
}
function drawBoard() {
    for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
            if (board[r][c] !== 0) {
                ctx.fillStyle = colors[board[r][c] – 1];
                ctx.fillRect(c * blockSize, r * blockSize, blockSize, blockSize);
                ctx.strokeStyle = "#333";
                ctx.strokeRect(c * blockSize, r * blockSize, blockSize, blockSize);
            }
        }
    }
}
function drawTetromino() {
    for (let r = 0; r < tetromino.shape.length; r++) {
        for (let c = 0; c < tetromino.shape[r].length; c++) {
            if (tetromino.shape[r][c] !== 0) {
                ctx.fillStyle = colors[tetromino.color];
                ctx.fillRect((tetromino.x + c) * blockSize, (tetromino.y + r) * blockSize, blockSize, blockSize);
                ctx.strokeStyle = "#333";
                ctx.strokeRect((tetromino.x + c) * blockSize, (tetromino.y + r) * blockSize, blockSize, blockSize);
            }
        }
    }
}
function rotateTetromino() {
    const newShape = [];
    for (let r = 0; r < tetromino.shape[0].length; r++) {
        newShape[r] = [];
        for (let c = 0; c < tetromino.shape.length; c++) {
            newShape[r][c] = tetromino.shape[tetromino.shape.length – 1 – c][r];
        }
    }
    if (!collides(newShape, tetromino.x, tetromino.y)) {
        tetromino.shape = newShape;
    }
}
function collides(shape, xOffset, yOffset) {
    for (let r = 0; r < shape.length; r++) {
        for (let c = 0; c < shape[r].length; c++) {
            if (shape[r][c] !== 0) {
                const x = xOffset + c;
                const y = yOffset + r;
                if (x = cols || y >= rows || (board[y] && board[y][x] !== 0)) {
                    return true;
                }
            }
        }
    }
    return false;
}
function placeTetromino() {
    for (let r = 0; r < tetromino.shape.length; r++) {
        for (let c = 0; c < tetromino.shape[r].length; c++) {
            if (tetromino.shape[r][c] !== 0) {
                board[tetromino.y + r][tetromino.x + c] = tetromino.color + 1;
            }
        }
    }
    clearFullLines();
    spawnTetromino();
}
function clearFullLines() {
    for (let r = 0; r  cell !== 0)) {
            board.splice(r, 1);
            board.unshift(Array(cols).fill(0));
        }
    }
}
function spawnTetromino() {
    const shapeIndex = Math.floor(Math.random() * shapes.length);
    tetromino = {
        shape: shapes[shapeIndex],
        x: Math.floor(cols / 2) – Math.floor(shapes[shapeIndex][0].length / 2),
        y: 0,
        color: shapeIndex
    };
    if (collides(tetromino.shape, tetromino.x, tetromino.y)) {
        gameOver = true;
        clearInterval(gameInterval);
        gameOverMessage.style.display = “block”;
    }
}
function moveTetrominoDown() {
    if (!gameOver && !collides(tetromino.shape, tetromino.x, tetromino.y + 1)) {
        tetromino.y++;
    } else {
        placeTetromino();
    }
}
function moveTetrominoLeft() {
    if (!collides(tetromino.shape, tetromino.x – 1, tetromino.y)) {
        tetromino.x–;
    }
}
function moveTetrominoRight() {
    if (!collides(tetromino.shape, tetromino.x + 1, tetromino.y)) {
        tetromino.x++;
    }
}
function update() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBoard();
    drawTetromino();
    if (!gameOver) {
        moveTetrominoDown();
    }
}
function restartGame() {
    initializeGame();
}
initializeGame();
document.addEventListener(“keydown”, function(event) {
    if (event.key === “ArrowLeft”) moveTetrominoLeft();
    if (event.key === “ArrowRight”) moveTetrominoRight();
    if (event.key === “ArrowDown”) moveTetrominoDown();
    if (event.key === “ArrowUp”) rotateTetromino();
    if (event.key === “Enter” && gameOver) restartGame();
});


