zeroed-some/bashamole / 9bb5d95

Browse files

random starting position

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
9bb5d9528f220d2bf02c391492f531d335280991
Parents
4f93540
Tree
cd00891

2 changed files

StatusFile+-
M backend/apps/trees/models.py 41 0
M frontend/src/components/Game.tsx 27 8
backend/apps/trees/models.pymodified
@@ -52,6 +52,9 @@ class FileSystemTree(models.Model):
5252
         # Place the mole in a random directory (not in standard FHS locations)
5353
         self._place_mole()
5454
         
55
+        # Set random starting position for player
56
+        self._set_random_start_position()
57
+        
5558
         # Cache the tree structure
5659
         self.cache_tree()
5760
         self.save()
@@ -194,6 +197,44 @@ class FileSystemTree(models.Model):
194197
             mole_dir = random.choice(candidates)
195198
             self.mole_location = mole_dir.path
196199
     
200
+    def _set_random_start_position(self):
201
+        """Set a random starting position for the player"""
202
+        # Get all directories that could be valid starting positions
203
+        # Exclude root and very deep directories (depth > 3)
204
+        candidates = DirectoryNode.objects.filter(
205
+            tree=self
206
+        ).exclude(
207
+            path="/"  # Don't start at root
208
+        )
209
+        
210
+        # Filter to reasonable starting positions
211
+        valid_starts = []
212
+        for node in candidates:
213
+            depth = node.path.count('/')
214
+            # Prefer directories at depth 1-3
215
+            if 1 <= depth <= 3:
216
+                # Don't start at the mole location
217
+                if node.path != self.mole_location:
218
+                    valid_starts.append(node)
219
+        
220
+        if valid_starts:
221
+            # Weight selection towards common starting areas but allow anywhere
222
+            weights = []
223
+            for node in valid_starts:
224
+                if node.path.startswith('/home'):
225
+                    weights.append(3)  # Higher weight for home directories
226
+                elif node.path.startswith('/usr'):
227
+                    weights.append(2)  # Medium weight for usr directories
228
+                else:
229
+                    weights.append(1)  # Lower weight for other directories
230
+            
231
+            # Select random starting position with weights
232
+            start_node = random.choices(valid_starts, weights=weights, k=1)[0]
233
+            self.player_location = start_node.path
234
+        else:
235
+            # Fallback to /home if no valid candidates
236
+            self.player_location = "/home"
237
+    
197238
     def cache_tree(self):
198239
         """Cache the tree structure for efficient retrieval"""
199240
         def build_tree_dict(node):
frontend/src/components/Game.tsxmodified
@@ -60,9 +60,26 @@ const Game: React.FC = () => {
6060
         loading: false,
6161
         error: null,
6262
       });
63
+      
64
+      // Create a more dynamic starting message based on random location
65
+      const startLocation = response.tree.player_location;
66
+      let locationContext = '';
67
+      
68
+      if (startLocation.startsWith('/home')) {
69
+        locationContext = "You've been dropped in someone's home directory. ";
70
+      } else if (startLocation.startsWith('/usr')) {
71
+        locationContext = "You're in the system's usr hierarchy. ";
72
+      } else if (startLocation.startsWith('/var')) {
73
+        locationContext = "You're somewhere in the variable data area. ";
74
+      } else if (startLocation.startsWith('/opt')) {
75
+        locationContext = "You're in the optional packages directory. ";
76
+      } else {
77
+        locationContext = "You've been placed somewhere in the filesystem. ";
78
+      }
79
+      
6380
       setCommandHistory([{
6481
         command: 'Hunt started!',
65
-        output: response.mole_hint + '\nType "help" for available commands.',
82
+        output: `${response.mole_hint}\n${locationContext}Use 'pwd' to see where you are.\nType "help" for available commands.`,
6683
         success: true,
6784
       }]);
6885
       setHints([]);
@@ -162,11 +179,7 @@ const Game: React.FC = () => {
162179
     return treeData;
163180
   };
164181
 
165
-  // Handle form submission
166
-  const handleSubmit = (e: React.FormEvent) => {
167
-    e.preventDefault();
168
-    executeCommand(command);
169
-  };
182
+
170183
 
171184
   // Handle node click in visualizer
172185
   const handleNodeClick = (path: string) => {
@@ -301,13 +314,19 @@ const Game: React.FC = () => {
301314
               <span className="text-gray-400 mx-1">::</span>
302315
               <span className="text-blue-400">{gameState.tree?.player_location || '~'}</span>
303316
               <span className="text-gray-400 ml-1">$</span>
304
-              <form onSubmit={handleSubmit} className="flex-1 ml-2">
317
+              <div className="flex-1 ml-2">
305318
                 <div className="relative">
306319
                   <input
307320
                     ref={inputRef}
308321
                     type="text"
309322
                     value={command}
310323
                     onChange={(e) => setCommand(e.target.value)}
324
+                    onKeyDown={(e) => {
325
+                      if (e.key === 'Enter') {
326
+                        e.preventDefault();
327
+                        executeCommand(command);
328
+                      }
329
+                    }}
311330
                     disabled={executing || gameState.tree?.is_completed}
312331
                     className="w-full bg-transparent text-gray-300 outline-none caret-transparent"
313332
                     placeholder=""
@@ -328,7 +347,7 @@ const Game: React.FC = () => {
328347
                     _
329348
                   </span>
330349
                 </div>
331
-              </form>
350
+              </div>
332351
             </div>
333352
           </div>
334353
         )}