about summary refs log tree commit diff stats
path: root/html/broughlike
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-12-02 21:09:16 -0500
committerelioat <elioat@tilde.institute>2024-12-02 21:09:16 -0500
commit5db4d92b3a6e2db45df6e471d676fd78b07be1f3 (patch)
treec985fd80464870cd93dbb1347f8b1e57c948910f /html/broughlike
parent2ffdc2c8b757571c934a64d5289ffcf9766c860a (diff)
downloadtour-5db4d92b3a6e2db45df6e471d676fd78b07be1f3.tar.gz
*
Diffstat (limited to 'html/broughlike')
-rw-r--r--html/broughlike/broughlike.js184
1 files changed, 148 insertions, 36 deletions
diff --git a/html/broughlike/broughlike.js b/html/broughlike/broughlike.js
index 87718f3..5e82ebb 100644
--- a/html/broughlike/broughlike.js
+++ b/html/broughlike/broughlike.js
@@ -1,7 +1,5 @@
 import { CONFIG, COLORS, CANVAS } from './config.js';
 
-const DEBUG = false;
-
 let highScore = localStorage.getItem('highScore') || 0;
 const player = {
     x: 0,
@@ -673,7 +671,7 @@ function resetGame() {
     generateEnemies();
     generateItems();
     render();
-    if (DEBUG)
+    if (AUTO_PLAY)
         autoPlay();
 }
 
@@ -697,7 +695,7 @@ function checkPlayerAtExit() {
         generateEnemies();
         generateItems();
         render();
-        if (DEBUG)
+        if (AUTO_PLAY)
             autoPlay();
     }
 }
@@ -793,40 +791,146 @@ render();
 
 
 
-function autoPlay() {
 
+
+
+function autoPlay() {
+    let lastPosition = { x: player.x, y: player.y };
+    let stuckCounter = 0;
+    
     const playerAtExit = () => player.x === exit.x && player.y === exit.y;
     const playerCanMove = (dx, dy) => isValidMove(player.x + dx, player.y + dy);
-    const playerCanAttack = (enemy) => Math.abs(enemy.x - player.x) + Math.abs(enemy.y - player.y) === 10;
+    
+    const checkIfStuck = () => {
+        if (lastPosition.x === player.x && lastPosition.y === player.y) {
+            stuckCounter++;
+        } else {
+            stuckCounter = 0;
+            lastPosition = { x: player.x, y: player.y };
+        }
+        return stuckCounter > 3; // Consider yourself stuck after 3 turns in the same position
+    };
 
-    const movePlayerTowardsExit = () => {
-        const path = findPath(player, exit);
-        if (path.length > 1) {
-            const nextStep = path[1];
-            const dx = nextStep.x - player.x;
-            const dy = nextStep.y - player.y;
+    const desperateEscape = () => {
+        const allDirections = [
+            {dx: 1, dy: 0}, {dx: -1, dy: 0},
+            {dx: 0, dy: 1}, {dx: 0, dy: -1},
+            {dx: 1, dy: 1}, {dx: -1, dy: 1},
+            {dx: 1, dy: -1}, {dx: -1, dy: -1}
+        ];
+        
+        allDirections.sort(() => Math.random() - 0.5);
+        
+        for (const {dx, dy} of allDirections) {
             if (playerCanMove(dx, dy)) {
                 movePlayer(dx, dy);
+                return true;
             }
         }
+        return false;
     };
 
-    const attackEnemies = () => {
-        const enemiesInRange = enemies.filter(enemy => playerCanAttack(enemy));
-        if (enemiesInRange.length > 0) {
-            const randomIndex = Math.floor(Math.random() * enemiesInRange.length);
-            const targetEnemy = enemiesInRange[randomIndex];
-            const dx = targetEnemy.x - player.x;
-            const dy = targetEnemy.y - player.y;
-            movePlayer(dx, dy);
+    const hasAdjacentEnemy = (x, y) => {
+        return enemies.some(enemy => 
+            Math.abs(enemy.x - x) + Math.abs(enemy.y - y) === 1
+        );
+    };
+
+    const findNearestItem = () => {
+        if (items.length === 0) return null;
+        return items.reduce((nearest, item) => {
+            const distToCurrent = Math.abs(player.x - item.x) + Math.abs(player.y - item.y);
+            const distToNearest = nearest ? Math.abs(player.x - nearest.x) + Math.abs(player.y - nearest.y) : Infinity;
+            return distToCurrent < distToNearest ? item : nearest;
+        }, null);
+    };
+
+    const decideNextTarget = () => {
+
+        const healingItem = items.find(item => 
+            item.type === 'pentagon' && 
+            player.health < CONFIG.PLAYER_HEALTH * 0.5
+        );
+        if (healingItem) return healingItem;
+
+        const nearestItem = findNearestItem();
+        if (nearestItem && Math.abs(player.x - nearestItem.x) + Math.abs(player.y - nearestItem.y) < 5) {
+            return nearestItem;
         }
+
+        return exit;
     };
 
-    const collectItem = () => {
-        const item = items.find(item => item.x === player.x && item.y === player.y);
-        if (item) {
-            handleItemCollection();
+    const moveTowardsTarget = (target) => {
+        const path = findPath(player, target);
+        if (path.length > 1) {
+            const nextStep = path[1];
+            
+            if (Math.random() < 0.2) {
+                const alternateDirections = [
+                    {dx: 1, dy: 0}, {dx: -1, dy: 0},
+                    {dx: 0, dy: 1}, {dx: 0, dy: -1}
+                ].filter(({dx, dy}) => 
+                    playerCanMove(dx, dy) && 
+                    !hasAdjacentEnemy(player.x + dx, player.y + dy)
+                );
+                
+                if (alternateDirections.length > 0) {
+                    const randomDir = alternateDirections[Math.floor(Math.random() * alternateDirections.length)];
+                    movePlayer(randomDir.dx, randomDir.dy);
+                    return true;
+                }
+            }
+            
+            if (!hasAdjacentEnemy(nextStep.x, nextStep.y)) {
+                const dx = nextStep.x - player.x;
+                const dy = nextStep.y - player.y;
+                if (playerCanMove(dx, dy)) {
+                    movePlayer(dx, dy);
+                    return true;
+                }
+            }
         }
+        return false;
+    };
+
+    const handleCombat = () => {
+        const adjacentEnemy = enemies.find(enemy => 
+            Math.abs(enemy.x - player.x) + Math.abs(enemy.y - player.y) === 1
+        );
+        
+        if (adjacentEnemy) {
+            // Increase the chance of retreating when stuck
+            const retreatChance = checkIfStuck() ? 0.8 : 0.3;
+            
+            if (Math.random() < retreatChance) {
+                const retreatDirections = [
+                    {dx: 1, dy: 0}, {dx: -1, dy: 0},
+                    {dx: 0, dy: 1}, {dx: 0, dy: -1}
+                ];
+                
+                retreatDirections.sort(() => Math.random() - 0.5);
+                
+                for (const {dx, dy} of retreatDirections) {
+                    if (playerCanMove(dx, dy) && !hasAdjacentEnemy(player.x + dx, player.y + dy)) {
+                        movePlayer(dx, dy);
+                        return true;
+                    }
+                }
+            }
+            
+            // If stuck, try desperate escape
+            if (checkIfStuck()) {
+                return desperateEscape();
+            }
+            
+            // Attack if can't retreat
+            const dx = adjacentEnemy.x - player.x;
+            const dy = adjacentEnemy.y - player.y;
+            movePlayer(dx, dy);
+            return true;
+        }
+        return false;
     };
 
     const play = () => {
@@ -834,22 +938,30 @@ function autoPlay() {
             return;
         }
 
-        movePlayerTowardsExit();
-
-        enemies.forEach(enemy => {
-            if (playerCanAttack(enemy)) {
-                attackEnemies(enemy);
-            }
-        });
-
-        collectItem();
+        // If stuck, try desperate escape
+        if (checkIfStuck() && desperateEscape()) {
+            // Successfully escaped
+        } else if (!handleCombat()) {
+            // If no combat, move towards the next target
+            const target = decideNextTarget();
+            moveTowardsTarget(target);
+        }
 
-        setTimeout(play, 1000);
+        setTimeout(play, 400); // 400ms is about 1.5 moves per second because 1000ms was terribly slow.
     };
 
     play();
 }
 
+let AUTO_PLAY = false;
 
-if (DEBUG)
-    autoPlay();
\ No newline at end of file
+document.addEventListener('keydown', (e) => {
+    if (e.key === 'v') {
+        // alert to confirm that the user wants to toggle auto play
+        if (confirm("Are you sure you want to toggle auto play? Once auto play is turned on, the only way to turn it off is to reload the page.")) {
+            AUTO_PLAY = !AUTO_PLAY;
+            if (AUTO_PLAY)
+                autoPlay();
+        }
+    }
+});
\ No newline at end of file