AI Code Test

Subway Surfers (with cars)

Review the original prompt, inspect the generated code, and compare how different AI models handled the same coding task.

Back to All Tests

Subway Surfers (with cars)

Gemini Flash 3.5 (Standard)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Curve Rider 3D</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #050510;
            user-select: none;
        }

        #canvas-container {
            width: 100vw;
            height: 100vh;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
        }

        /* UI Overlays */
        .ui-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 10;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            color: white;
            text-shadow: 0 4px 8px rgba(0,0,0,0.7);
            transition: opacity 0.3s ease;
        }

        .hidden {
            opacity: 0;
            pointer-events: none;
            display: none !important;
        }

        /* Screen Stylings */
        #menu-screen {
            background: linear-gradient(to bottom, rgba(5, 5, 20, 0.45), rgba(15, 10, 35, 0.85));
        }

        #gameover-screen {
            background: rgba(15, 0, 0, 0.75);
            backdrop-filter: blur(4px);
        }

        #hud {
            position: absolute;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 5;
            display: flex;
            gap: 40px;
            font-size: 24px;
            font-weight: bold;
            letter-spacing: 2px;
            background: rgba(0, 0, 0, 0.4);
            padding: 10px 30px;
            border-radius: 30px;
            border: 1px solid rgba(255, 255, 255, 0.1);
            pointer-events: none;
        }

        /* Typography & Buttons */
        h1 {
            font-size: 64px;
            margin-bottom: 10px;
            letter-spacing: 6px;
            text-transform: uppercase;
            background: linear-gradient(45deg, #ff007f, #00f0ff);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            filter: drop-shadow(0 2px 10px rgba(0,240,255,0.3));
        }

        p {
            font-size: 18px;
            margin-bottom: 30px;
            color: #ccc;
        }

        .btn {
            padding: 15px 40px;
            font-size: 20px;
            font-weight: bold;
            text-transform: uppercase;
            letter-spacing: 2px;
            color: white;
            background: linear-gradient(90deg, #ff0055, #9900ff);
            border: none;
            border-radius: 5px;
            cursor: pointer;
            box-shadow: 0 5px 15px rgba(255, 0, 85, 0.4);
            transition: transform 0.1s, box-shadow 0.2s;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(255, 0, 85, 0.6);
        }

        .btn:active {
            transform: translateY(1px);
        }

        .controls-hint {
            margin-top: 40px;
            font-size: 14px;
            color: #888;
            background: rgba(0,0,0,0.3);
            padding: 10px 20px;
            border-radius: 5px;
        }
    </style>

    <!-- Include Three.js via CDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
</head>
<body>

    <div id="canvas-container"></div>

    <!-- HUD -->
    <div id="hud" class="hidden">
        <div>SCORE: <span id="score-val">0</span></div>
        <div>SPEED: <span id="speed-val">0</span> MPH</div>
    </div>

    <!-- Main Menu Screen -->
    <div id="menu-screen" class="ui-layer">
        <h1>NEON DRIVE 3D</h1>
        <p>Race down the winding cyber highway. Avoid the structural barriers.</p>
        <button class="btn" id="start-btn">Start Race</button>
        <div class="controls-hint">Use LEFT / RIGHT Arrows or A / D keys to switch lanes</div>
    </div>

    <!-- Game Over Screen -->
    <div id="gameover-screen" class="ui-layer hidden">
        <h1 style="background: linear-gradient(45deg, #ff3333, #ff8800); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">CRASHED!</h1>
        <p>Your vehicle sustained catastrophic damage.</p>
        <p style="font-size: 28px; margin-top: -15px;">Final Score: <span id="final-score">0</span></p>
        <button class="btn" id="restart-btn" style="background: linear-gradient(90deg, #ff4400, #ffaa00); box-shadow: 0 5px 15px rgba(255, 68, 0, 0.4);">Restart</button>
    </div>

    <script>
        // --- GAME CONFIG & STATE ---
        const CONFIG = {
            laneWidth: 4.5,
            laneSwitchSpeed: 12,
            initialSpeed: 45,
            maxSpeed: 120,
            acceleration: 1.5,
            roadSegmentLength: 4,
            visibleSegments: 45,
            curveIntensity: 18,     // How far left/right the road snakes
            curveFrequency: 0.015   // Wavelength of the road curves
        };

        let gameState = 'MENU'; // MENU, PLAYING, GAMEOVER
        let score = 0;
        let currentSpeed = CONFIG.initialSpeed;
        let distanceTraveled = 0;
        
        let currentLane = 0; // -1: Left, 0: Center, 1: Right
        let targetX = 0;     // Target X coord for smooth lane changing
        let playerX = 0;     // Actual physical X coordinate of player car

        // --- THREE.JS GLOBALS ---
        let scene, camera, renderer;
        let playerCar, roadGroup, obstacleGroup, cloudGroup;
        let roadSegments = [];
        let obstacles = [];

        // --- INITIALIZATION ---
        function init() {
            const container = document.getElementById('canvas-container');
            
            // Scene Setup
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x050512);
            scene.fog = new THREE.FogExp2(0x050512, 0.007);

            // Camera Setup
            camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
            // Angle camera down at the car slightly
            camera.position.set(0, 6, -11);
            camera.lookAt(new THREE.Vector3(0, 2, 20));

            // Renderer Setup
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.shadowMap.enabled = true;
            container.appendChild(renderer.domElement);

            // Groups
            roadGroup = new THREE.Group();
            obstacleGroup = new THREE.Group();
            cloudGroup = new THREE.Group();
            scene.add(roadGroup);
            scene.add(obstacleGroup);
            scene.add(cloudGroup);

            // Lighting
            setupLighting();

            // Build Static Environment / Objects
            createPlayerCar();
            buildInitialRoad();
            generateClouds();

            // Event Listeners
            window.addEventListener('resize', onWindowResize);
            window.addEventListener('keydown', handleKeyDown);
            
            document.getElementById('start-btn').addEventListener('click', startGame);
            document.getElementById('restart-btn').addEventListener('click', restartGame);

            // Kick off game animation loop
            animate();
        }

        // --- LIGHTING ---
        function setupLighting() {
            const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
            scene.add(ambientLight);

            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(20, 40, -20);
            directionalLight.castShadow = true;
            scene.add(directionalLight);

            // Subtle neon glow from bottom up
            const skyLight = new THREE.HemisphereLight(0x00ffff, 0xff00ff, 0.3);
            scene.add(skyLight);
        }

        // --- PROCEDURAL GENERATION HELPERS ---
        
        // Math formula that determines how the road curves based on total Z distance
        function getRoadCenterAtZ(zCoordinate) {
            return Math.sin(zCoordinate * CONFIG.curveFrequency) * CONFIG.curveIntensity;
        }

        function createPlayerCar() {
            playerCar = new THREE.Group();

            // Main Chassis (Lower Body)
            const bodyGeom = new THREE.BoxGeometry(2, 0.6, 4.2);
            const bodyMat = new THREE.MeshStandardMaterial({ color: 0xff0055, roughness: 0.2, metalness: 0.8 });
            const body = new THREE.Mesh(bodyGeom, bodyMat);
            body.position.y = 0.5;
            body.castShadow = true;
            playerCar.add(body);

            // Cabin (Upper glass/roof)
            const cabinGeom = new THREE.BoxGeometry(1.6, 0.6, 2);
            const cabinMat = new THREE.MeshStandardMaterial({ color: 0x111122, roughness: 0.1, transparent: true, opacity: 0.7 });
            const cabin = new THREE.Mesh(cabinGeom, cabinMat);
            cabin.position.set(0, 1.1, -0.3);
            playerCar.add(cabin);

            // Wheels (Cylinders)
            const wheelGeom = new THREE.CylinderGeometry(0.4, 0.4, 0.4, 16);
            const wheelMat = new THREE.MeshStandardMaterial({ color: 0x111111, roughness: 0.8 });
            
            const wheelPositions = [
                [-1.05, 0.4, 1.3],  // Front Left
                [1.05, 0.4, 1.3],   // Front Right
                [-1.05, 0.4, -1.3], // Rear Left
                [1.05, 0.4, -1.3]   // Rear Right
            ];

            wheelPositions.forEach(pos => {
                const wheel = new THREE.Mesh(wheelGeom, wheelMat);
                wheel.position.set(pos[0], pos[1], pos[2]);
                wheel.rotation.z = Math.PI / 2; // Flip cylinder sideways
                playerCar.add(wheel);
            });

            // Headlights (Neon visual indicators)
            const lightGeom = new THREE.BoxGeometry(0.4, 0.15, 0.1);
            const lightMat = new THREE.MeshBasicMaterial({ color: 0x00ffff });
            const leftLight = new THREE.Mesh(lightGeom, lightMat);
            leftLight.position.set(-0.7, 0.6, 2.1);
            const rightLight = leftLight.clone();
            rightLight.position.x = 0.7;
            playerCar.add(leftLight, rightLight);

            scene.add(playerCar);
        }

        function createRoadSegment(zPos) {
            const segmentGroup = new THREE.Group();
            const roadWidth = CONFIG.laneWidth * 3;

            // Main Asphalt
            const roadGeom = new THREE.BoxGeometry(roadWidth, 0.2, CONFIG.roadSegmentLength);
            const roadMat = new THREE.MeshStandardMaterial({ color: 0x1a1a24, roughness: 0.7 });
            const road = new THREE.Mesh(roadGeom, roadMat);
            road.receiveShadow = true;
            segmentGroup.add(road);

            // Side Railings / Neon borders
            const railGeom = new THREE.BoxGeometry(0.3, 0.4, CONFIG.roadSegmentLength);
            const railMat = new THREE.MeshStandardMaterial({ color: 0x9900ff, emissive: 0x330066 });
            
            const leftRail = new THREE.Mesh(railGeom, railMat);
            leftRail.position.set(-roadWidth/2 - 0.15, 0.2, 0);
            
            const rightRail = leftRail.clone();
            rightRail.position.x = roadWidth/2 + 0.15;
            segmentGroup.add(leftRail, rightRail);

            // Lane Dividers (Dashed Center Lines)
            if (Math.floor(zPos / CONFIG.roadSegmentLength) % 2 === 0) {
                const lineGeom = new THREE.BoxGeometry(0.15, 0.22, CONFIG.roadSegmentLength * 0.6);
                const lineMat = new THREE.MeshBasicMaterial({ color: 0xffffff });
                
                const line1 = new THREE.Mesh(lineGeom, lineMat);
                line1.position.set(-CONFIG.laneWidth / 2, 0, 0);

                const line2 = line1.clone();
                line2.position.x = CONFIG.laneWidth / 2;
                
                segmentGroup.add(line1, line2);
            }

            // Curve positioning alignment
            const targetCenterX = getRoadCenterAtZ(zPos);
            segmentGroup.position.set(targetCenterX, 0, zPos);

            roadGroup.add(segmentGroup);
            
            return {
                mesh: segmentGroup,
                z: zPos,
                centerX: targetCenterX
            };
        }

        function buildInitialRoad() {
            for (let i = 0; i < CONFIG.visibleSegments; i++) {
                const zPos = i * CONFIG.roadSegmentLength;
                roadSegments.push(createRoadSegment(zPos));
            }
        }

        function createObstacle(zPos, lane) {
            // Lane mapping calculations
            const baseCenterX = getRoadCenterAtZ(zPos);
            const laneXOffset = lane * CONFIG.laneWidth;
            const absoluteX = baseCenterX + laneXOffset;

            const obstacleMesh = new THREE.Group();

            // Main Barrier beam
            const barrierGeom = new THREE.BoxGeometry(3.6, 0.5, 0.8);
            const barrierMat = new THREE.MeshStandardMaterial({ color: 0xff7700, roughness: 0.5 });
            const barrier = new THREE.Mesh(barrierGeom, barrierMat);
            barrier.position.y = 0.8;
            barrier.castShadow = true;
            obstacleMesh.add(barrier);

            // Support pillars
            const legGeom = new THREE.BoxGeometry(0.4, 0.8, 0.8);
            const legMat = new THREE.MeshStandardMaterial({ color: 0x333333 });
            const leftLeg = new THREE.Mesh(legGeom, legMat);
            leftLeg.position.set(-1.4, 0.4, 0);
            const rightLeg = leftLeg.clone();
            rightLeg.position.x = 1.4;
            obstacleMesh.add(leftLeg, rightLeg);

            // Neon warning strip
            const stripeGeom = new THREE.BoxGeometry(3.62, 0.2, 0.82);
            const stripeMat = new THREE.MeshBasicMaterial({ color: 0xffaa00 });
            const stripe = new THREE.Mesh(stripeGeom, stripeMat);
            stripe.position.y = 0.8;
            obstacleMesh.add(stripe);

            obstacleMesh.position.set(absoluteX, 0, zPos);
            obstacleGroup.add(obstacleMesh);

            obstacles.push({
                mesh: obstacleMesh,
                z: zPos,
                lane: lane,
                boundingBox: new THREE.Box3(new THREE.Vector3(), new THREE.Vector3())
            });
        }

        function generateClouds() {
            const cloudMat = new THREE.MeshStandardMaterial({ color: 0x222244, roughness: 0.9, flatShading: true });
            
            for(let i=0; i<25; i++) {
                const cloud = new THREE.Group();
                const numSpheres = 3 + Math.floor(Math.random() * 4);
                
                for(let j=0; j<numSpheres; j++) {
                    const radius = 3 + Math.random() * 5;
                    const sphereGeom = new THREE.SphereGeometry(radius, 6, 6);
                    const sphere = new THREE.Mesh(sphereGeom, cloudMat);
                    sphere.position.set(
                        (j * 3) - (numSpheres * 1.5),
                        (Math.random() * 2) - 1,
                        (Math.random() * 2) - 1
                    );
                    cloud.add(sphere);
                }

                // Disperse widely over horizon skybox
                cloud.position.set(
                    (Math.random() - 0.5) * 300,
                    15 + Math.random() * 25,
                    40 + Math.random() * 160
                );
                cloudGroup.add(cloud);
            }
        }

        // --- PROCEDURAL RECYCLING LOOP ---
        function updateInfiniteWorld(delta) {
            // Calculate how far we traveled inside this tick frame
            const speedFactor = currentSpeed * 0.44704; // Conversion framework to M/S
            const frameDistance = speedFactor * delta;
            distanceTraveled += frameDistance;

            if (gameState === 'PLAYING') {
                score = Math.floor(distanceTraveled / 3);
                document.getElementById('score-val').innerText = score;
                document.getElementById('speed-val').innerText = Math.floor(currentSpeed);
                
                // Accelerate gently over time
                if (currentSpeed < CONFIG.maxSpeed) {
                    currentSpeed += CONFIG.acceleration * delta;
                }
            }

            // Move the obstacle meshes and clouds backward towards player
            obstacleGroup.position.z -= frameDistance;
            cloudGroup.children.forEach(cloud => {
                cloud.position.z -= frameDistance * 0.1; // Cloud drift looks slower (parallax effect)
                if (cloud.position.z < -20) {
                    cloud.position.z = 150 + Math.random() * 50;
                    cloud.position.x = (Math.random() - 0.5) * 300;
                }
            });

            // Adjust road segments track
            roadSegments.forEach(seg => {
                seg.z -= frameDistance;
                // Recycle chunk index to horizon when it leaves player camera range
                if (seg.z < -CONFIG.roadSegmentLength * 3) {
                    const highestZ = Math.max(...roadSegments.map(s => s.z));
                    seg.z = highestZ + CONFIG.roadSegmentLength;
                    seg.centerX = getRoadCenterAtZ(distanceTraveled + seg.z);
                }
                seg.mesh.position.set(seg.centerX, 0, seg.z);
            });

            // Handle Obstacle spawning logic rules
            obstacles.forEach((obs, index) => {
                obs.z -= frameDistance;
                // Track dynamic curves adjustments as barriers move closer
                const absoluteRoadCenter = getRoadCenterAtZ(distanceTraveled + obs.z);
                obs.mesh.position.set(absoluteRoadCenter + (obs.lane * CONFIG.laneWidth), 0, obs.z);

                // Update physical bounding box matrices targets
                if (obs.mesh.children[0]) {
                    obs.boundingBox.setFromObject(obs.mesh);
                }

                // Clear barriers safely when behind player cockpit
                if (obs.z < -5) {
                    obstacleGroup.remove(obs.mesh);
                    obstacles.splice(index, 1);
                }
            });

            // Continuous spawn stream triggers
            if (gameState === 'PLAYING' && obstacles.length < 8) {
                const furthestZ = obstacles.length > 0 ? Math.max(...obstacles.map(o => o.z)) : 40;
                // Spawn spacing gaps dynamically based on speed thresholds
                const spawnGap = 35 + (currentSpeed * 0.2); 
                
                if (furthestZ < 140) {
                    const targetSpawnZ = furthestZ + spawnGap;
                    const choicePattern = Math.random();
                    
                    if (choicePattern < 0.40) {
                        // Single random barrier
                        createObstacle(targetSpawnZ, Math.floor(Math.random() * 3) - 1);
                    } else if (choicePattern < 0.75) {
                        // Double barrier blockade combo (Forces clean swift lane skips)
                        const emptyLane = Math.floor(Math.random() * 3) - 1;
                        [-1, 0, 1].forEach(lane => {
                            if (lane !== emptyLane) createObstacle(targetSpawnZ, lane);
                        });
                    }
                }
            }
        }

        // --- PLAYER INTERACTION INTERPOLATION ---
        function updatePlayerMovement(delta) {
            // Find current alignment profile anchor directly underneath the vehicle
            const currentRoadCenter = getRoadCenterAtZ(distanceTraveled);
            
            // Map lateral lane selections values targets
            targetX = currentRoadCenter + (currentLane * CONFIG.laneWidth);

            // Interpolate vehicle physics position across curves tracks safely
            playerX += (targetX - playerX) * CONFIG.laneSwitchSpeed * delta;
            
            playerCar.position.set(playerX, 0, 0);

            // Tilt/Lean effects calculations based on steering targets tracking gaps delta
            const lateralDeflection = targetX - playerX;
            playerCar.rotation.y = lateralDeflection * 0.08;
            playerCar.rotation.z = -lateralDeflection * 0.05;
        }

        // --- COLLISION LOGIC DETECTOR ---
        function checkCollisions() {
            if (gameState !== 'PLAYING') return;

            // Generate Bounding box wrapping system calculations cleanly around car frame
            const carBox = new THREE.Box3().setFromObject(playerCar);

            // Add margin reduction profile to ease visual tolerances safely
            carBox.min.x += 0.15;
            carBox.max.x -= 0.15;
            carBox.min.z += 0.2;
            carBox.max.z -= 0.2;

            for (let i = 0; i < obstacles.length; i++) {
                const obs = obstacles[i];
                
                // Only evaluate intersections strictly near tracking range parameters
                if (obs.z > -2 && obs.z < 3) {
                    if (carBox.intersectsBox(obs.boundingBox)) {
                        endGame();
                        break;
                    }
                }
            }
        }

        // --- STATE ACTIONS ---
        function startGame() {
            document.getElementById('menu-screen').classList.add('hidden');
            document.getElementById('hud').classList.remove('hidden');
            gameState = 'PLAYING';
        }

        function endGame() {
            gameState = 'GAMEOVER';
            document.getElementById('hud').classList.add('hidden');
            document.getElementById('final-score').innerText = score;
            document.getElementById('gameover-screen').classList.remove('hidden');
        }

        function restartGame() {
            document.getElementById('gameover-screen').classList.add('hidden');
            document.getElementById('hud').classList.remove('hidden');

            // Reset variable loops
            score = 0;
            distanceTraveled = 0;
            currentSpeed = CONFIG.initialSpeed;
            currentLane = 0;
            playerX = 0;
            targetX = 0;

            // Purge existing barriers from runtime context cache safely
            obstacles.forEach(obs => obstacleGroup.remove(obs.mesh));
            obstacles = [];

            gameState = 'PLAYING';
        }

        // --- CORE LOOPS CONTROLLER ---
        let clock = new THREE.Clock();

        function animate() {
            requestAnimationFrame(animate);

            // Fetch structural Delta framework steps safely capped to prevent lag spikes
            let delta = clock.getDelta();
            if (delta > 0.1) delta = 0.1; 

            // Environment transformations ticks executed continuously
            updateInfiniteWorld(delta);
            updatePlayerMovement(delta);
            checkCollisions();

            renderer.render(scene, camera);
        }

        // --- CONTROL MAPS ---
        function handleKeyDown(e) {
            if (gameState !== 'PLAYING') return;

            if ((e.key === 'ArrowLeft' || e.key.toLowerCase() === 'a') && currentLane > -1) {
                currentLane--;
            }
            if ((e.key === 'ArrowRight' || e.key.toLowerCase() === 'd') && currentLane < 1) {
                currentLane++;
            }
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        // Boot system core runtime directly on finish loading document context safely
        window.onload = init;
    </script>
</body>
</html>

Models

73
Compare code outputs