CoolFace
Datasetpublic

ysn-rfd/text-dataset-tiny-code-script-py-format

USED of tahamajs/medicine_ds_persian for .parquet file USED of Alijafarixcs2/persian-it-llama2-2k for .parquet file USED of Abirate/english_quotes for .jsonl file NEW FILES (05/12/2025) NEW FILES (12/26/2025) NEW FILES (02/15/2026)

sourceHugging Faceapache-2.0updated 4mo agoView on Hugging Face
3likes1.6kdownloads
Python_Script_Text_based_RPD_Game2.py1621 linesDownload Raw Back to Workspace
1import os
2import sys
3import json
4import random
5import time
6import math
7import pickle
8import importlib
9from enum import Enum
10from dataclasses import dataclass, field
11from typing import Dict, List, Optional, Tuple, Callable, Any, Union
12from abc import ABC, abstractmethod
13
14# Color codes for terminal output
15class Colors:
16    RESET = '\033[0m'
17    BLACK = '\033[30m'
18    RED = '\033[31m'
19    GREEN = '\033[32m'
20    YELLOW = '\033[33m'
21    BLUE = '\033[34m'
22    MAGENTA = '\033[35m'
23    CYAN = '\033[36m'
24    WHITE = '\033[37m'
25    BRIGHT_BLACK = '\033[90m'
26    BRIGHT_RED = '\033[91m'
27    BRIGHT_GREEN = '\033[92m'
28    BRIGHT_YELLOW = '\033[93m'
29    BRIGHT_BLUE = '\033[94m'
30    BRIGHT_MAGENTA = '\033[95m'
31    BRIGHT_CYAN = '\033[96m'
32    BRIGHT_WHITE = '\033[97m'
33    BG_BLACK = '\033[40m'
34    BG_RED = '\033[41m'
35    BG_GREEN = '\033[42m'
36    BG_YELLOW = '\033[43m'
37    BG_BLUE = '\033[44m'
38    BG_MAGENTA = '\033[45m'
39    BG_CYAN = '\033[46m'
40    BG_WHITE = '\033[47m'
41
42# Game Enums
43class Direction(Enum):
44    NORTH = "north"
45    SOUTH = "south"
46    EAST = "east"
47    WEST = "west"
48    NORTHEAST = "northeast"
49    NORTHWEST = "northwest"
50    SOUTHEAST = "southeast"
51    SOUTHWEST = "southwest"
52    UP = "up"
53    DOWN = "down"
54
55class SkillType(Enum):
56    COMBAT = "combat"
57    MAGIC = "magic"
58    STEALTH = "stealth"
59    CRAFTING = "crafting"
60    SOCIAL = "social"
61    SURVIVAL = "survival"
62
63class Weather(Enum):
64    CLEAR = "clear"
65    CLOUDY = "cloudy"
66    RAINY = "rainy"
67    STORMY = "stormy"
68    SNOWY = "snowy"
69    FOGGY = "foggy"
70
71class TimeOfDay(Enum):
72    DAWN = "dawn"
73    MORNING = "morning"
74    NOON = "noon"
75    AFTERNOON = "afternoon"
76    DUSK = "dusk"
77    EVENING = "evening"
78    NIGHT = "night"
79    MIDNIGHT = "midnight"
80
81# Data Classes
82@dataclass
83class Position:
84    x: int = 0
85    y: int = 0
86    z: int = 0
87
88@dataclass
89class Stats:
90    health: int = 100
91    max_health: int = 100
92    mana: int = 50
93    max_mana: int = 50
94    stamina: int = 100
95    max_stamina: int = 100
96    hunger: int = 100
97    max_hunger: int = 100
98    thirst: int = 100
99    max_thirst: int = 100
100    experience: int = 0
101    level: int = 1
102    
103    def level_up(self):
104        self.level += 1
105        self.experience = 0
106        self.max_health += 10
107        self.health = self.max_health
108        self.max_mana += 5
109        self.mana = self.max_mana
110        self.max_stamina += 5
111        self.stamina = self.max_stamina
112
113@dataclass
114class Skill:
115    name: str
116    type: SkillType
117    level: int = 1
118    experience: int = 0
119    max_experience: int = 100
120    
121    def gain_experience(self, amount: int):
122        self.experience += amount
123        while self.experience >= self.max_experience:
124            self.experience -= self.max_experience
125            self.level += 1
126            self.max_experience = int(self.max_experience * 1.5)
127            return True  # Leveled up
128        return False
129
130@dataclass
131class Item:
132    id: str
133    name: str
134    description: str
135    value: int = 0
136    weight: float = 1.0
137    consumable: bool = False
138    equippable: bool = False
139    stackable: bool = True
140    max_stack: int = 99
141    effects: Dict[str, Any] = field(default_factory=dict)
142    
143    def use(self, player):
144        if self.consumable:
145            for stat, value in self.effects.items():
146                if hasattr(player.stats, stat):
147                    current = getattr(player.stats, stat)
148                    max_stat = getattr(player.stats, f"max_{stat}")
149                    setattr(player.stats, stat, min(max_stat, current + value))
150            return True
151        return False
152
153@dataclass
154class Weapon(Item):
155    damage: int = 10
156    damage_type: str = "physical"
157    two_handed: bool = False
158    range: int = 1
159    
160    def __post_init__(self):
161        self.equippable = True
162
163@dataclass
164class Armor(Item):
165    defense: int = 5
166    armor_type: str = "light"
167    slot: str = "chest"
168    
169    def __post_init__(self):
170        self.equippable = True
171
172@dataclass
173class Quest:
174    id: str
175    name: str
176    description: str
177    objectives: List[str]
178    rewards: Dict[str, Any]
179    completed: bool = False
180    active: bool = False
181
182@dataclass
183class NPC:
184    id: str
185    name: str
186    description: str
187    dialogue: Dict[str, List[str]]
188    location_id: str
189    hostile: bool = False
190    stats: Stats = field(default_factory=Stats)
191    inventory: List[Item] = field(default_factory=list)
192    quests: List[Quest] = field(default_factory=list)
193    faction: str = "neutral"
194    
195    def talk(self, topic="greeting"):
196        if topic in self.dialogue:
197            return random.choice(self.dialogue[topic])
198        return "I don't have anything to say about that."
199
200@dataclass
201class Location:
202    id: str
203    name: str
204    description: str
205    exits: Dict[Direction, str] = field(default_factory=dict)
206    items: List[Item] = field(default_factory=list)
207    npcs: List[NPC] = field(default_factory=list)
208    discovered: bool = False
209    indoor: bool = False
210    position: Position = field(default_factory=Position)
211    
212    def add_exit(self, direction: Direction, location_id: str):
213        self.exits[direction] = location_id
214    
215    def add_item(self, item: Item):
216        self.items.append(item)
217    
218    def add_npc(self, npc: NPC):
219        self.npcs.append(npc)
220    
221    def remove_item(self, item: Item):
222        if item in self.items:
223            self.items.remove(item)
224            return True
225        return False
226    
227    def remove_npc(self, npc: NPC):
228        if npc in self.npcs:
229            self.npcs.remove(npc)
230            return True
231        return False
232
233# Plugin System
234class Plugin(ABC):
235    @abstractmethod
236    def initialize(self, game):
237        pass
238    
239    @abstractmethod
240    def get_commands(self) -> Dict[str, Callable]:
241        return {}
242
243# Game Classes
244class GameWorld:
245    def __init__(self):
246        self.locations: Dict[str, Location] = {}
247        self.global_time: int = 0  # Game time in minutes
248        self.weather: Weather = Weather.CLEAR
249        self.time_of_day: TimeOfDay = TimeOfDay.MORNING
250        self.day_count: int = 1
251        
252    def add_location(self, location: Location):
253        self.locations[location.id] = location
254    
255    def get_location(self, location_id: str) -> Optional[Location]:
256        return self.locations.get(location_id)
257    
258    def update_time(self, minutes: int = 1):
259        self.global_time += minutes
260        # Update day count (each day is 1440 minutes)
261        self.day_count = (self.global_time // 1440) + 1
262        
263        # Update time of day (each period is 3 hours = 180 minutes)
264        time_periods = list(TimeOfDay)
265        period_index = (self.global_time // 180) % len(time_periods)
266        self.time_of_day = time_periods[period_index]
267        
268        # Randomly change weather
269        if random.random() < 0.05:  # 5% chance of weather change
270            self.weather = random.choice(list(Weather))
271    
272    def get_time_description(self) -> str:
273        return f"Day {self.day_count}, {self.time_of_day.value.capitalize()}, Weather: {self.weather.value.capitalize()}"
274
275class Player:
276    def __init__(self, name: str):
277        self.name: str = name
278        self.location_id: str = "start"
279        self.stats: Stats = Stats()
280        self.inventory: Dict[str, Tuple[Item, int]] = {}  # item_id: (item, quantity)
281        self.equipped: Dict[str, Item] = {}  # slot: item
282        self.skills: Dict[str, Skill] = {
283            "combat": Skill("Combat", SkillType.COMBAT),
284            "magic": Skill("Magic", SkillType.MAGIC),
285            "stealth": Skill("Stealth", SkillType.STEALTH),
286            "crafting": Skill("Crafting", SkillType.CRAFTING),
287            "social": Skill("Social", SkillType.SOCIAL),
288            "survival": Skill("Survival", SkillType.SURVIVAL)
289        }
290        self.quests: List[Quest] = []
291        self.known_locations: List[str] = ["start"]
292        self.faction_reputation: Dict[str, int] = {}
293        
294    def add_item(self, item: Item, quantity: int = 1):
295        if item.id in self.inventory:
296            current_item, current_quantity = self.inventory[item.id]
297            if item.stackable:
298                new_quantity = min(current_quantity + quantity, item.max_stack)
299                self.inventory[item.id] = (current_item, new_quantity)
300                return quantity - (new_quantity - current_quantity)  # Return leftover quantity
301            else:
302                # For non-stackable items, add multiple entries
303                for _ in range(quantity):
304                    self.inventory[f"{item.id}_{len(self.inventory)}"] = (item, 1)
305                return 0
306        else:
307            self.inventory[item.id] = (item, quantity)
308            return 0
309    
310    def remove_item(self, item_id: str, quantity: int = 1) -> bool:
311        if item_id in self.inventory:
312            item, current_quantity = self.inventory[item_id]
313            if current_quantity <= quantity:
314                del self.inventory[item_id]
315                return True
316            else:
317                self.inventory[item_id] = (item, current_quantity - quantity)
318                return True
319        return False
320    
321    def has_item(self, item_id: str, quantity: int = 1) -> bool:
322        if item_id in self.inventory:
323            _, current_quantity = self.inventory[item_id]
324            return current_quantity >= quantity
325        return False
326    
327    def equip_item(self, item_id: str) -> bool:
328        if item_id in self.inventory:
329            item, _ = self.inventory[item_id]
330            if item.equippable:
331                # Determine slot based on item type
332                if isinstance(item, Weapon):
333                    slot = "weapon"
334                elif isinstance(item, Armor):
335                    slot = item.slot
336                else:
337                    slot = "accessory"
338                
339                # Unequip current item if any
340                if slot in self.equipped:
341                    self.add_item(self.equipped[slot])
342                
343                # Equip new item
344                self.equipped[slot] = item
345                self.remove_item(item_id)
346                return True
347        return False
348    
349    def unequip_item(self, slot: str) -> bool:
350        if slot in self.equipped:
351            item = self.equipped[slot]
352            self.add_item(item)
353            del self.equipped[slot]
354            return True
355        return False
356    
357    def get_total_defense(self) -> int:
358        defense = 0
359        for item in self.equipped.values():
360            if isinstance(item, Armor):
361                defense += item.defense
362        return defense
363    
364    def get_total_damage(self) -> int:
365        damage = 5  # Base damage
366        if "weapon" in self.equipped:
367            weapon = self.equipped["weapon"]
368            if isinstance(weapon, Weapon):
369                damage = weapon.damage
370        return damage
371    
372    def gain_experience(self, amount: int):
373        self.stats.experience += amount
374        exp_needed = self.stats.level * 100  # Simple formula
375        while self.stats.experience >= exp_needed:
376            self.stats.experience -= exp_needed
377            self.stats.level_up()
378            exp_needed = self.stats.level * 100
379            return True  # Leveled up
380        return False
381    
382    def add_quest(self, quest: Quest):
383        self.quests.append(quest)
384        quest.active = True
385    
386    def complete_quest(self, quest_id: str) -> bool:
387        for quest in self.quests:
388            if quest.id == quest_id and quest.active and not quest.completed:
389                quest.completed = True
390                # Apply rewards
391                if "experience" in quest.rewards:
392                    self.gain_experience(quest.rewards["experience"])
393                if "items" in quest.rewards:
394                    for item_id, quantity in quest.rewards["items"].items():
395                        # This would need a reference to the game world to get the actual item
396                        pass
397                if "reputation" in quest.rewards:
398                    for faction, amount in quest.rewards["reputation"].items():
399                        if faction in self.faction_reputation:
400                            self.faction_reputation[faction] += amount
401                        else:
402                            self.faction_reputation[faction] = amount
403                return True
404        return False
405    
406    def update_vitals(self):
407        # Decrease hunger and thirst over time
408        self.stats.hunger = max(0, self.stats.hunger - 1)
409        self.stats.thirst = max(0, self.stats.thirst - 1)
410        
411        # Apply effects of hunger and thirst
412        if self.stats.hunger == 0:
413            self.stats.health = max(0, self.stats.health - 2)
414        if self.stats.thirst == 0:
415            self.stats.health = max(0, self.stats.health - 3)
416        
417        # Regenerate health, mana, and stamina slowly
418        if self.stats.health < self.stats.max_health:
419            self.stats.health = min(self.stats.max_health, self.stats.health + 1)
420        if self.stats.mana < self.stats.max_mana:
421            self.stats.mana = min(self.stats.max_mana, self.stats.mana + 1)
422        if self.stats.stamina < self.stats.max_stamina:
423            self.stats.stamina = min(self.stats.max_stamina, self.stats.stamina + 2)
424
425class CombatSystem:
426    @staticmethod
427    def attack(attacker, defender):
428        # Calculate damage
429        base_damage = attacker.get_total_damage() if hasattr(attacker, 'get_total_damage') else 10
430        
431        # Add some randomness
432        damage = max(1, base_damage + random.randint(-2, 2))
433        
434        # Apply defense
435        defense = defender.get_total_defense() if hasattr(defender, 'get_total_defense') else 0
436        damage = max(1, damage - defense // 2)
437        
438        # Apply damage
439        defender.stats.health = max(0, defender.stats.health - damage)
440        
441        return damage
442    
443    @staticmethod
444    def check_flee(player, npc) -> bool:
445        # Base chance to flee is 50%, modified by player's level vs NPC's level
446        base_chance = 0.5
447        level_diff = player.stats.level - npc.stats.level
448        chance = base_chance + (level_diff * 0.1)
449        chance = max(0.1, min(0.9, chance))  # Clamp between 10% and 90%
450        
451        return random.random() < chance
452
453class Game:
454    def __init__(self):
455        self.world = GameWorld()
456        self.player = None
457        self.running = True
458        self.plugins: Dict[str, Plugin] = {}
459        self.commands: Dict[str, Callable] = {}
460        self.combat = CombatSystem()
461        self.in_combat = False
462        self.current_opponent = None
463        
464        # Initialize core commands
465        self.register_command("help", self.cmd_help)
466        self.register_command("quit", self.cmd_quit)
467        self.register_command("look", self.cmd_look)
468        self.register_command("go", self.cmd_go)
469        self.register_command("take", self.cmd_take)
470        self.register_command("inventory", self.cmd_inventory)
471        self.register_command("use", self.cmd_use)
472        self.register_command("equip", self.cmd_equip)
473        self.register_command("unequip", self.cmd_unequip)
474        self.register_command("talk", self.cmd_talk)
475        self.register_command("attack", self.cmd_attack)
476        self.register_command("flee", self.cmd_flee)
477        self.register_command("quests", self.cmd_quests)
478        self.register_command("skills", self.cmd_skills)
479        self.register_command("time", self.cmd_time)
480        self.register_command("save", self.cmd_save)
481        self.register_command("load", self.cmd_load)
482        self.register_command("wait", self.cmd_wait)
483        self.register_command("status", self.cmd_status)
484        self.register_command("drop", self.cmd_drop)
485        self.register_command("examine", self.cmd_examine)
486        self.register_command("map", self.cmd_map)
487        self.register_command("rest", self.cmd_rest)
488        self.register_command("plugins", self.cmd_plugins)
489        
490        # Initialize the game world
491        self.initialize_world()
492    
493    def register_command(self, name: str, func: Callable):
494        self.commands[name] = func
495    
496    def load_plugin(self, plugin_path: str):
497        try:
498            spec = importlib.util.spec_from_file_location("plugin", plugin_path)
499            plugin_module = importlib.util.module_from_spec(spec)
500            spec.loader.exec_module(plugin_module)
501            
502            # Get plugin class (should be named "Plugin")
503            if hasattr(plugin_module, "Plugin"):
504                plugin_class = getattr(plugin_module, "Plugin")
505                plugin = plugin_class()
506                plugin.initialize(self)
507                
508                # Register plugin commands
509                plugin_commands = plugin.get_commands()
510                for name, func in plugin_commands.items():
511                    self.register_command(name, func)
512                
513                self.plugins[plugin_path] = plugin
514                return True
515        except Exception as e:
516            print(f"{Colors.RED}Error loading plugin: {e}{Colors.RESET}")
517        return False
518    
519    def unload_plugin(self, plugin_path: str):
520        if plugin_path in self.plugins:
521            plugin = self.plugins[plugin_path]
522            plugin_commands = plugin.get_commands()
523            
524            # Unregister plugin commands
525            for name in plugin_commands:
526                if name in self.commands:
527                    del self.commands[name]
528            
529            del self.plugins[plugin_path]
530            return True
531        return False
532    
533    def initialize_world(self):
534        # Create starting location
535        start_location = Location(
536            id="start",
537            name="Starting Village",
538            description="A small village surrounded by forests and mountains. There's a path leading north to the forest and east to the mountains.",
539            position=Position(0, 0, 0)
540        )
541        
542        # Create forest location
543        forest_location = Location(
544            id="forest",
545            name="Dark Forest",
546            description="A dense forest with tall trees and little light. You can hear strange sounds in the distance.",
547            position=Position(0, 1, 0)
548        )
549        
550        # Create mountain location
551        mountain_location = Location(
552            id="mountain",
553            name="Mountain Pass",
554            description="A narrow path through the mountains. It's cold and windy here.",
555            position=Position(1, 0, 0)
556        )
557        
558        # Create cave location
559        cave_location = Location(
560            id="cave",
561            name="Mysterious Cave",
562            description="A dark cave with glowing crystals on the walls. You can hear dripping water.",
563            position=Position(0, 0, -1),
564            indoor=True
565        )
566        
567        # Create village shop
568        shop_location = Location(
569            id="shop",
570            name="Village Shop",
571            description="A small shop with various items for sale. The shopkeeper looks friendly.",
572            position=Position(-1, 0, 0),
573            indoor=True
574        )
575        
576        # Connect locations
577        start_location.add_exit(Direction.NORTH, "forest")
578        start_location.add_exit(Direction.EAST, "mountain")
579        start_location.add_exit(Direction.WEST, "shop")
580        
581        forest_location.add_exit(Direction.SOUTH, "start")
582        forest_location.add_exit(Direction.DOWN, "cave")
583        
584        mountain_location.add_exit(Direction.WEST, "start")
585        
586        cave_location.add_exit(Direction.UP, "forest")
587        
588        shop_location.add_exit(Direction.EAST, "start")
589        
590        # Add items to locations
591        # Starting village items
592        start_location.add_item(Item(
593            id="apple",
594            name="Apple",
595            description="A fresh red apple. Looks delicious.",
596            value=5,
597            consumable=True,
598            effects={"hunger": 20}
599        ))
600        
601        start_location.add_item(Item(
602            id="bread",
603            name="Bread",
604            description="A loaf of bread. Still warm.",
605            value=10,
606            consumable=True,
607            effects={"hunger": 40}
608        ))
609        
610        # Forest items
611        forest_location.add_item(Weapon(
612            id="sword",
613            name="Rusty Sword",
614            description="An old rusty sword. Better than nothing.",
615            value=25,
616            damage=15,
617            weight=3.0
618        ))
619        
620        forest_location.add_item(Item(
621            id="herb",
622            name="Healing Herb",
623            description="A green herb with medicinal properties.",
624            value=15,
625            consumable=True,
626            effects={"health": 20}
627        ))
628        
629        # Cave items
630        cave_location.add_item(Item(
631            id="crystal",
632            name="Magic Crystal",
633            description="A glowing crystal that hums with magical energy.",
634            value=100,
635            consumable=True,
636            effects={"mana": 50}
637        ))
638        
639        # Shop items
640        shop_location.add_item(Weapon(
641            id="dagger",
642            name="Dagger",
643            description="A sharp dagger. Good for quick attacks.",
644            value=30,
645            damage=10,
646            weight=1.0
647        ))
648        
649        shop_location.add_item(Armor(
650            id="leather_armor",
651            name="Leather Armor",
652            description="Simple armor made of leather. Provides basic protection.",
653            value=50,
654            defense=10,
655            armor_type="light",
656            slot="chest"
657        ))
658        
659        # Add NPCs
660        # Village elder
661        elder = NPC(
662            id="elder",
663            name="Village Elder",
664            description="An old man with a long white beard and wise eyes.",
665            dialogue={
666                "greeting": [
667                    "Welcome to our humble village, young adventurer.",
668                    "Ah, a new face. What brings you to our village?"
669                ],
670                "quest": [
671                    "We have a problem with wolves in the forest. Could you help us?",
672                    "The forest to the north has become dangerous. Please investigate."
673                ],
674                "help": [
675                    "You can use 'go [direction]' to move around.",
676                    "Try 'talk [npc]' to interact with people."
677                ]
678            },
679            location_id="start"
680        )
681        
682        # Add quest to elder
683        wolf_quest = Quest(
684            id="wolf_problem",
685            name="Wolf Problem",
686            description="Deal with the wolves in the forest.",
687            objectives=["Kill 5 wolves"],
688            rewards={
689                "experience": 100,
690                "items": {"gold": 50}
691            }
692        )
693        elder.quests.append(wolf_quest)
694        
695        # Shopkeeper
696        shopkeeper = NPC(
697            id="shopkeeper",
698            name="Shopkeeper",
699            description="A friendly-looking person with a big smile.",
700            dialogue={
701                "greeting": [
702                    "Welcome to my shop! Feel free to browse.",
703                    "Hello! Looking for something special?"
704                ],
705                "buy": [
706                    "What would you like to buy?",
707                    "Everything here is for sale, just name it."
708                ],
709                "sell": [
710                    "What do you want to sell me?",
711                    "I'll give you a fair price for your items."
712                ]
713            },
714            location_id="shop"
715        )
716        
717        # Forest wolf
718        wolf = NPC(
719            id="wolf",
720            name="Wolf",
721            description="A wild wolf with sharp teeth and hungry eyes.",
722            dialogue={},
723            location_id="forest",
724            hostile=True,
725            stats=Stats(health=50, max_health=50)
726        )
727        
728        # Add NPCs to locations
729        start_location.add_npc(elder)
730        shop_location.add_npc(shopkeeper)
731        forest_location.add_npc(wolf)
732        
733        # Add locations to world
734        self.world.add_location(start_location)
735        self.world.add_location(forest_location)
736        self.world.add_location(mountain_location)
737        self.world.add_location(cave_location)
738        self.world.add_location(shop_location)
739    
740    def start(self):
741        self.clear_screen()
742        self.print_title()
743        
744        # Character creation
745        name = input(f"{Colors.CYAN}Enter your character's name: {Colors.RESET}")
746        self.player = Player(name)
747        
748        # Welcome message
749        self.print_wrapped(f"{Colors.GREEN}Welcome, {self.player.name}!{Colors.RESET}")
750        self.print_wrapped("You find yourself in a small village. Your adventure begins here.")
751        self.print_wrapped("Type 'help' for a list of commands.")
752        self.print_separator()
753        
754        # Main game loop
755        while self.running:
756            if not self.in_combat:
757                # Update game world
758                self.world.update_time()
759                self.player.update_vitals()
760                
761                # Check if player is dead
762                if self.player.stats.health <= 0:
763                    self.game_over()
764                    break
765                
766                # Display location
767                self.display_location()
768            
769            # Get player input
770            try:
771                command_input = input(f"{Colors.YELLOW}> {Colors.RESET}").strip().lower()
772                if not command_input:
773                    continue
774                
775                # Parse command
776                parts = command_input.split()
777                command = parts[0]
778                args = parts[1:] if len(parts) > 1 else []
779                
780                # Execute command
781                if command in self.commands:
782                    self.commands[command](args)
783                else:
784                    print(f"{Colors.RED}Unknown command: {command}{Colors.RESET}")
785                    print(f"{Colors.CYAN}Type 'help' for a list of commands.{Colors.RESET}")
786                
787            except KeyboardInterrupt:
788                print("\nGoodbye!")
789                self.running = False
790            except EOFError:
791                print("\nGoodbye!")
792                self.running = False
793            except Exception as e:
794                print(f"{Colors.RED}Error: {e}{Colors.RESET}")
795    
796    def game_over(self):
797        self.clear_screen()
798        print(f"{Colors.RED}========================================{Colors.RESET}")
799        print(f"{Colors.RED}            GAME OVER{Colors.RESET}")
800        print(f"{Colors.RED}========================================{Colors.RESET}")
801        print(f"{Colors.WHITE}You have died.{Colors.RESET}")
802        print(f"{Colors.WHITE}Level reached: {self.player.stats.level}{Colors.RESET}")
803        print(f"{Colors.WHITE}Experience gained: {self.player.stats.experience}{Colors.RESET}")
804        print(f"{Colors.RED}========================================{Colors.RESET}")
805        self.running = False
806    
807    def clear_screen(self):
808        os.system('cls' if os.name == 'nt' else 'clear')
809    
810    def print_title(self):
811        print(f"{Colors.BRIGHT_CYAN}")
812        print("========================================")
813        print("       ULTIMATE OPEN WORLD GAME        ")
814        print("========================================")
815        print(f"{Colors.RESET}")
816    
817    def print_separator(self):
818        print(f"{Colors.BRIGHT_BLACK}----------------------------------------{Colors.RESET}")
819    
820    def print_wrapped(self, text, width=80):
821        words = text.split()
822        lines = []
823        current_line = []
824        current_length = 0
825        
826        for word in words:
827            if current_length + len(word) + 1 <= width:
828                current_line.append(word)
829                current_length += len(word) + 1
830            else:
831                lines.append(' '.join(current_line))
832                current_line = [word]
833                current_length = len(word)
834        
835        if current_line:
836            lines.append(' '.join(current_line))
837        
838        for line in lines:
839            print(line)
840    
841    def display_location(self):
842        location = self.world.get_location(self.player.location_id)
843        if not location:
844            return
845        
846        # Mark location as discovered
847        if not location.discovered:
848            location.discovered = True
849            if location.id not in self.player.known_locations:
850                self.player.known_locations.append(location.id)
851        
852        # Display location name
853        print(f"{Colors.BRIGHT_GREEN}{location.name}{Colors.RESET}")
854        
855        # Display location description
856        self.print_wrapped(f"{Colors.WHITE}{location.description}{Colors.RESET}")
857        
858        # Display time and weather
859        print(f"{Colors.CYAN}{self.world.get_time_description()}{Colors.RESET}")
860        
861        # Display exits
862        if location.exits:
863            exits = ", ".join([d.value for d in location.exits.keys()])
864            print(f"{Colors.YELLOW}Exits: {exits}{Colors.RESET}")
865        
866        # Display items
867        if location.items:
868            item_names = [f"{item.name} ({quantity})" if item.stackable else item.name 
869                         for item, quantity in [(item, 1) for item in location.items]]
870            print(f"{Colors.GREEN}Items: {', '.join(item_names)}{Colors.RESET}")
871        
872        # Display NPCs
873        if location.npcs:
874            npc_names = [npc.name for npc in location.npcs]
875            print(f"{Colors.MAGENTA}People: {', '.join(npc_names)}{Colors.RESET}")
876        
877        self.print_separator()
878    
879    # Command implementations
880    def cmd_help(self, args):
881        print(f"{Colors.CYAN}Available commands:{Colors.RESET}")
882        for command in sorted(self.commands.keys()):
883            print(f"  {Colors.YELLOW}{command}{Colors.RESET}")
884        print(f"\n{Colors.CYAN}For more information on a command, type: help [command]{Colors.RESET}")
885    
886    def cmd_quit(self, args):
887        print(f"{Colors.YELLOW}Are you sure you want to quit? (y/n){Colors.RESET}")
888        response = input("> ").strip().lower()
889        if response == 'y':
890            self.running = False
891    
892    def cmd_look(self, args):
893        self.display_location()
894    
895    def cmd_go(self, args):
896        if not args:
897            print(f"{Colors.RED}Go where?{Colors.RESET}")
898            return
899        
900        direction_str = args[0]
901        try:
902            direction = Direction(direction_str)
903        except ValueError:
904            print(f"{Colors.RED}Invalid direction: {direction_str}{Colors.RESET}")
905            return
906        
907        location = self.world.get_location(self.player.location_id)
908        if not location:
909            return
910        
911        if direction in location.exits:
912            # Check for hostile NPCs that might block the way
913            for npc in location.npcs:
914                if npc.hostile and npc.stats.health > 0:
915                    print(f"{Colors.RED}{npc.name} blocks your path!{Colors.RESET}")
916                    self.start_combat(npc)
917                    return
918            
919            # Move to the new location
920            self.player.location_id = location.exits[direction]
921            print(f"{Colors.GREEN}You go {direction.value}.{Colors.RESET}")
922            
923            # Update time (movement takes time)
924            self.world.update_time(5)
925            
926            # Consume stamina
927            self.player.stats.stamina = max(0, self.player.stats.stamina - 5)
928            
929            # Check for random encounters
930            if random.random() < 0.1:  # 10% chance of random encounter
931                self.random_encounter()
932        else:
933            print(f"{Colors.RED}You can't go {direction.value} from here.{Colors.RESET}")
934    
935    def cmd_take(self, args):
936        if not args:
937            print(f"{Colors.RED}Take what?{Colors.RESET}")
938            return
939        
940        item_name = ' '.join(args)
941        location = self.world.get_location(self.player.location_id)
942        if not location:
943            return
944        
945        # Find the item
946        for item in location.items:
947            if item.name.lower() == item_name.lower():
948                # Add to player inventory
949                leftover = self.player.add_item(item)
950                if leftover == 0:
951                    location.remove_item(item)
952                    print(f"{Colors.GREEN}You take the {item.name}.{Colors.RESET}")
953                else:
954                    print(f"{Colors.YELLOW}You can only carry {item.max_stack} {item.name}s.{Colors.RESET}")
955                return
956        
957        print(f"{Colors.RED}There is no {item_name} here.{Colors.RESET}")
958    
959    def cmd_inventory(self, args):
960        if not self.player.inventory:
961            print(f"{Colors.YELLOW}Your inventory is empty.{Colors.RESET}")
962            return
963        
964        print(f"{Colors.CYAN}Inventory:{Colors.RESET}")
965        for item_id, (item, quantity) in self.player.inventory.items():
966            if item.stackable:
967                print(f"  {Colors.GREEN}{item.name} x{quantity}{Colors.RESET} - {item.description}")
968            else:
969                print(f"  {Colors.GREEN}{item.name}{Colors.RESET} - {item.description}")
970        
971        # Show equipped items
972        if self.player.equipped:
973            print(f"\n{Colors.CYAN}Equipped:{Colors.RESET}")
974            for slot, item in self.player.equipped.items():
975                print(f"  {Colors.YELLOW}{slot}: {item.name}{Colors.RESET}")
976    
977    def cmd_use(self, args):
978        if not args:
979            print(f"{Colors.RED}Use what?{Colors.RESET}")
980            return
981        
982        item_name = ' '.join(args)
983        
984        # Find the item in inventory
985        for item_id, (item, quantity) in self.player.inventory.items():
986            if item.name.lower() == item_name.lower():
987                if item.use(self.player):
988                    if item.consumable:
989                        if quantity > 1:
990                            self.player.inventory[item_id] = (item, quantity - 1)
991                        else:
992                            self.player.remove_item(item_id)
993                    print(f"{Colors.GREEN}You use the {item.name}.{Colors.RESET}")
994                else:
995                    print(f"{Colors.RED}You can't use the {item.name}.{Colors.RESET}")
996                return
997        
998        print(f"{Colors.RED}You don't have a {item_name}.{Colors.RESET}")
999    
1000    def cmd_equip(self, args):
1001        if not args:
1002            print(f"{Colors.RED}Equip what?{Colors.RESET}")
1003            return
1004        
1005        item_name = ' '.join(args)
1006        
1007        # Find the item in inventory
1008        for item_id, (item, quantity) in self.player.inventory.items():
1009            if item.name.lower() == item_name.lower():
1010                if self.player.equip_item(item_id):
1011                    print(f"{Colors.GREEN}You equip the {item.name}.{Colors.RESET}")
1012                else:
1013                    print(f"{Colors.RED}You can't equip the {item.name}.{Colors.RESET}")
1014                return
1015        
1016        print(f"{Colors.RED}You don't have a {item_name}.{Colors.RESET}")
1017    
1018    def cmd_unequip(self, args):
1019        if not args:
1020            print(f"{Colors.RED}Unequip what?{Colors.RESET}")
1021            return
1022        
1023        slot = args[0].lower()
1024        
1025        if self.player.unequip_item(slot):
1026            print(f"{Colors.GREEN}You unequip your {slot}.{Colors.RESET}")
1027        else:
1028            print(f"{Colors.RED}You don't have anything equipped in that slot.{Colors.RESET}")
1029    
1030    def cmd_talk(self, args):
1031        if not args:
1032            print(f"{Colors.RED}Talk to whom?{Colors.RESET}")
1033            return
1034        
1035        npc_name = ' '.join(args)
1036        location = self.world.get_location(self.player.location_id)
1037        if not location:
1038            return
1039        
1040        # Find the NPC
1041        for npc in location.npcs:
1042            if npc.name.lower() == npc_name.lower():
1043                # Get dialogue topic
1044                topic = "greeting"
1045                if len(args) > 1:
1046                    topic = ' '.join(args[1:])
1047                
1048                # Get dialogue
1049                dialogue = npc.talk(topic)
1050                print(f"{Colors.MAGENTA}{npc.name}: {dialogue}{Colors.RESET}")
1051                
1052                # Check for quests
1053                if topic == "quest" and npc.quests:
1054                    for quest in npc.quests:
1055                        if not quest.completed and not any(q.id == quest.id for q in self.player.quests):
1056                            self.player.add_quest(quest)
1057                            print(f"{Colors.GREEN}New quest: {quest.name}{Colors.RESET}")
1058                            print(f"{Colors.WHITE}{quest.description}{Colors.RESET}")
1059                
1060                return
1061        
1062        print(f"{Colors.RED}There is no one named {npc_name} here.{Colors.RESET}")
1063    
1064    def cmd_attack(self, args):
1065        if not args:
1066            print(f"{Colors.RED}Attack whom?{Colors.RESET}")
1067            return
1068        
1069        npc_name = ' '.join(args)
1070        location = self.world.get_location(self.player.location_id)
1071        if not location:
1072            return
1073        
1074        # Find the NPC
1075        for npc in location.npcs:
1076            if npc.name.lower() == npc_name.lower():
1077                if not npc.hostile:
1078                    print(f"{Colors.RED}You can't attack {npc.name}.{Colors.RESET}")
1079                    return
1080                
1081                self.start_combat(npc)
1082                return
1083        
1084        print(f"{Colors.RED}There is no one named {npc_name} here.{Colors.RESET}")
1085    
1086    def cmd_flee(self, args):
1087        if not self.in_combat:
1088            print(f"{Colors.RED}You're not in combat.{Colors.RESET}")
1089            return
1090        
1091        if self.combat.check_flee(self.player, self.current_opponent):
1092            print(f"{Colors.GREEN}You successfully flee from combat.{Colors.RESET}")
1093            self.end_combat()
1094            
1095            # Move to a random adjacent location
1096            location = self.world.get_location(self.player.location_id)
1097            if location and location.exits:
1098                directions = list(location.exits.keys())
1099                random_direction = random.choice(directions)
1100                self.player.location_id = location.exits[random_direction]
1101                print(f"{Colors.GREEN}You run away to the {random_direction.value}.{Colors.RESET}")
1102        else:
1103            print(f"{Colors.RED}You fail to flee!{Colors.RESET}")
1104            # Enemy gets a free attack
1105            damage = self.combat.attack(self.current_opponent, self.player)
1106            print(f"{Colors.RED}{self.current_opponent.name} attacks you for {damage} damage!{Colors.RESET}")
1107            
1108            if self.player.stats.health <= 0:
1109                self.game_over()
1110    
1111    def cmd_quests(self, args):
1112        if not self.player.quests:
1113            print(f"{Colors.YELLOW}You don't have any active quests.{Colors.RESET}")
1114            return
1115        
1116        print(f"{Colors.CYAN}Active Quests:{Colors.RESET}")
1117        for quest in self.player.quests:
1118            if quest.active and not quest.completed:
1119                print(f"  {Colors.YELLOW}{quest.name}{Colors.RESET}")
1120                print(f"    {quest.description}")
1121                print(f"    Objectives: {', '.join(quest.objectives)}")
1122        
1123        print(f"\n{Colors.CYAN}Completed Quests:{Colors.RESET}")
1124        for quest in self.player.quests:
1125            if quest.completed:
1126                print(f"  {Colors.GREEN}{quest.name}{Colors.RESET}")
1127    
1128    def cmd_skills(self, args):
1129        print(f"{Colors.CYAN}Skills:{Colors.RESET}")
1130        for skill_name, skill in self.player.skills.items():
1131            print(f"  {Colors.YELLOW}{skill.name}: Level {skill.level} ({skill.experience}/{skill.max_experience} XP){Colors.RESET}")
1132    
1133    def cmd_time(self, args):
1134        print(f"{Colors.CYAN}{self.world.get_time_description()}{Colors.RESET}")
1135    
1136    def cmd_save(self, args):
1137        save_name = args[0] if args else "save1"
1138        save_data = {
1139            "player": self.player,
1140            "world": self.world,
1141            "in_combat": self.in_combat,
1142            "current_opponent": self.current_opponent
1143        }
1144        
1145        try:
1146            with open(f"{save_name}.sav", "wb") as f:
1147                pickle.dump(save_data, f)
1148            print(f"{Colors.GREEN}Game saved as {save_name}.{Colors.RESET}")
1149        except Exception as e:
1150            print(f"{Colors.RED}Failed to save game: {e}{Colors.RESET}")
1151    
1152    def cmd_load(self, args):
1153        save_name = args[0] if args else "save1"
1154        
1155        try:
1156            with open(f"{save_name}.sav", "rb") as f:
1157                save_data = pickle.load(f)
1158            
1159            self.player = save_data["player"]
1160            self.world = save_data["world"]
1161            self.in_combat = save_data["in_combat"]
1162            self.current_opponent = save_data["current_opponent"]
1163            
1164            print(f"{Colors.GREEN}Game loaded from {save_name}.{Colors.RESET}")
1165        except Exception as e:
1166            print(f"{Colors.RED}Failed to load game: {e}{Colors.RESET}")
1167    
1168    def cmd_wait(self, args):
1169        minutes = 30  # Default wait time
1170        if args:
1171            try:
1172                minutes = int(args[0])
1173            except ValueError:
1174                print(f"{Colors.RED}Invalid time: {args[0]}{Colors.RESET}")
1175                return
1176        
1177        print(f"{Colors.YELLOW}You wait for {minutes} minutes...{Colors.RESET}")
1178        self.world.update_time(minutes)
1179        self.player.update_vitals()
1180        
1181        # Random events while waiting
1182        if random.random() < 0.2:  # 20% chance of something happening
1183            self.random_event()
1184    
1185    def cmd_status(self, args):
1186        print(f"{Colors.CYAN}Character Status:{Colors.RESET}")
1187        print(f"  Name: {self.player.name}")
1188        print(f"  Level: {self.player.stats.level}")
1189        print(f"  Experience: {self.player.stats.experience}")
1190        print(f"  Health: {self.player.stats.health}/{self.player.stats.max_health}")
1191        print(f"  Mana: {self.player.stats.mana}/{self.player.stats.max_mana}")
1192        print(f"  Stamina: {self.player.stats.stamina}/{self.player.stats.max_stamina}")
1193        print(f"  Hunger: {self.player.stats.hunger}/{self.player.stats.max_hunger}")
1194        print(f"  Thirst: {self.player.stats.thirst}/{self.player.stats.max_thirst}")
1195        print(f"  Defense: {self.player.get_total_defense()}")
1196        print(f"  Damage: {self.player.get_total_damage()}")
1197    
1198    def cmd_drop(self, args):
1199        if not args:
1200            print(f"{Colors.RED}Drop what?{Colors.RESET}")

Showing the first 1,200 of 1621 lines. Download the file for the rest.