<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Agent Survival Simulation</title>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
            background-color: #f0f0f0;
        }
        #simulation-container {
            position: relative;
            width: 800px;
            height: 600px;
            background-color: #cce7ff;
            border: 5px solid #000;
            margin: 50px auto;
            overflow: hidden;
        }
        #agent {
            position: absolute;
            width: 30px;
            height: 30px;
            background-color: red;
            border-radius: 50%;
            transition: left 0.1s, top 0.1s;
        }
        .block {
            position: absolute;
            width: 25px;
            height: 15px;
            background-color: blue;
            border: 1px solid #000;
        }
        .food {
            position: absolute;
            width: 10px;
            height: 10px;
            background-color: green;
            border-radius: 50%;
        }
        #health-bar {
            width: 200px;
            height: 20px;
            background-color: #ddd;
            margin: 10px auto;
        }
        #health-bar-fill {
            height: 100%;
            background-color: #4CAF50;
            transition: width 0.5s;
        }
        #status {
            text-align: center;
            margin-top: 20px;
            font-size: 18px;
        }
        #countdown {
            font-size: 24px;
            text-align: center;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <div id="simulation-container">
        <div id="agent"></div>
    </div>
    <div id="countdown">Time Left: 120s</div>
    <div id="health-bar"><div id="health-bar-fill"></div></div>
    <div id="status"></div>

    <script>
    const container = document.getElementById('simulation-container');
    const agent = document.getElementById('agent');
    const healthBarFill = document.getElementById('health-bar-fill');
    const status = document.getElementById('status');
    const countdown = document.getElementById('countdown');

    const GRID_SIZE = 40;
    const CELL_WIDTH = container.offsetWidth / GRID_SIZE;
    const CELL_HEIGHT = container.offsetHeight / GRID_SIZE;

    let agentX = 20;
    let agentY = 20;
    let targetX = agentX;
    let targetY = agentY;
    let health = 100;
    let foodCollected = 0;
    let isCarryingBlock = false;
    let carriedBlock = null;
    let rewardPoints = 0;

    let isHotCycle = false;
    let timeLeft = 120;
    let blocks = [];
    let foods = [];
    let shelterBlocks = [];
    let timeUnderShelter = 0;
    let consecutiveLowFoodCycles = 0;
    let simulationInterval = null;

    const REWARD_LIFT_BLOCK = 10;
    const REWARD_DROP_BLOCK = 20;
    const REWARD_BUILD_SHELTER = 100;

    function createRandomBlocks(num) {
        for (let i = 0; i < num; i++) {
            const block = document.createElement('div');
            block.classList.add('block');
            let x, y;
            do {
                x = Math.floor(Math.random() * GRID_SIZE);
                y = Math.floor(Math.random() * GRID_SIZE);
            } while (isOccupied(x, y));
            block.style.left = x * CELL_WIDTH + 'px';
            block.style.top = y * CELL_HEIGHT + 'px';
            container.appendChild(block);
            blocks.push(block);
        }
    }

    function createRandomFood(num) {
        for (let i = 0; i < num; i++) {
            const food = document.createElement('div');
            food.classList.add('food');
            let x, y;
            do {
                x = Math.floor(Math.random() * GRID_SIZE);
                y = Math.floor(Math.random() * GRID_SIZE);
            } while (isOccupied(x, y));
            food.style.left = x * CELL_WIDTH + 'px';
            food.style.top = y * CELL_HEIGHT + 'px';
            container.appendChild(food);
            foods.push(food);
        }
    }

    function isOccupied(x, y) {
        return blocks.some(block => 
            parseFloat(block.style.left) / CELL_WIDTH === x && 
            parseFloat(block.style.top) / CELL_HEIGHT === y
        ) || foods.some(food => 
            parseFloat(food.style.left) / CELL_WIDTH === x && 
            parseFloat(food.style.top) / CELL_HEIGHT === y
        ) || (Math.floor(agentX) === x && Math.floor(agentY) === y);
    }

    function moveAgent(dx, dy) {
        targetX = Math.max(0, Math.min(GRID_SIZE - 1, targetX + dx));
        targetY = Math.max(0, Math.min(GRID_SIZE - 1, targetY + dy));
    }

    function updateAgentPosition() {
        const lerp = (start, end, t) => start + (end - start) * t;
        const smoothFactor = 0.05;  // Slower movement
        
        agentX = lerp(agentX, targetX, smoothFactor);
        agentY = lerp(agentY, targetY, smoothFactor);
        
        agent.style.left = agentX * CELL_WIDTH + 'px';
        agent.style.top = agentY * CELL_HEIGHT + 'px';
        
        if (isCarryingBlock && carriedBlock) {
            carriedBlock.style.left = agent.style.left;
            carriedBlock.style.top = agent.style.top;
        }
    }

    function buildEnclosedShelter() {
        const shelterPositions = [
            {x: Math.floor(agentX) - 1, y: Math.floor(agentY)}, // Left
            {x: Math.floor(agentX) + 1, y: Math.floor(agentY)}, // Right
            {x: Math.floor(agentX), y: Math.floor(agentY) - 1}, // Top
            {x: Math.floor(agentX), y: Math.floor(agentY) + 1}  // Bottom
        ];
        
        const missingBlocks = shelterPositions.filter(pos => !isBlockAt(pos.x, pos.y));
        
        if (missingBlocks.length > 0) {
            if (!isCarryingBlock) {
                let nearestBlock = findNearest(blocks, agentX, agentY);
                if (nearestBlock) {
                    moveToward(nearestBlock);
                    if (isNear(agentX, agentY, nearestBlock)) {
                        pickUpBlock(nearestBlock);  // Pick up the block
                    }
                }
            } else {
                const targetPosition = missingBlocks[0];  // Target the first incomplete position
                moveTowardPosition(targetPosition.x, targetPosition.y);  // Move toward it
                if (isNear(agentX, agentY, targetPosition)) {
                    dropBlock();  // Drop block at the correct position
                    shelterBlocks.push({x: Math.floor(agentX), y: Math.floor(agentY)});
                    rewardPoints += REWARD_DROP_BLOCK;  // Reward for dropping block
                }
            }
        } else if (isCarryingBlock) {
            dropBlock();  // Drop any extra block once the shelter is complete
        }

        if (isAgentInShelter()) {
            rewardPoints += REWARD_BUILD_SHELTER;  // Reward for being in complete shelter
        }
    }

    function findNearest(objects, x, y) {
        let minDistance = Infinity;
        let nearest = null;
        objects.forEach(obj => {
            const objX = parseFloat(obj.style.left) / CELL_WIDTH;
            const objY = parseFloat(obj.style.top) / CELL_HEIGHT;
            const distance = Math.abs(objX - x) + Math.abs(objY - y);
            if (distance < minDistance) {
                minDistance = distance;
                nearest = obj;
            }
        });
        return nearest;
    }

    function moveToward(target) {
        const targetX = parseFloat(target.style.left) / CELL_WIDTH;
        const targetY = parseFloat(target.style.top) / CELL_HEIGHT;
        moveTowardPosition(targetX, targetY);
    }

    function moveTowardPosition(targetX, targetY) {
        const dx = Math.sign(targetX - agentX);
        const dy = Math.sign(targetY - agentY);
        moveAgent(dx, dy);  // Controlled movement toward the target
    }

    function isNear(x1, y1, obj) {
        const x2 = parseFloat(obj.style.left) / CELL_WIDTH;
        const y2 = parseFloat(obj.style.top) / CELL_HEIGHT;
        return Math.abs(x1 - x2) <= 1 && Math.abs(y1 - y2) <= 1;
    }

    function pickUpBlock(block) {
        isCarryingBlock = true;
        carriedBlock = block;
        blocks = blocks.filter(b => b !== block);
        rewardPoints += REWARD_LIFT_BLOCK;
        updateAgentPosition();
    }

    function dropBlock() {
        if (isCarryingBlock && carriedBlock) {
            isCarryingBlock = false;
            carriedBlock = null;
        }
    }

    function isBlockAt(x, y) {
        return shelterBlocks.some(block => block.x === x && block.y === y);
    }

    function isAgentInShelter() {
        const requiredPositions = [
            {x: Math.floor(agentX) - 1, y: Math.floor(agentY)},
            {x: Math.floor(agentX) + 1, y: Math.floor(agentY)},
            {x: Math.floor(agentX), y: Math.floor(agentY) - 1},
            {x: Math.floor(agentX), y: Math.floor(agentY) + 1}
        ];
        return requiredPositions.every(pos => isBlockAt(pos.x, pos.y));
    }

    function aiDecision() {
        if (isHotCycle || (timeLeft < 30 && !isAgentInShelter())) {
            buildEnclosedShelter();
        } else {
            if (health < 50 || foods.length > 0) {
                findAndEatFood();
            } else if (blocks.length > 0 && shelterBlocks.length < 4) {
                collectBlocks();
            } else {
                moveRandomly();
            }
        }
    }

    function moveRandomly() {
        const dx = Math.floor(Math.random() * 3) - 1;
        const dy = Math.floor(Math.random() * 3) - 1;
        moveAgent(dx, dy);
    }

    function updateHealth() {
        if (isHotCycle) {
            if (isAgentInShelter()) {
                timeUnderShelter++;
                if (timeUnderShelter >= 80) {
                    health = Math.max(0, health - 1);
                }
            } else {
                health = Math.max(0, health - 2);
            }
        } else {
            health = Math.min(100, health + 0.5);
            timeUnderShelter = 0;
        }
        healthBarFill.style.width = health + '%';

        if (health <= 0) {
            clearInterval(simulationInterval);
            alert('Game Over! Agent died.');
            resetSimulation();
        }
    }

    function findAndEatFood() {
        let nearestFood = findNearest(foods, agentX, agentY);
        if (nearestFood) {
            moveToward(nearestFood);
            if (isNear(agentX, agentY, nearestFood)) {
                eatFood(nearestFood);
            }
        }
    }

    function collectBlocks() {
        let nearestBlock = findNearest(blocks, agentX, agentY);
        if (nearestBlock) {
            moveToward(nearestBlock);
            if (isNear(agentX, agentY, nearestBlock)) {
                pickUpBlock(nearestBlock);
            }
        }
    }

    function eatFood(food) {
        container.removeChild(food);
        foods = foods.filter(f => f !== food);
        foodCollected++;
        health = Math.min(100, health + 20);
        updateStatus();
    }

    function toggleTemperatureCycle() {
        isHotCycle = !isHotCycle;
        container.style.backgroundColor = isHotCycle ? '#ffcccc' : '#cce7ff';
        if (!isHotCycle) {
            if (foodCollected < 9) {
                consecutiveLowFoodCycles++;
                if (consecutiveLowFoodCycles >= 5) {
                    clearInterval(simulationInterval);
                    alert('Game Over! Agent starved.');
                    resetSimulation();
                }
            } else {
                consecutiveLowFoodCycles = 0;
            }
            foodCollected = 0;
            createRandomFood(12);
        }
        updateStatus();
    }

    function updateCountdown() {
        countdown.textContent = `Time Left: ${Math.round(timeLeft)}s`;
        timeLeft -= 0.016;
        if (timeLeft <= 0) {
            toggleTemperatureCycle();
            timeLeft = 120;
        }
    }

    function updateStatus() {
        status.textContent = `Health: ${Math.round(health)} | Food Collected: ${foodCollected} | Reward Points: ${rewardPoints} | Temperature: ${isHotCycle ? 'Hot' : 'Cool'} | Consecutive Low Food Cycles: ${consecutiveLowFoodCycles}`;
    }

    function resetSimulation() {
        agentX = targetX = 20;
        agentY = targetY = 20;
        health = 100;
        foodCollected = 0;
        rewardPoints = 0;
        timeLeft = 120;
        isHotCycle = false;
        isCarryingBlock = false;
        carriedBlock = null;
        shelterBlocks = [];
        timeUnderShelter = 0;
        consecutiveLowFoodCycles = 0;
        blocks.forEach(block => container.removeChild(block));
        foods.forEach(food => container.removeChild(food));
        blocks = [];
        foods = [];
        createRandomBlocks(20);
        createRandomFood(12);
        updateAgentPosition();
        updateStatus();
    }

    function startSimulation() {
        resetSimulation();
        simulationInterval = setInterval(() => {
            updateCountdown();
            updateHealth();
            aiDecision();
            updateAgentPosition();
            updateStatus();
        }, 16); // ~60 FPS for smoother animation
    }

    // Initialize the simulation
    updateAgentPosition();
    startSimulation();

    // Optional: Add event listener for manual reset
    document.addEventListener('keydown', (event) => {
        if (event.key === 'r' || event.key === 'R') {
            clearInterval(simulationInterval);
            startSimulation();
        }
    });
    </script>
</body>
</html>