Hi ! Debug, extand, refine, enhance and optimize the following game. Generate the new full functional code here, so i can copy/paste and run. import pickle
import random
import time
from datetime import datetime, timedelta

# Global Variables
game_time = None  # Initialized in main()

# Item Classes
class Item:
    def __init__(self, name, description, quantity=1):
        self.name = name.lower()
        self.description = description
        self.quantity = quantity

    def use(self, player):
        print(f"You can't use the {self.name}.")

    def __str__(self):
        return f"{self.name.capitalize()} (x{self.quantity}): {self.description}"

class Weapon(Item):
    def __init__(self, name, description, damage, quantity=1):
        super().__init__(name, description, quantity)
        self.damage = damage

    def use(self, player):
        player.equip_weapon(self)
        print(f"You have equipped the {self.name}.")

class Consumable(Item):
    def __init__(self, name, description, heal_amount, quantity=1):
        super().__init__(name, description, quantity)
        self.heal_amount = heal_amount

    def use(self, player):
        if self.quantity > 0:
            player.heal(self.heal_amount)
            self.quantity -= 1
            print(f"You used a {self.name}. Your health is now {player.health}/{player.max_health}.")
            if self.quantity <= 0:
                player.remove_from_inventory(self)
        else:
            print(f"You don't have any {self.name} left.")

class Craftable(Item):
    def __init__(self, name, description, recipe, quantity=1):
        super().__init__(name, description, quantity)
        self.recipe = recipe  # dict of item_name: required_quantity

    def can_craft(self, player):
        for item_name, qty in self.recipe.items():
            if not player.has_item_quantity(item_name, qty):
                return False
        return True

    def craft(self, player):
        if self.can_craft(player):
            for item_name, qty in self.recipe.items():
                player.remove_specific_item(item_name, qty)
            crafted_item = Item(self.name, self.description, self.quantity)
            player.add_to_inventory(crafted_item)
            print(f"You have crafted a {self.name}.")
            return True
        else:
            print("You don't have the required items to craft this.")
            return False

class LockedChest(Item):
    def __init__(self, name, description, locked=True, contents=None, quantity=1):
        super().__init__(name, description, quantity)
        self.locked = locked
        self.contents = contents or []

    def use(self, player):
        if self.locked:
            key = player.has_item('key')
            if key:
                self.locked = False
                player.remove_specific_item('key', 1)
                print("You used a key to unlock the chest.")
                if self.contents:
                    for item in self.contents:
                        player.add_to_inventory(item)
                    self.contents = []
                else:
                    print("The chest is empty.")
            else:
                print("The chest is locked. You need a key to open it.")
        else:
            if self.contents:
                for item in self.contents:
                    player.add_to_inventory(item)
                self.contents = []
            else:
                print("The chest is empty.")

# Armor Class
class Armor(Item):
    def __init__(self, name, description, defense, quantity=1):
        super().__init__(name, description, quantity)
        self.defense = defense

# Monster Class
class Monster:
    def __init__(self, name, health, attack_power, defense, attack_chance=0.8, critical_chance=0.1):
        self.name = name
        self.health = health
        self.attack_power = attack_power
        self.defense = defense
        self.attack_chance = attack_chance
        self.critical_chance = critical_chance

    def is_alive(self):
        return self.health > 0

    def attack(self, player):
        if random.random() <= self.attack_chance:
            if random.random() <= self.critical_chance:
                damage = max(0, (self.attack_power * 2) - player.defense)
                print(f"The {self.name} lands a CRITICAL HIT dealing {damage} damage!")
            else:
                damage = max(0, self.attack_power - player.defense)
                print(f"The {self.name} attacks dealing {damage} damage.")
            player.health -= damage
            if player.health < 0:
                player.health = 0
            print(f"Your health is now {player.health}/{player.max_health}.")
        else:
            print(f"The {self.name} attempts to attack but misses!")

# NPC Classes
class NPC:
    def __init__(self, name, description, dialogues):
        self.name = name
        self.description = description
        self.dialogues = dialogues
        self.current_dialogue = 0

    def talk(self, player):
        while self.current_dialogue < len(self.dialogues):
            player_choice, npc_response, next_dialogues = self.dialogues[self.current_dialogue]
            print(f"\n{self.name}: {npc_response}")
            if not player_choice:
                self.current_dialogue += 1
                continue
            print("Your options:")
            for idx, choice in enumerate(player_choice, 1):
                print(f"{idx}. {choice}")
            choice = input("Enter the number of your choice: ").strip()
            if choice.isdigit() and 1 <= int(choice) <= len(player_choice):
                selected = player_choice[int(choice) - 1]
                print(f"\nYou: {selected}")
                self.current_dialogue += 1
            else:
                print("Invalid choice. Please try again.")
        print(f"{self.name} has nothing more to say.")

class FriendlyNPC(NPC):
    def __init__(self, name, description, dialogues, quest=None, gift=None):
        super().__init__(name, description, dialogues)
        self.quest = quest
        self.gift = gift

    def interact(self, player):
        self.talk(player)
        if self.quest and self.quest not in player.quests:
            player.add_quest(self.quest)
            if self.gift:
                player.add_to_inventory(self.gift)
                print(f"{self.name} has given you a {self.gift.name}.")

class UnfriendlyNPC(NPC):
    def __init__(self, name, description, dialogues, monster):
        super().__init__(name, description, dialogues)
        self.monster = monster

    def interact(self, player, current_room):
        self.talk(player)
        print(f"{self.name} is hostile and attacks you!")
        battle(player, self.monster, current_room)

# Quest Class
class Quest:
    def __init__(self, name, description, reward, objectives):
        self.name = name
        self.description = description
        self.reward = reward
        self.objectives = objectives
        self.progress = {obj: 0 for obj in objectives}
        self.completed = False

    def update_progress(self, objective_type, amount=1):
        if objective_type in self.objectives:
            self.progress[objective_type] += amount
            print(f"\nQuest Progress Updated: {self.name}")
            print(f"{objective_type.capitalize()}: {self.progress[objective_type]}/{self.objectives[objective_type]}")
            self.check_completion()
        else:
            print(f"No such objective '{objective_type}' in quest '{self.name}'.")

    def check_completion(self):
        if all(self.progress[obj] >= self.objectives[obj] for obj in self.objectives):
            self.complete()

    def complete(self):
        if not self.completed:
            self.completed = True
            print(f"\nCongratulations! You have completed the quest: {self.name}")
            print("Reward Received:")
            for item in self.reward:
                print(f"- {item.name.capitalize()} (x{item.quantity})")
            for item in self.reward:
                Player.instance().add_to_inventory(item)
        else:
            print(f"Quest '{self.name}' is already completed.")

    def __str__(self):
        status = "Completed" if self.completed else "In Progress"
        objectives_str = ', '.join([f"{obj.capitalize()}: {self.progress[obj]}/{self.objectives[obj]}" for obj in self.objectives])
        return f"Quest: {self.name}\nDescription: {self.description}\nStatus: {status}\nObjectives: {objectives_str}"

# Player Class
class Player:
    _instance = None

    @staticmethod
    def instance():
        if Player._instance is None:
            Player()
        return Player._instance

    def __init__(self):
        if Player._instance is not None:
            raise Exception("This class is a singleton!")
        else:
            Player._instance = self
        self.name = self.get_player_name()
        self.health = 100
        self.max_health = 100
        self.defense = 10
        self.inventory = []
        self.equipped_weapon = None
        self.equipped_armor = None
        self.quests = []
        self.score = 0
        self.lives = 3
        self.skills = ["Power Strike"]

    def get_player_name(self):
        name = ""
        while not name:
            name = input("Enter your character's name: ").strip()
            if not name:
                print("Name cannot be empty. Please enter a valid name.")
        return name

    def is_alive(self):
        return self.health > 0

    def attack(self, monster):
        if self.equipped_weapon:
            damage = max(0, self.equipped_weapon.damage - monster.defense)
            monster.health -= damage
            print(f"\nYou attack the {monster.name} with your {self.equipped_weapon.name} dealing {damage} damage.")
            self.score += damage
        else:
            damage = max(0, 10 - monster.defense)
            monster.health -= damage
            print(f"\nYou attack the {monster.name} with your bare hands dealing {damage} damage.")
            self.score += damage

    def heal(self, amount):
        self.health += amount
        if self.health > self.max_health:
            self.health = self.max_health

    def add_to_inventory(self, item):
        existing_item = next((i for i in self.inventory if i.name == item.name.lower()), None)
        if existing_item:
            existing_item.quantity += item.quantity
        else:
            self.inventory.append(item)
        print(f"\nAdded {item.quantity} x {item.name.capitalize()} to your inventory.")

    def remove_from_inventory(self, item):
        if item in self.inventory:
            self.inventory.remove(item)

    def remove_specific_item(self, item_name, quantity):
        for item in self.inventory:
            if item.name == item_name.lower():
                if item.quantity > quantity:
                    item.quantity -= quantity
                    print(f"\nRemoved {quantity} x {item.name.capitalize()} from your inventory.")
                    return
                elif item.quantity == quantity:
                    self.inventory.remove(item)
                    print(f"\nRemoved {item.name.capitalize()} from your inventory.")
                    return
                else:
                    print(f"\nYou don't have enough {item_name} to remove.")
                    return
        print(f"\nYou don't have a {item_name} in your inventory.")

    def has_item(self, item_name):
        for item in self.inventory:
            if item.name == item_name.lower():
                return item
        return None

    def has_item_quantity(self, item_name, quantity):
        item = self.has_item(item_name)
        if item and item.quantity >= quantity:
            return True
        return False

    def equip_weapon(self, weapon):
        self.equipped_weapon = weapon
        print(f"\nYou have equipped the {weapon.name}.")

    def equip_armor(self, armor):
        self.equipped_armor = armor
        self.defense += armor.defense
        print(f"\nYou have equipped the {armor.name}.")

    def unequip_armor(self):
        if self.equipped_armor:
            self.defense -= self.equipped_armor.defense
            self.equipped_armor = None
            print(f"\nYou have unequipped the {self.equipped_armor.name}.")
        else:
            print("\nYou have no armor equipped.")

    def show_inventory(self):
        if not self.inventory:
            print("\nYour inventory is empty.")
            return
        print("\n=== Inventory ===")
        for item in self.inventory:
            print(f"- {item.name.capitalize()} (x{item.quantity}): {item.description}")
        print("=================\n")

    def add_quest(self, quest):
        if any(q.name == quest.name for q in self.quests):
            return  # Quest already added
        self.quests.append(quest)
        print(f"\nNew Quest Added: {quest.name}\nDescription: {quest.description}")

    def check_quests_completion(self):
        for quest in self.quests:
            if not quest.completed:
                quest.check_completion()

    def use_skill(self, skill_name, monster=None):
        print(f"\nYou used the skill: {skill_name}")
        if skill_name.lower() == "power strike":
            if self.equipped_weapon and monster:
                damage = max(0, (self.equipped_weapon.damage * 1.5) - monster.defense)
                print(f"You perform a Power Strike, dealing {int(damage)} damage to the {monster.name}!")
                monster.health -= damage
                self.score += int(damage)
                if monster.health <= 0:
                    print(f"\nYou have defeated the {monster.name} using Power Strike!")
                    self.score += 200
                    return True
            else:
                print("You have no weapon equipped or no monster to attack.")
        else:
            print(f"\nSkill '{skill_name}' is not implemented yet.")
        return False

    def __str__(self):
        weapon = self.equipped_weapon.name if self.equipped_weapon else "None"
        armor = self.equipped_armor.name if self.equipped_armor else "None"
        return (f"Name: {self.name}\n"
                f"Health: {self.health}/{self.max_health}\n"
                f"Defense: {self.defense}\n"
                f"Equipped Weapon: {weapon}\n"
                f"Equipped Armor: {armor}\n"
                f"Score: {self.score}\n"
                f"Lives: {self.lives}\n"
                f"Skills: {', '.join(self.skills) if self.skills else 'None'}")

# Room Class
class Room:
    def __init__(self, name, description, items=None, monsters=None, npcs=None, quests=None):
        self.name = name
        self.description = description
        self.items = items or []
        self.monsters = monsters or []
        self.npcs = npcs or []
        self.quests = quests or []
        self.connections = {}

    def connect_rooms(self, direction, room):
        self.connections[direction.lower()] = room

    def get_room_in_direction(self, direction):
        return self.connections.get(direction.lower(), None)

    def describe(self):
        print(f"\n=== {self.name} ===")
        print(self.description)
        if self.items:
            print("\nItems in the room:")
            for item in self.items:
                print(f"- {item.name.capitalize()} (x{item.quantity}): {item.description}")
        if self.monsters:
            print("\nMonsters in the room:")
            for monster in self.monsters:
                print(f"- {monster.name} (Health: {monster.health})")
        if self.npcs:
            print("\nNPCs in the room:")
            for npc in self.npcs:
                print(f"- {npc.name}: {npc.description}")
        if self.quests:
            print("\nQuests available in this room:")
            for quest in self.quests:
                print(f"- {quest.name}: {quest.description}")

# World Creation
def create_world():
    # Define Items
    sword = Weapon("Sword", "A sharp blade gleaming in the light.", damage=20)
    potion = Consumable("Potion", "Heals 25 health points.", heal_amount=25)
    fishing_rod = Craftable("Fishing Rod", "Assembled from a stick and string.", recipe={"stick": 1, "string": 1})
    key = Item("Key", "An old rusty key. It might open something.")
    gold_coin = Item("Gold Coin", "A shiny gold coin.", quantity=5)
    locked_chest = LockedChest("Locked Chest", "A sturdy chest with intricate engravings.", contents=[gold_coin])

    # Define Armor
    leather_armor = Armor("Leather Armor", "Light armor made of tough leather.", defense=5)

    # Define Monsters
    goblin = Monster("Goblin", health=30, attack_power=8, defense=5)
    orc = Monster("Orc", health=50, attack_power=12, defense=8)

    # Define Quests
    quest1 = Quest("Goblin Menace", "Eliminate the goblin causing trouble in the cave.", [potion], {"kill": 1})
    quest2 = Quest("Crafting Basics", "Craft a fishing rod using a stick and string.", [Item("Fish", "A fresh fish. Restores 15 health points.", quantity=1)], {"craft": 1})

    # Define NPCs
    friendly_npc = FriendlyNPC("Elder Mira", "A wise elder who knows much about the land.", [], quest=quest1, gift=sword)
    unfriendly_npc = UnfriendlyNPC("Rokar", "A nasty bandit looking for trouble.", [], monster=goblin)

    # Define Rooms
    village = Room("Village", "A peaceful village with friendly inhabitants.", [sword], [], [friendly_npc], [])
    cave = Room("Cave", "A dark cave where a goblin lurks.", [], [goblin], [], [])
    clearing = Room("Clearing", "A sunny clearing with a gentle stream.", [], [], [], [quest2])
    river = Room("River", "A flowing river. The sound of water is soothing.", [], [], [], [])
    mysterious_ruins = Room("Mysterious Ruins", "Ancient ruins filled with secrets.", [locked_chest], [], [], [])
    castle = Room("Abandoned Castle", "An old castle with towering walls.", [key], [], [unfriendly_npc], [])

    # Connect Rooms
    village.connect_rooms("north", cave)
    cave.connect_rooms("south", village)
    cave.connect_rooms("east", clearing)
    clearing.connect_rooms("west", cave)
    clearing.connect_rooms("east", river)
    river.connect_rooms("west", clearing)
    river.connect_rooms("north", mysterious_ruins)
    mysterious_ruins.connect_rooms("south", river)
    mysterious_ruins.connect_rooms("east", castle)
    castle.connect_rooms("west", mysterious_ruins)

    return village

# Utility Functions
def display_choices(choices):
    print("\n=== Available Actions ===")
    for idx, choice in enumerate(choices, 1):
        print(f"{idx}. {choice}")
    print("B. Back")
    print("Q. Quit")
    print("S. Save")

def get_user_choice(choices):
    while True:
        choice = input("\nEnter your choice: ").strip().lower()
        if choice.isdigit():
            num = int(choice)
            if 1 <= num <= len(choices):
                return choices[num - 1].upper()
        elif choice in ['b', 'back']:
            return 'BACK'
        elif choice in ['q', 'quit']:
            return 'QUIT'
        elif choice in ['s', 'save']:
            return 'SAVE'
        else:
            print("Invalid input. Please try again.")

def save_game(player, current_room):
    try:
        with open("save_game.pkl", "wb") as f:
            pickle.dump({"player": player, "current_room": current_room, "game_time": game_time}, f)
        print("\nGame has been saved successfully!")
    except Exception as e:
        print(f"\nFailed to save the game: {e}")

def load_game():
    try:
        with open("save_game.pkl", "rb") as f:
            data = pickle.load(f)
            player = data["player"]
            current_room = data["current_room"]
            loaded_time = data["game_time"]
            Player._instance = player
            game_time = loaded_time
            print("\nGame loaded successfully!")
            return player, current_room
    except FileNotFoundError:
        print("\nNo saved game found. Starting a new game.")
        return None, None
    except Exception as e:
        print(f"\nFailed to load the game: {e}")
        return None, None

def is_daytime():
    return 6 <= game_time.hour < 18

def display_text(text, delay=1):
    print(text)
    time.sleep(delay)

# Battle System
def battle(player, monster, current_room):
    print(f"\n=== Battle Start ===")
    print(f"You have encountered a {monster.name}!")

    while player.is_alive() and monster.is_alive():
        print(f"\nYour Health: {player.health}/{player.max_health}")
        print(f"{monster.name} Health: {monster.health}")
        choices = ["Attack", "Use Item", "Use Skill"]
        display_choices(choices)
        action = get_user_choice(choices)

        if action == "ATTACK":
            player.attack(monster)
        elif action == "USE ITEM":
            if any(isinstance(item, Consumable) for item in player.inventory):
                player.show_inventory()
                item_name = input("Enter the name of the item you want to use: ").strip().lower()
                item = player.has_item(item_name)
                if item and isinstance(item, Consumable):
                    item.use(player)
                else:
                    print("\nYou can't use that item.")
            else:
                print("\nYou have no consumable items to use.")
        elif action == "USE SKILL":
            if player.skills:
                print("\nAvailable Skills:")
                for idx, skill in enumerate(player.skills, 1):
                    print(f"{idx}. {skill}")
                skill_choice = input("Enter the number of the skill you want to use: ").strip()
                if skill_choice.isdigit():
                    skill_num = int(skill_choice)
                    if 1 <= skill_num <= len(player.skills):
                        selected_skill = player.skills[skill_num - 1]
                        if selected_skill.lower() == "power strike":
                            if player.equipped_weapon:
                                damage = max(0, (player.equipped_weapon.damage * 1.5) - monster.defense)
                                print(f"\nYou used Power Strike dealing {int(damage)} damage to the {monster.name}!")
                                monster.health -= damage
                                player.score += int(damage)
                                if monster.health <= 0:
                                    print(f"\nYou have defeated the {monster.name} using Power Strike!")
                                    player.score += 200
                                    return True
                            else:
                                print("You have no weapon equipped.")
                        else:
                            print(f"\nSkill '{selected_skill}' is not implemented yet.")
                    else:
                        print("\nInvalid skill selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nYou have no skills to use.")

        if monster.is_alive():
            monster.attack(player)
            if not player.is_alive():
                print("\nYou have been defeated.")
                player.lives -= 1
                if player.lives > 0:
                    print(f"You have {player.lives} lives left.")
                    player.health = player.max_health
                    print("You respawned with full health.")
                else:
                    print("You have no lives left. Game Over.")
                    exit()

    if player.is_alive():
        print(f"\nYou have defeated the {monster.name}!")
        player.score += 100
        if monster in current_room.monsters:
            current_room.monsters.remove(monster)
    else:
        print("\nYou have been defeated. Game Over.")
        exit()

# Main Game Loop
def main():
    global game_time
    game_time = datetime.now().replace(hour=9, minute=0, second=0, microsecond=0)

    player = Player.instance()
    loaded_player, loaded_room = load_game()
    if loaded_player and loaded_room:
        player = loaded_player
        current_room = loaded_room
    else:
        current_room = create_world()

    print(f"\n=== Welcome to the Adventure Game, {player.name}! ===")

    while True:
        current_room.describe()

        if is_daytime():
            print("\nIt's daytime.")
        else:
            print("\nIt's nighttime.")

        for quest in current_room.quests:
            player.add_quest(quest)

        if current_room.monsters:
            print("\nMonsters present in this room:")
            for monster in current_room.monsters:
                print(f"- {monster.name} (Health: {monster.health})")

        if current_room.npcs:
            print("\nNPCs present in this room:")
            for npc in current_room.npcs:
                print(f"- {npc.name}: {npc.description}")

        if current_room.items:
            print("\nItems available in this room:")
            for item in current_room.items:
                print(f"- {item.name.capitalize()} (x{item.quantity}): {item.description}")

        print(f"\n=== {player} ===")

        actions = ["Look Around", "Inventory", "Take Item", "Use Item", "Craft Item", "Quests", "Fight", "Interact with NPC", "Move", "Use Skill", "Equip Weapon", "Equip Armor"]
        display_choices(actions)
        action = get_user_choice(actions)

        if action == "LOOK AROUND":
            current_room.describe()
        elif action == "INVENTORY":
            player.show_inventory()
        elif action == "TAKE ITEM":
            if current_room.items:
                print("\nAvailable items to take:")
                for item in current_room.items:
                    print(f"- {item.name.capitalize()} (x{item.quantity})")
                item_choice = input("Enter the name of the item you want to take: ").strip().lower()
                target_item = next((i for i in current_room.items if i.name == item_choice), None)
                if target_item:
                    quantity = 1
                    if target_item.quantity > 1:
                        try:
                            quantity = int(input(f"How many {target_item.name.capitalize()}s do you want to take? (1-{target_item.quantity}): "))
                            if quantity < 1 or quantity > target_item.quantity:
                                print("Invalid quantity.")
                                continue
                        except ValueError:
                            print("Please enter a valid number.")
                            continue
                    player.add_to_inventory(Item(target_item.name, target_item.description, quantity))
                    target_item.quantity -= quantity
                    if target_item.quantity <= 0:
                        current_room.items.remove(target_item)
                    print(f"\nYou took {quantity} x {target_item.name.capitalize()}.")
                else:
                    chest = next((i for i in current_room.items if i.name == item_choice and isinstance(i, LockedChest)), None)
                    if chest:
                        chest.use(player)
                    else:
                        print("\nThat item is not available here.")
            else:
                print("\nThere are no items to take here.")
        elif action == "USE ITEM":
            if player.inventory:
                player.show_inventory()
                item_name = input("Enter the name of the item you want to use: ").strip().lower()
                item = player.has_item(item_name)
                if item:
                    item.use(player)
                else:
                    print("\nYou don't have that item.")
            else:
                print("\nYour inventory is empty.")
        elif action == "CRAFT ITEM":
            craftable_items = [item for item in player.inventory if isinstance(item, Craftable) and item.can_craft(player)]
            if craftable_items:
                print("\nAvailable items to craft:")
                for idx, craftable in enumerate(craftable_items, 1):
                    recipe = ', '.join([f"{qty} x {name.capitalize()}" for name, qty in craftable.recipe.items()])
                    print(f"{idx}. {craftable.name.capitalize()} - {craftable.description} (Recipe: {recipe})")
                craft_choice = input("Enter the number of the item you want to craft: ").strip()
                if craft_choice.isdigit():
                    craft_num = int(craft_choice)
                    if 1 <= craft_num <= len(craftable_items):
                        craft_item = craftable_items[craft_num - 1]
                        craft_item.craft(player)
                    else:
                        print("\nInvalid selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nYou have no craftable items or lack the necessary materials.")
        elif action == "QUESTS":
            if player.quests:
                print("\n=== Your Quests ===")
                for quest in player.quests:
                    print(f"\n{quest}")
                print("====================")
            else:
                print("\nYou have no active quests.")
        elif action == "FIGHT":
            alive_monsters = [monster for monster in current_room.monsters if monster.is_alive()]
            if alive_monsters:
                print("\nMonsters available to fight:")
                for idx, monster in enumerate(alive_monsters, 1):
                    print(f"{idx}. {monster.name} (Health: {monster.health})")
                fight_choice = input("Enter the number of the monster you want to fight: ").strip()
                if fight_choice.isdigit():
                    fight_num = int(fight_choice)
                    if 1 <= fight_num <= len(alive_monsters):
                        monster = alive_monsters[fight_num - 1]
                        battle(player, monster, current_room)
                    else:
                        print("\nInvalid selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nThere are no monsters to fight here.")
        elif action == "INTERACT WITH NPC":
            if current_room.npcs:
                print("\nNPCs available to interact with:")
                for idx, npc in enumerate(current_room.npcs, 1):
                    print(f"{idx}. {npc.name}: {npc.description}")
                npc_choice = input("Enter the number of the NPC you want to interact with: ").strip()
                if npc_choice.isdigit():
                    npc_num = int(npc_choice)
                    if 1 <= npc_num <= len(current_room.npcs):
                        npc = current_room.npcs[npc_num - 1]
                        if isinstance(npc, FriendlyNPC):
                            npc.interact(player)
                        elif isinstance(npc, UnfriendlyNPC):
                            npc.interact(player, current_room)  # Pass current_room here
                    else:
                        print("\nInvalid selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nThere are no NPCs to interact with here.")
        elif action == "MOVE":
            available_directions = list(current_room.connections.keys())
            if available_directions:
                print("\nAvailable directions to move:")
                for idx, direction in enumerate(available_directions, 1):
                    connected_room = current_room.get_room_in_direction(direction)
                    print(f"{idx}. {direction.capitalize()} to {connected_room.name}")
                direction_choice = input("Enter the number of the direction you want to move: ").strip()
                if direction_choice.isdigit():
                    dir_num = int(direction_choice)
                    if 1 <= dir_num <= len(available_directions):
                        chosen_direction = available_directions[dir_num - 1]
                        next_room = current_room.get_room_in_direction(chosen_direction)
                        current_room = next_room
                        print(f"\nYou move {chosen_direction.capitalize()} to the {current_room.name}.")
                    else:
                        print("\nInvalid selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nThere are no exits from this room.")
        elif action == "EQUIP WEAPON":
            weapons = [item for item in player.inventory if isinstance(item, Weapon)]
            if weapons:
                print("\nAvailable weapons to equip:")
                for idx, weapon in enumerate(weapons, 1):
                    print(f"{idx}. {weapon.name} (Damage: {weapon.damage})")
                weapon_choice = input("Enter the number of the weapon you want to equip: ").strip()
                if weapon_choice.isdigit():
                    weapon_num = int(weapon_choice)
                    if 1 <= weapon_num <= len(weapons):
                        weapon = weapons[weapon_num - 1]
                        player.equip_weapon(weapon)
                    else:
                        print("\nInvalid selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nYou have no weapons to equip.")
        elif action == "EQUIP ARMOR":
            armors = [item for item in player.inventory if isinstance(item, Armor)]
            if armors:
                print("\nAvailable armors to equip:")
                for idx, armor in enumerate(armors, 1):
                    print(f"{idx}. {armor.name} (Defense: {armor.defense})")
                armor_choice = input("Enter the number of the armor you want to equip: ").strip()
                if armor_choice.isdigit():
                    armor_num = int(armor_choice)
                    if 1 <= armor_num <= len(armors):
                        armor = armors[armor_num - 1]
                        player.equip_armor(armor)
                    else:
                        print("\nInvalid selection.")
                else:
                    print("\nPlease enter a valid number.")
            else:
                print("\nYou have no armors to equip.")
        elif action == "BACK":
            print("\nReturning to the previous menu.")
        elif action == "QUIT":
            confirm = input("Are you sure you want to quit? (y/n): ").strip().lower()
            if confirm == 'y':
                save_game(player, current_room)
                print("\nThank you for playing! Goodbye!")
                break
            else:
                continue
        elif action == "SAVE":
            save_game(player, current_room)

        # Update quests completion
        player.check_quests_completion()

        # Advance game time
        game_time += timedelta(minutes=15)

        # Increment score based on time or events
        player.score += 1

        # Simulate day-night cycle effects or other time-based events
        time.sleep(0.5)

# Entry Point
if __name__ == "__main__":
    main()