Daniel Garcia Costa пре 1 месец
родитељ
комит
a441f9aba7
1 измењених фајлова са 275 додато и 0 уклоњено
  1. 275 0
      GUI/index.html

+ 275 - 0
GUI/index.html

@@ -0,0 +1,275 @@
+<!DOCTYPE html>
+<html lang="es">
+<head>
+    <meta charset="UTF-8">
+    <title>Player Simulator</title>
+
+    <!-- Bootstrap 5 -->
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
+    
+    <style>
+        body {
+            background-color: #f5f6fa;
+        }
+        .log {
+            background: #1e1e1e;
+            color: #00ff9c;
+            height: 220px;
+            overflow-y: auto;
+            font-family: monospace;
+            padding: 10px;
+            border-radius: 5px;
+            font-size: 0.85rem;
+        }
+
+    </style>
+</head>
+
+<body>
+
+<div class="container my-4">
+    <h1 class="mb-4 text-center">🌍 - Player Simulator</h1>
+
+    <div class="row g-4">
+
+        <div class="col-md-12">
+            <div class="alert alert-primary">
+                🧑 Jugador actual: <strong id="playerId"></strong>
+            </div>
+        </div>
+
+        <!-- Acciones manuales -->
+        <div class="col-md-6">
+            <div class="card shadow-sm">
+                <div class="card-header bg-primary text-white">
+                    🎮 Acciones manuales
+                </div>
+                <div class="card-body d-flex flex-wrap gap-2">
+                    <button class="btn btn-outline-primary" onclick="sendAction('EXPLORE')">🧭 Explorar</button>
+                    <button class="btn btn-outline-success" onclick="sendAction('GATHER')">🌿 Recolectar</button>
+                    <button class="btn btn-outline-danger" onclick="sendAction('FIGHT')">⚔ Combatir</button>
+                    <button class="btn btn-outline-secondary" onclick="sendAction('REST')">💤 Descansar</button>
+                </div>
+            </div>
+        </div>
+
+        <!-- Acciones automáticas fijas -->
+        <div class="col-md-6">
+            <div class="card shadow-sm">
+                <div class="card-header bg-warning">
+                    ⏱ Acciones automáticas
+                </div>
+                <div class="card-body">
+                    <div class="row g-2">
+                        <div class="col-md-6">
+                            <label class="form-label">Acción</label>
+                            <select id="autoAction" class="form-select">
+                                <option value="EXPLORE">Explorar</option>
+                                <option value="GATHER">Recolectar</option>
+                                <option value="FIGHT">Combatir</option>
+                                <option value="REST">Descansar</option>
+                            </select>
+                        </div>
+                        <div class="col-md-6">
+                            <label class="form-label">Cada (ms)</label>
+                            <input type="number" id="interval" class="form-control" value="2000">
+                        </div>
+                    </div>
+
+                    <div class="mt-3 d-flex gap-2">
+                        <button class="btn btn-success" onclick="startAuto()">▶ Iniciar</button>
+                        <button class="btn btn-danger" onclick="stopAuto()">⏹ Detener</button>
+                        <span class="badge bg-secondary align-self-center" id="autoStatus">Detenido</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- Simulación aleatoria -->
+        <div class="col-md-6">
+            <div class="card shadow-sm">
+                <div class="card-header bg-dark text-white">
+                    🎲 Simulación aleatoria
+                </div>
+                <div class="card-body">
+                    <label class="form-label">Intervalo (ms)</label>
+                    <input type="number" id="randomInterval" class="form-control mb-3" value="1000">
+
+                    <div class="d-flex gap-2">
+                        <button class="btn btn-success" onclick="startRandomSimulation()">🎲 Iniciar</button>
+                        <button class="btn btn-danger" onclick="stopRandomSimulation()">⏹ Detener</button>
+                        <span class="badge bg-secondary align-self-center" id="randomStatus">Detenida</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- Consultas -->
+        <div class="col-md-6">
+            <div class="card shadow-sm">
+                <div class="card-header bg-info text-white">
+                    📊 Consultas
+                </div>
+                <div class="card-body d-flex flex-wrap gap-2">
+                    <button class="btn btn-outline-info" onclick="fetchState()">🌍 Estado del mundo</button>
+                    <button class="btn btn-outline-info" onclick="fetchStats()">👤 Stats del jugador</button>
+                </div>
+            </div>
+        </div>
+
+        <!-- Log -->
+        <div class="col-12">
+            <div class="card shadow-sm">
+                <div class="card-header bg-secondary text-white">
+                    🧾 Log de eventos
+                </div>
+                <div class="card-body">
+                    <div class="log" id="log"></div>
+                </div>
+            </div>
+        </div>
+
+    </div>
+</div>
+
+<script>
+    const WORLD_API = "http://localhost:8080/world";
+    const ACTIONS = ["EXPLORE", "GATHER", "FIGHT", "REST"];
+
+    let autoTimer = null;
+    let randomTimer = null;
+
+    function generatePlayerId() {
+        return "player-" + crypto.randomUUID();
+    }
+
+    let playerId = localStorage.getItem("playerId");
+
+    if (!playerId) {
+        playerId = generatePlayerId();
+        localStorage.setItem("playerId", playerId);
+    }
+
+    document.addEventListener("DOMContentLoaded", () => {
+        document.getElementById("playerId").innerText = playerId;
+        log(`Jugador registrado con id: ${playerId}`);
+    });
+
+
+    
+function log(message) {
+    const logDiv = document.getElementById("log");
+
+    let output;
+
+    if (typeof message === "object") {
+        output = JSON.stringify(message, null, 2);
+    } 
+    else if (typeof message === "string") {
+        try {
+            const parsed = JSON.parse(message);
+            output = JSON.stringify(parsed, null, 2);
+        } catch {
+            output = message;
+        }
+    } 
+    else {
+        output = String(message);
+    }
+
+    const entry = document.createElement("pre");
+    entry.textContent = output;
+
+    logDiv.appendChild(entry);
+    logDiv.scrollTop = logDiv.scrollHeight;
+}
+
+
+    function sendAction(action) {
+        console.log('sending action '+action);
+        fetch(`${WORLD_API}/action`, {
+            method: "POST",
+            headers: {
+                "Content-Type": "application/json"
+            },
+            body: JSON.stringify({
+                playerId: playerId,
+                action: action
+            })
+        })
+        .then(res => res.json())
+        .then(data => { 
+            log(`➡ Acción (${action}): `); 
+            log(data); 
+        })
+        .catch(err => { log(`❌ Error (${action}): ${err}`); });
+    }
+
+    function fetchState() {
+        fetch(`${WORLD_API}/state`)
+            .then(res => res.json())
+            .then(data => {
+                log(`🌍 Estado mundo: `);
+                log(data);
+            })
+            .catch(err => log("❌ Error al obtener el estado del mundo"));
+    }
+
+    function fetchStats() {
+        fetch(`${WORLD_API}/players/${playerId}/stats`)
+            .then(res => res.json())
+            .then(data => {
+                log(`📊 Stats jugador:`);
+                log(data);
+            })
+            .catch(err => log("❌ Error al obtener estadísticas"));
+    }
+
+    function startAuto() {
+        if (autoTimer) return;
+
+        const action = document.getElementById("autoAction").value;
+        const interval = parseInt(document.getElementById("interval").value);
+
+        autoTimer = setInterval(() => sendAction(action), interval);
+
+        document.getElementById("autoStatus").className = "badge bg-success";
+        document.getElementById("autoStatus").innerText = "En ejecución";
+        log(`▶ Acción automática: ${action} cada ${interval} ms`);
+    }
+
+    function stopAuto() {
+        clearInterval(autoTimer);
+        autoTimer = null;
+
+        document.getElementById("autoStatus").className = "badge bg-secondary";
+        document.getElementById("autoStatus").innerText = "Detenido";
+        log(`⏹ Acción automática detenida`);
+    }
+
+    function startRandomSimulation() {
+        if (randomTimer) return;
+
+        const interval = parseInt(document.getElementById("randomInterval").value);
+        randomTimer = setInterval(() => {
+            const action = ACTIONS[Math.floor(Math.random() * ACTIONS.length)];
+            sendAction(action);
+        }, interval);
+
+        document.getElementById("randomStatus").className = "badge bg-success";
+        document.getElementById("randomStatus").innerText = "En ejecución";
+        log(`🎲 Simulación aleatoria cada ${interval} ms`);
+    }
+
+    function stopRandomSimulation() {
+        clearInterval(randomTimer);
+        randomTimer = null;
+
+        document.getElementById("randomStatus").className = "badge bg-secondary";
+        document.getElementById("randomStatus").innerText = "⛔ Detenida";
+        log(`⏹ Simulación aleatoria detenida`);
+    }
+</script>
+
+</body>
+</html>