Qwen3-Coder (Tetris Challenge)

Das neue LLM Qwen3-Coder schlägt sich in meinem persönlichen Tetris Benchmark ganz gut. Mit folgendem Prompt und einem Request kommt ein spielbares Tetris Spiel raus. Voll funktionsfähig, wie man es von Tetris kennt. Etwa auf dem Level von o3-mini oder Deepseek R1.

Bitte schreibe in JavaScript und HTML ein Tetris Spiel. Die Steuerung soll über die Pfeiltasten erfolgen. Der Drop der Bricks erfolgt über Space Taste. Bitte baue noch einen Score für das Game mit ein. Der ganze code soll sich in einer HTML Datei befinden.

Tetris Qwen3-Coder
Tetris Qwen3-Coder

Das Ergebnis von ChatGPT o3-mini und DeepSeek R1 seht ihr hier:

Hier der Quellcode von Qwen3-Coder zum selber ausprobieren:

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tetris</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        
        .game-container {
            display: flex;
            gap: 20px;
        }
        
        #game-board {
            border: 2px solid #333;
            background-color: #111;
            box-shadow: 0 0 10px rgba(0,0,0,0.3);
        }
        
        .info-panel {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        
        #score-display {
            font-size: 24px;
            font-weight: bold;
            color: #333;
            background-color: white;
            padding: 15px;
            border-radius: 5px;
            box-shadow: 0 0 5px rgba(0,0,0,0.2);
        }
        
        .controls {
            background-color: white;
            padding: 15px;
            border-radius: 5px;
            box-shadow: 0 0 5px rgba(0,0,0,0.2);
        }
        
        .controls h3 {
            margin-top: 0;
            color: #333;
        }
        
        .controls ul {
            padding-left: 20px;
            margin: 10px 0;
        }
        
        .controls li {
            margin: 5px 0;
        }
        
        .key {
            display: inline-block;
            background-color: #ddd;
            border: 1px solid #999;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <canvas id="game-board" width="300" height="600"></canvas>
        <div class="info-panel">
            <div id="score-display">Punkte: 0</div>
            <div class="controls">
                <h3>Steuerung:</h3>
                <ul>
                    <li><span class="key">←</span> <span class="key">→</span> Bewegen</li>
                    <li><span class="key">↑</span> Drehen</li>
                    <li><span class="key">↓</span> Langsam fallen</li>
                    <li><span class="key">Leertaste</span> Sofort fallen</li>
                </ul>
            </div>
        </div>
    </div>

    <script>
        // Spielkonstanten
        const COLS = 10;
        const ROWS = 20;
        const BLOCK_SIZE = 30;
        const COLORS = [
            null,
            '#FF0D72', // I
            '#0DC2FF', // J
            '#0DFF72', // L
            '#F538FF', // O
            '#FF8E0D', // S
            '#FFE138', // T
            '#3877FF'  // Z
        ];

        // Tetromino-Formen
        const SHAPES = [
            [],
            [[0,0,0,0], [1,1,1,1], [0,0,0,0], [0,0,0,0]], // I
            [[2,0,0], [2,2,2], [0,0,0]],                   // J
            [[0,0,3], [3,3,3], [0,0,0]],                   // L
            [[4,4], [4,4]],                                // O
            [[0,5,5], [5,5,0], [0,0,0]],                   // S
            [[0,6,0], [6,6,6], [0,0,0]],                   // T
            [[7,7,0], [0,7,7], [0,0,0]]                    // Z
        ];

        // Spielvariablen
        let canvas = document.getElementById('game-board');
        let ctx = canvas.getContext('2d');
        let score = 0;
        let scoreElement = document.getElementById('score-display');
        let board = createMatrix(COLS, ROWS);
        let player = {
            pos: {x: 0, y: 0},
            matrix: null,
            score: 0
        };

        // Matrix erstellen
        function createMatrix(width, height) {
            const matrix = [];
            while (height--) {
                matrix.push(new Array(width).fill(0));
            }
            return matrix;
        }

        // Zufälliges Tetromino erstellen
        function createPiece() {
            const piece = Math.floor(Math.random() * 7) + 1;
            return SHAPES[piece];
        }

        // Spieler zurücksetzen
        function playerReset() {
            player.matrix = createPiece();
            player.pos.y = 0;
            player.pos.x = Math.floor(COLS / 2) - Math.floor(player.matrix[0].length / 2);
            
            // Spielende prüfen
            if (collide()) {
                board.forEach(row => row.fill(0));
                player.score = 0;
                updateScore();
            }
        }

        // Kollisionserkennung
        function collide() {
            const [m, o] = [player.matrix, player.pos];
            for (let y = 0; y < m.length; ++y) {
                for (let x = 0; x < m[y].length; ++x) {
                    if (m[y][x] !== 0 &&
                        (board[y + o.y] &&
                        board[y + o.y][x + o.x]) !== 0) {
                        return true;
                    }
                }
            }
            return false;
        }

        // Zeichnen
        function draw() {
            ctx.fillStyle = '#111';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            drawMatrix(board, {x: 0, y: 0});
            drawMatrix(player.matrix, player.pos);
        }

        // Matrix zeichnen
        function drawMatrix(matrix, offset) {
            matrix.forEach((row, y) => {
                row.forEach((value, x) => {
                    if (value !== 0) {
                        ctx.fillStyle = COLORS[value];
                        ctx.fillRect(x + offset.x, y + offset.y, 1, 1);
                        // Block zeichnen
                        ctx.fillStyle = COLORS[value];
                        ctx.fillRect((x + offset.x) * BLOCK_SIZE, (y + offset.y) * BLOCK_SIZE, 
                                   BLOCK_SIZE - 1, BLOCK_SIZE - 1);
                    }
                });
            });
        }

        // Zusammenführen
        function merge() {
            player.matrix.forEach((row, y) => {
                row.forEach((value, x) => {
                    if (value !== 0) {
                        board[y + player.pos.y][x + player.pos.x] = value;
                    }
                });
            });
        }

        // Spieler bewegen
        function playerMove(dir) {
            player.pos.x += dir;
            if (collide()) {
                player.pos.x -= dir;
            }
        }

        // Spieler drehen
        function playerRotate() {
            const pos = player.pos.x;
            let offset = 1;
            rotate(player.matrix);
            while (collide()) {
                player.pos.x += offset;
                offset = -(offset + (offset > 0 ? 1 : -1));
                if (offset > player.matrix[0].length) {
                    rotate(player.matrix);
                    player.pos.x = pos;
                    return;
                }
            }
        }

        // Matrix drehen
        function rotate(matrix) {
            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]];
                }
            }
            matrix.forEach(row => row.reverse());
        }

        // Spieler fallen lassen
        function playerDrop() {
            player.pos.y++;
            if (collide()) {
                player.pos.y--;
                merge();
                playerReset();
                sweepRows();
                updateScore();
            }
            dropCounter = 0;
        }

        // Sofortiges Fallen
        function playerHardDrop() {
            while (!collide()) {
                player.pos.y++;
            }
            player.pos.y--;
            playerDrop();
        }

        // Reihen löschen
        function sweepRows() {
            let rowCount = 0;
            outer: for (let y = board.length - 1; y >= 0; --y) {
                for (let x = 0; x < board[y].length; ++x) {
                    if (board[y][x] === 0) {
                        continue outer;
                    }
                }

                const row = board.splice(y, 1)[0].fill(0);
                board.unshift(row);
                ++y;
                rowCount++;
            }
            
            // Punkte für gelöschte Reihen
            if (rowCount > 0) {
                player.score += rowCount * 100 * rowCount; // Mehr Punkte für mehr Reihen
            }
        }

        // Punktestand aktualisieren
        function updateScore() {
            scoreElement.textContent = `Punkte: ${player.score}`;
        }

        // Spiel-Loop
        let dropCounter = 0;
        let dropInterval = 1000;
        let lastTime = 0;

        function update(time = 0) {
            const deltaTime = time - lastTime;
            lastTime = time;

            dropCounter += deltaTime;
            if (dropCounter > dropInterval) {
                playerDrop();
            }

            draw();
            requestAnimationFrame(update);
        }

        // Tastatureingaben
        document.addEventListener('keydown', event => {
            switch (event.keyCode) {
                case 37: // Pfeil links
                    playerMove(-1);
                    break;
                case 39: // Pfeil rechts
                    playerMove(1);
                    break;
                case 40: // Pfeil runter
                    playerDrop();
                    break;
                case 38: // Pfeil hoch
                    playerRotate();
                    break;
                case 32: // Leertaste
                    playerHardDrop();
                    break;
            }
        });

        // Spiel starten
        playerReset();
        updateScore();
        update();
    </script>
</body>
</html>
Nach oben scrollen