<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Retro Pong + AI</title>

    <style>

        :root {

            --bg-color: #051005;

            --game-bg: #000000;

            --accent: #33ff33;

            --text-color: #33ff33;

            --commentary-bg: #000000;

        }


        body {

            margin: 0;

            padding: 0;

            background-color: var(--bg-color);

            color: var(--text-color);

            display: flex;

            flex-direction: column;

            align-items: center;

            justify-content: center;

            height: 100vh;

            font-family: 'Courier New', Courier, monospace;

            overflow: hidden;

            transition: background-color 0.5s;

        }


        .container {

            position: relative;

            box-shadow: 0 0 20px rgba(0,0,0,0.5);

            border-radius: 4px;

            overflow: hidden;

            width: 100%;

            max-width: 800px;

            aspect-ratio: 4/3;

            background: var(--game-bg);

            transition: background-color 0.5s;

        }


        canvas {

            display: block;

            width: 100%;

            height: 100%;

            background-color: var(--game-bg);

            transition: background-color 0.5s;

        }


        .ui-layer {

            position: absolute;

            top: 0;

            left: 0;

            width: 100%;

            height: 100%;

            pointer-events: none;

            display: flex;

            flex-direction: column;

            justify-content: center;

            align-items: center;

            text-align: center;

        }


        .score-board {

            position: absolute;

            top: 20px;

            width: 100%;

            display: flex;

            justify-content: center;

            font-size: 4rem;

            font-weight: bold;

            opacity: 0.5;

            pointer-events: none;

            gap: 100px;

            color: var(--text-color);

            transition: color 0.5s;

        }


        /* Commentary Bubble */

        .commentary-box {

            position: absolute;

            bottom: 20px;

            width: 80%;

            min-height: 40px;

            background: rgba(0, 0, 0, 0.8);

            border: 2px solid var(--accent);

            color: var(--accent);

            padding: 10px 20px;

            font-size: 1rem;

            text-transform: uppercase;

            text-align: center;

            display: flex;

            align-items: center;

            justify-content: center;

            border-radius: 4px;

            opacity: 0;

            transition: opacity 0.3s, color 0.5s, border-color 0.5s;

        }


        .commentary-box.visible {

            opacity: 1;

        }


        .start-screen, .game-over-screen, .theme-modal {

            background: rgba(0, 0, 0, 0.9);

            padding: 2rem;

            border-radius: 8px;

            pointer-events: auto;

            transition: opacity 0.3s;

            border: 1px solid var(--accent);

            max-width: 80%;

        }


        h1 {

            margin: 0 0 1rem 0;

            font-size: 2.5rem;

            text-transform: uppercase;

            letter-spacing: 4px;

            text-shadow: 0 0 10px var(--accent);

            color: var(--accent);

            transition: color 0.5s, text-shadow 0.5s;

        }


        p {

            font-size: 1.1rem;

            line-height: 1.5;

            margin-bottom: 2rem;

            color: var(--text-color);

            opacity: 0.8;

            transition: color 0.5s;

        }


        button {

            background: var(--accent);

            color: var(--game-bg);

            border: none;

            padding: 12px 30px;

            font-size: 1.2rem;

            font-family: inherit;

            font-weight: bold;

            cursor: pointer;

            text-transform: uppercase;

            border-radius: 2px;

            transition: transform 0.1s, background-color 0.2s, color 0.5s;

            margin: 10px;

        }


        button:hover {

            transform: scale(1.05);

            filter: brightness(1.2);

        }


        button:active {

            transform: scale(0.95);

        }


        button:disabled {

            opacity: 0.5;

            cursor: not-allowed;

            transform: none;

        }


        input[type="text"] {

            background: transparent;

            border: 2px solid var(--accent);

            color: var(--accent);

            padding: 10px;

            font-family: inherit;

            font-size: 1rem;

            margin-bottom: 20px;

            width: 100%;

            box-sizing: border-box;

            outline: none;

        }


        input[type="text"]::placeholder {

            color: var(--accent);

            opacity: 0.5;

        }


        .controls-hint {

            margin-top: 15px;

            font-size: 0.8rem;

            opacity: 0.7;

            color: var(--text-color);

        }


        /* Pause Button & Overlay */

        .pause-btn {

            position: absolute;

            top: 20px;

            right: 20px;

            background: transparent;

            border: 2px solid var(--accent);

            color: var(--accent);

            width: 40px;

            height: 40px;

            border-radius: 50%;

            font-weight: bold;

            display: flex;

            align-items: center;

            justify-content: center;

            cursor: pointer;

            z-index: 20;

            opacity: 0.5;

            transition: opacity 0.3s, transform 0.2s, background-color 0.3s;

            pointer-events: auto;

        }


        .pause-btn:hover {

            opacity: 1;

            transform: scale(1.1);

            background: rgba(255, 255, 255, 0.1);

        }


        .pause-overlay {

            background: rgba(0, 0, 0, 0.4);

            backdrop-filter: blur(2px);

        }


        .scanlines {

            position: absolute;

            top: 0;

            left: 0;

            width: 100%;

            height: 100%;

            background: linear-gradient(

                to bottom,

                rgba(255, 255, 255, 0),

                rgba(255, 255, 255, 0) 50%,

                rgba(0, 0, 0, 0.2) 50%,

                rgba(0, 0, 0, 0.2)

            );

            background-size: 100% 4px;

            pointer-events: none;

            z-index: 10;

        }


        .hidden {

            display: none !important;

        }


        .loading {

            animation: blink 1s infinite;

        }


        @keyframes blink {

            0%, 100% { opacity: 1; }

            50% { opacity: 0.5; }

        }


    </style>

</head>

<body>


    <div class="container" id="gameContainer">

        <canvas id="gameCanvas" width="800" height="600"></canvas>

        <div class="scanlines"></div>


        <div class="score-board">

            <span id="playerScore">0</span>

            <span id="aiScore">0</span>

        </div>


        <button id="pauseBtn" class="pause-btn hidden">||</button>


        <div id="commentaryBox" class="commentary-box">AI: "PREPARE TO BE DELETED."</div>


        <!-- Start Screen -->

        <div id="startScreen" class="ui-layer">

            <div class="start-screen">

                <h1>PONG</h1>

                <p>First to 5 points wins.</p>

                <div>

                    <button id="startBtn">Start Game</button>

                    <button id="themeBtn">✨ AI Theme</button>

                </div>

                <div class="controls-hint">

                    Controls: Mouse / Touch / Arrow Keys

                </div>

            </div>

        </div>


        <!-- Theme Modal -->

        <div id="themeModal" class="ui-layer hidden">

            <div class="theme-modal">

                <h1>Dream Theme</h1>

                <p>Describe a style (e.g., "Cyberpunk", "80s Sunset", "Matrix")</p>

                <input type="text" id="themeInput" placeholder="Enter theme description...">

                <div>

                    <button id="generateThemeBtn">Generate</button>

                    <button id="cancelThemeBtn" style="background: transparent; border: 1px solid var(--accent); color: var(--accent);">Cancel</button>

                </div>

            </div>

        </div>


        <!-- Pause Screen -->

        <div id="pauseScreen" class="ui-layer hidden pause-overlay">

            <div class="start-screen">

                <h1>PAUSED</h1>

                <button id="resumeBtn">Resume</button>

            </div>

        </div>


        <!-- Game Over Screen -->

        <div id="gameOverScreen" class="ui-layer hidden">

            <div class="game-over-screen">

                <h1 id="winnerText">Player Wins!</h1>

                <button id="restartBtn">Play Again</button>

            </div>

        </div>

    </div>


    <script>

        /**

         * Pong Game Logic with Gemini API Integration

         */

        

        // --- Gemini API Setup ---

        const apiKey = "AIzaSyBj14Ny1_4pgz4AIVISdnJn-tFa7aHVbAM"; // System will provide API key at runtime


        async function callGemini(prompt, systemInstruction, jsonMode = false) {

            const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-09-2025:generateContent?key=${apiKey}`;

            

            const payload = {

                contents: [{ parts: [{ text: prompt }] }],

                systemInstruction: { parts: [{ text: systemInstruction }] }

            };


            if (jsonMode) {

                payload.generationConfig = {

                    responseMimeType: "application/json",

                    responseSchema: {

                        type: "OBJECT",

                        properties: {

                            bg_color: { type: "STRING" },

                            game_bg: { type: "STRING" },

                            accent: { type: "STRING" },

                            text_color: { type: "STRING" }

                        }

                    }

                };

            }


            try {

                const response = await fetch(url, {

                    method: 'POST',

                    headers: { 'Content-Type': 'application/json' },

                    body: JSON.stringify(payload)

                });


                if (!response.ok) throw new Error(`API Error: ${response.status}`);

                

                const data = await response.json();

                return data.candidates?.[0]?.content?.parts?.[0]?.text;

            } catch (error) {

                console.error("Gemini API Error:", error);

                return null;

            }

        }


        // --- Configuration ---

        const CONFIG = {

            paddleWidth: 15,

            paddleHeight: 100,

            ballSize: 10,

            winScore: 5,

            initialBallSpeed: 5,

            speedIncrease: 0.5,

            aiSpeed: 5

        };


        // --- State Management ---

        const canvas = document.getElementById('gameCanvas');

        const ctx = canvas.getContext('2d');

        const container = document.getElementById('gameContainer');


        // UI Elements

        const startScreen = document.getElementById('startScreen');

        const gameOverScreen = document.getElementById('gameOverScreen');

        const themeModal = document.getElementById('themeModal');

        const startBtn = document.getElementById('startBtn');

        const restartBtn = document.getElementById('restartBtn');

        const themeBtn = document.getElementById('themeBtn');

        const generateThemeBtn = document.getElementById('generateThemeBtn');

        const cancelThemeBtn = document.getElementById('cancelThemeBtn');

        const themeInput = document.getElementById('themeInput');

        

        const playerScoreEl = document.getElementById('playerScore');

        const aiScoreEl = document.getElementById('aiScore');

        const winnerText = document.getElementById('winnerText');

        const commentaryBox = document.getElementById('commentaryBox');

        

        // Pause Elements

        const pauseBtn = document.getElementById('pauseBtn');

        const pauseScreen = document.getElementById('pauseScreen');

        const resumeBtn = document.getElementById('resumeBtn');


        let animationId;

        let isGameRunning = false;

        let isPaused = false;

        let serveTimeout;

        let currentTheme = {

            accent: '#33ff33',

            game_bg: '#000000',

            ball: '#33ff33',

            player: '#33ff33',

            ai: '#33ff33'

        };


        // Game Objects

        const ball = {

            x: canvas.width / 2,

            y: canvas.height / 2,

            radius: CONFIG.ballSize,

            speedX: CONFIG.initialBallSpeed,

            speedY: CONFIG.initialBallSpeed,

            speed: CONFIG.initialBallSpeed

        };


        const player = {

            x: 0, 

            y: (canvas.height - CONFIG.paddleHeight) / 2,

            width: CONFIG.paddleWidth,

            height: CONFIG.paddleHeight,

            score: 0,

            dy: 0 // Velocity for keyboard controls

        };


        const ai = {

            x: canvas.width - CONFIG.paddleWidth,

            y: (canvas.height - CONFIG.paddleHeight) / 2,

            width: CONFIG.paddleWidth,

            height: CONFIG.paddleHeight,

            score: 0,

            dy: 0

        };


        // --- AI Commentary Logic ---

        

        async function triggerCommentary(eventType) {

            // Rate limiting/randomness to avoid spamming every single event

            if (eventType === 'rally' && Math.random() > 0.3) return;


            const systemPrompt = "You are a competitive, slightly arrogant 1980s retro computer AI named 'CPU-001' playing Pong against a human. Speak in all-caps, short sentences (max 8 words). Use technical/glitchy jargon. Be sarcastic if you lose, gloat if you win.";

            

            let userPrompt = "";

            switch(eventType) {

                case 'start': userPrompt = "The game has just started. Intimidate the human."; break;

                case 'ai_score': userPrompt = `I just scored. Current score: CPU ${ai.score}, Human ${player.score}. Gloat.`; break;

                case 'player_score': userPrompt = `The human just scored. Current score: CPU ${ai.score}, Human ${player.score}. Make an excuse or insult them.`; break;

                case 'win': userPrompt = "I won the match. Celebrate my superiority."; break;

                case 'loss': userPrompt = "I lost the match. Claim it was a bug or hardware failure."; break;

                case 'rally': userPrompt = "The rally has been going on for a long time. Comment on the intensity."; break;

            }


            // Show loading...

            commentaryBox.textContent = "CPU-001 IS THINKING...";

            commentaryBox.classList.add('visible');


            const text = await callGemini(userPrompt, systemPrompt);

            if (text) {

                commentaryBox.textContent = `CPU: "${text.replace(/"/g, '')}"`;

                // Hide after 4 seconds

                setTimeout(() => {

                    // Only hide if text hasn't changed

                    if (commentaryBox.textContent.includes(text.replace(/"/g, ''))) {

                        commentaryBox.classList.remove('visible');

                    }

                }, 4000);

            }

        }


        // --- Theme Logic ---


        async function generateTheme() {

            const description = themeInput.value;

            if (!description) return;


            generateThemeBtn.textContent = "Generating...";

            generateThemeBtn.disabled = true;


            const systemPrompt = "You are a UI design assistant. Generate a color palette for a retro pong game based on the user's description. Return strictly JSON.";

            const userPrompt = `Create a theme for: "${description}". Needs 4 colors: bg_color (page background), game_bg (canvas background), accent (paddles/text/ball), text_color.`;


            const jsonStr = await callGemini(userPrompt, systemPrompt, true);

            

            if (jsonStr) {

                try {

                    const theme = JSON.parse(jsonStr);

                    applyTheme(theme);

                    closeThemeModal();

                } catch (e) {

                    console.error("Failed to parse theme", e);

                }

            }


            generateThemeBtn.textContent = "Generate";

            generateThemeBtn.disabled = false;

        }


        function applyTheme(theme) {

            const root = document.documentElement;

            root.style.setProperty('--bg-color', theme.bg_color || '#000');

            root.style.setProperty('--game-bg', theme.game_bg || '#111');

            root.style.setProperty('--accent', theme.accent || '#fff');

            root.style.setProperty('--text-color', theme.text_color || '#fff');


            // Update JS internal colors

            currentTheme.accent = theme.accent || '#fff';

            currentTheme.game_bg = theme.game_bg || '#111';

            currentTheme.ball = theme.accent || '#fff';

            currentTheme.player = theme.accent || '#fff';

            currentTheme.ai = theme.accent || '#fff';

        }


        // --- Game Flow ---


        function init() {

            resetBall();

            player.score = 0;

            ai.score = 0;

            updateScoreBoard();

            player.x = 20;

            ai.x = canvas.width - 20 - CONFIG.paddleWidth;

            triggerCommentary('start');

        }


        function gameLoop() {

            if (!isGameRunning) return;

            

            if (!isPaused) {

                update();

                draw();

            }

            

            animationId = requestAnimationFrame(gameLoop);

        }


        function start() {

            startScreen.classList.add('hidden');

            gameOverScreen.classList.add('hidden');

            themeModal.classList.add('hidden');

            pauseScreen.classList.add('hidden');

            pauseBtn.classList.remove('hidden'); // Show pause button


            isGameRunning = true;

            isPaused = false;

            init();

            gameLoop();

        }


        function togglePause() {

            if (!isGameRunning) return;

            

            isPaused = !isPaused;

            

            if (isPaused) {

                pauseScreen.classList.remove('hidden');

                pauseBtn.textContent = '▶';

            } else {

                pauseScreen.classList.add('hidden');

                pauseBtn.textContent = '||';

            }

        }


        function stop(winner) {

            isGameRunning = false;

            pauseBtn.classList.add('hidden'); // Hide pause button

            cancelAnimationFrame(animationId);

            if (serveTimeout) clearTimeout(serveTimeout);

            

            winnerText.textContent = winner === 'player' ? "YOU WIN!" : "GAME OVER";

            gameOverScreen.classList.remove('hidden');


            triggerCommentary(winner === 'player' ? 'loss' : 'win');

        }


        let rallyCount = 0;


        function update() {

            if (player.dy !== 0) {

                player.y += player.dy;

            }


            if (player.y < 0) player.y = 0;

            if (player.y + player.height > canvas.height) player.y = canvas.height - player.height;


            // AI Movement

            let aiCenter = ai.y + ai.height / 2;

            if (aiCenter < ball.y - 35) {

                ai.y += CONFIG.aiSpeed;

            } else if (aiCenter > ball.y + 35) {

                ai.y -= CONFIG.aiSpeed;

            }

            if (ai.y < 0) ai.y = 0;

            if (ai.y + ai.height > canvas.height) ai.y = canvas.height - ai.height;


            // Ball Movement

            ball.x += ball.speedX;

            ball.y += ball.speedY;


            if (ball.y - ball.radius < 0 || ball.y + ball.radius > canvas.height) {

                ball.speedY = -ball.speedY;

            }


            let activePaddle = (ball.x < canvas.width / 2) ? player : ai;


            if (collision(ball, activePaddle)) {

                let collidePoint = (ball.y - (activePaddle.y + activePaddle.height / 2));

                collidePoint = collidePoint / (activePaddle.height / 2);

                let angleRad = (Math.PI / 4) * collidePoint;

                let direction = (ball.x < canvas.width / 2) ? 1 : -1;


                ball.speed += CONFIG.speedIncrease;

                ball.speedX = direction * ball.speed * Math.cos(angleRad);

                ball.speedY = ball.speed * Math.sin(angleRad);

                

                rallyCount++;

                if (rallyCount === 10) triggerCommentary('rally');

            }


            // Scoring

            if (ball.x - ball.radius < 0) {

                ai.score++;

                triggerCommentary('ai_score');

                updateScoreBoard();

                checkWinCondition();

                resetBall();

            } else if (ball.x + ball.radius > canvas.width) {

                player.score++;

                triggerCommentary('player_score');

                updateScoreBoard();

                checkWinCondition();

                resetBall();

            }

        }


        function collision(b, p) {

            return b.x + b.radius > p.x && 

                   b.x - b.radius < p.x + p.width && 

                   b.y + b.radius > p.y && 

                   b.y - b.radius < p.y + p.height;

        }


        function resetBall() {

            rallyCount = 0;

            ball.x = canvas.width / 2;

            ball.y = canvas.height / 2;

            ball.speed = CONFIG.initialBallSpeed;

            ball.speedX = 0;

            ball.speedY = 0;

            

            if (serveTimeout) clearTimeout(serveTimeout);


            serveTimeout = setTimeout(() => {

                if (!isGameRunning) return;

                launchBall();

            }, 3000);

        }


        function launchBall() {

            ball.speedX = (Math.random() > 0.5 ? 1 : -1) * ball.speed;

            ball.speedY = (Math.random() * 2 - 1) * ball.speed * 0.5;

        }


        function checkWinCondition() {

            if (player.score >= CONFIG.winScore) {

                stop('player');

            } else if (ai.score >= CONFIG.winScore) {

                stop('ai');

            }

        }


        function updateScoreBoard() {

            playerScoreEl.textContent = player.score;

            aiScoreEl.textContent = ai.score;

        }


        // --- Rendering ---


        function draw() {

            // Clear Screen with current theme color

            ctx.fillStyle = currentTheme.game_bg;

            ctx.fillRect(0, 0, canvas.width, canvas.height);


            drawNet();

            drawRect(player.x, player.y, player.width, player.height, currentTheme.player);

            drawRect(ai.x, ai.y, ai.width, ai.height, currentTheme.ai);

            drawCircle(ball.x, ball.y, ball.radius, currentTheme.ball);

        }


        function drawRect(x, y, w, h, color) {

            ctx.fillStyle = color;

            ctx.fillRect(x, y, w, h);

        }


        function drawCircle(x, y, r, color) {

            ctx.fillStyle = color;

            ctx.beginPath();

            ctx.arc(x, y, r, 0, Math.PI * 2, false);

            ctx.closePath();

            ctx.fill();

        }


        function drawNet() {

            ctx.strokeStyle = currentTheme.accent;

            ctx.globalAlpha = 0.2;

            ctx.lineWidth = 4;

            ctx.setLineDash([15, 10]);

            ctx.beginPath();

            ctx.moveTo(canvas.width / 2, 0);

            ctx.lineTo(canvas.width / 2, canvas.height);

            ctx.stroke();

            ctx.setLineDash([]);

            ctx.globalAlpha = 1.0;

        }


        // --- Input Handling ---


        container.addEventListener('mousemove', (e) => {

            if (!isGameRunning || isPaused) return;

            const rect = canvas.getBoundingClientRect();

            const scaleY = canvas.height / rect.height;

            const relativeY = (e.clientY - rect.top) * scaleY;

            player.y = relativeY - player.height / 2;

        });


        container.addEventListener('touchmove', (e) => {

            if (!isGameRunning || isPaused) return;

            e.preventDefault();

            const rect = canvas.getBoundingClientRect();

            const scaleY = canvas.height / rect.height;

            const touch = e.touches[0];

            const relativeY = (touch.clientY - rect.top) * scaleY;

            player.y = relativeY - player.height / 2;

        }, { passive: false });


        window.addEventListener('keydown', (e) => {

            // Toggle pause with 'P'

            if (isGameRunning && (e.key === 'p' || e.key === 'P')) {

                togglePause();

                return;

            }


            if (!isGameRunning || isPaused) return;

            if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W') player.dy = -8;

            else if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') player.dy = 8;

        });


        window.addEventListener('keyup', (e) => {

            if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W' || 

                e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') player.dy = 0;

        });


        // Button Event Listeners

        startBtn.addEventListener('click', start);

        restartBtn.addEventListener('click', start);

        pauseBtn.addEventListener('click', togglePause);

        resumeBtn.addEventListener('click', togglePause);


        // Theme UI

        themeBtn.addEventListener('click', () => {

            startScreen.classList.add('hidden');

            themeModal.classList.remove('hidden');

        });


        cancelThemeBtn.addEventListener('click', closeThemeModal);


        function closeThemeModal() {

            themeModal.classList.add('hidden');

            if (!isGameRunning) startScreen.classList.remove('hidden');

        }


        generateThemeBtn.addEventListener('click', generateTheme);


        // Initial Draw

        draw();


    </script>

</body>

</html>