Python battle game help

Joined
Feb 23, 2023
Messages
1
Reaction score
0
Hi, I'm getting this error.

Traceback (most recent call last):
File "C:\Users\\OneDrive\Desktop\Python Turn Based Battle Game Group 10.py", line 157, in <module>
run_battle(player_team, ai_team)
File "C:\Users\\OneDrive\Desktop\Python Turn Based Battle Game Group 10.py", line 98, in run_battle
target = random.choice([u for u in ai_team if u.is_alive()])
File "C:\Users\\AppData\Local\Programs\Python\Python311\Lib\random.py", line 370, in choice
raise IndexError('Cannot choose from an empty sequence')
IndexError: Cannot choose from an empty sequence

I have added the code below. Can someone please help, my submission is tmrw. The error is very random too, it randomly breaks whenever I run the game. sometimes it works.

--START-OF-CODE--

import random
from datetime import datetime

class Unit:
def __init__(self, name, profession, health, damage, defense, experience=0, level=1):
self.name = name
self.profession = profession
self.max_health = health
self.health = health
self.damage = damage
self.defense = defense
self.experience = experience
self.level = level

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

def take_damage(self, damage):
damage_taken = max(0, damage)
self.health -= damage_taken

def attack(self, target):
target.take_damage(self.damage)
print(f"{self.name} attacks {target.name} for {self.damage} damage.")
if not target.is_alive():
print(f"{target.name} has been defeated.")
self.gain_experience(20)

def gain_experience(self, amount):
self.experience += amount
print(f"{self.name} gained {amount} experience points.")
if self.experience >= 100:
self.level_up()

def level_up(self):
self.level += 1
self.max_health += 10
self.damage += 5
self.defense += 2
self.health = self.max_health
self.experience -= 100
print(f"{self.name} leveled up to level {self.level}!")


def generate_ai_team():
names = ["Goblin", "Orc", "Troll", "Skeleton", "Zombie"]
professions = ["Warrior", "Tanker"]
team = []
for i in range(3):
name = random.choice(names)
profession = random.choice(professions)
if profession == "Warrior":
team.append(Unit(name, profession, 100, random.randint(5, 20), random.randint(1, 10)))
elif profession == "Tanker":
team.append(Unit(name, profession, 100, random.randint(1, 10), random.randint(5, 15)))
return team

def select_units():
units = []
professions = ["Warrior", "Tanker"]
for i in range(3):
name = input(f"Enter a name for unit {i+1}: ")
while True:
profession = input(f"Select a profession for unit {i+1} (Warrior/Tanker): ")
if profession in professions:
break
else:
print("Invalid profession. Please select either 'Warrior' or 'Tanker'.")
if profession == "Warrior":
units.append(Unit(name, "Warrior", 100, random.randint(5, 20), random.randint(1, 10)))
elif profession == "Tanker":
units.append(Unit(name, "Tanker", 100, random.randint(1, 10), random.randint(5, 15)))
return units


def run_battle(player_team, ai_team):
turn_number = 1
event_log = []
while True:
now = datetime.now()
date_time = now.strftime("%m/%d/%Y %H:%M:%S")

print(f"\nTurn {turn_number}")
# Player's turn
for unit in player_team:
if unit.is_alive():
print(f"{unit.name} ({unit.profession}) - Health: {unit.health}/{unit.max_health}")
while True:
action = input("Choose an action (Attack): ")
if action.lower() == "attack":
target = random.choice([u for u in ai_team if u.is_alive()])
unit.attack(target)
event_log.append(f"{date_time}: {unit.name} ({unit.profession}) attacked {target.name} ({target.profession}) for {unit.damage} damage.")
# Print AI's statistics
for ai_unit in ai_team:
if ai_unit.is_alive():
print(f"{ai_unit.name} ({ai_unit.profession}) - Health: {ai_unit.health}/{ai_unit.max_health}")
break
else:
print("Invalid action.")

# Check if player has lost
if all([u.health <= 0 for u in player_team]):
print("You have been defeated!")
event_log.append(f"{date_time}: You have been defeated.")
break

# AI's turn
ai_damage_taken = 0
for unit in ai_team:
if unit.is_alive():
target = random.choice([u for u in player_team if u.is_alive()])
unit.attack(target)
damage_taken = unit.damage
ai_damage_taken += damage_taken
event_log.append(f"{date_time}: {unit.name} ({unit.profession}) attacked {target.name} ({target.profession}) for {unit.damage} damage.")
else:
ai_team = [unit for unit in ai_team if unit.is_alive()]

# Write event log to file
with open("event_log.txt", "w") as f:
for event in event_log:
f.write(f"{event}\n")

# Check if AI has lost
if all([u.health <= 0 for u in ai_team]):
print("You win!")
event_log.append(f"{date_time}: You win!")
break

# Print AI damage taken and statistics
print(f"AI units have taken {ai_damage_taken} damage in total.")
for ai_unit in ai_team:
if ai_unit.is_alive():
print(f"{ai_unit.name} ({ai_unit.profession}) - Health: {ai_unit.health}/{ai_unit.max_health}")

turn_number += 1


# Main program
player_team = select_units()
ai_team = generate_ai_team()
print("Your team:")
for unit in player_team:
print(f"{unit.name} ({unit.profession}) - Health: {unit.health}/{unit.max_health}")
print("\nAI team:")
for unit in ai_team:
print(f"{unit.name} ({unit.profession}) - Health: {unit.health}/{unit.max_health}")
input("Press enter to start the battle...")
run_battle(player_team, ai_team)
 
Joined
May 11, 2022
Messages
61
Reaction score
6
when you write code, you have to put code identifiers around it.
space the code properly, then select all of it, and press the</> button
 
Joined
Dec 10, 2022
Messages
80
Reaction score
24
I would recommend using classes. It would be easier to control flow and changes of the game.
Here is an example of building an axis and allied army.

Python:
# Do the imports
import random as rnd
from datetime import datetime
from tabulate import tabulate


# Create some empty list
allies = []
axis = []

# Create some list for names and class
names = ['Goblin', 'Orc', 'Troll', 'Skeleton', 'Zombie']
allied_names = ['John', 'Jane', 'Rex', 'Tiffany', 'George', 'Sam', 'Samantha']
classes = ['Tanker', 'Warrior', 'Wizard', 'Mage']


# Create a character class
# The class can have either random settings or user set settings
# Class will add to allied army by default
class Unit:
    def __init__(self, name=rnd.choice(names), profession=rnd.choice(classes), army='allied'):
        self.data = {
        'name': name.title(),
        'profession': profession.title(),
        'health': 100,
        'damage': 0,
        'defense': rnd.randint(5, 20),
        'experience': rnd.randint(1, 10),
        'level': 1
        }
        if army == 'allied':
            allies.append(self)
        else:
            axis.append(self)


# Generate allied army
# Cand use default settings or user settings
player = Unit('john')
player2 = Unit('jane', 'Wizard')
for i in range(3):
    Unit(name=rnd.choice(allied_names), profession=rnd.choice(classes), army='allied')

# Generate axis army
for i in range(5):
    Unit(name=rnd.choice(names), profession=rnd.choice(classes) ,army='axis')

# Headers are for the tabulate table
headers = ['Name', 'Profession', 'Health', 'Damage', 'Defense', 'Experience', 'Level']

# Get and create a list of characters from both armies
players = [character.data.values() for character in allies]
axis_players = [character.data.values() for character in axis]

# Print allied army
print('Allies Army')
print(tabulate(players, headers, tablefmt='fancy_grid', numalign='center'))

# For a space
print()

# Print axis army
print('Axis Army')
print(tabulate(axis_players, headers, tablefmt='fancy_grid', numalign='center'))

Output

Code:
       Allies Army
╒════════╤══════════════╤══════════╤══════════╤═══════════╤══════════════╤═════════╕
│ Name   │ Profession   │  Health  │  Damage  │  Defense  │  Experience  │  Level  │
╞════════╪══════════════╪══════════╪══════════╪═══════════╪══════════════╪═════════╡
│ John   │ Tanker       │   100    │    0     │    17     │      8       │    1    │
├────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Jane   │ Wizard       │   100    │    0     │    14     │      9       │    1    │
├────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Rex    │ Warrior      │   100    │    0     │    19     │      1       │    1    │
├────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Rex    │ Mage         │   100    │    0     │    13     │      4       │    1    │
├────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ John   │ Mage         │   100    │    0     │    12     │      4       │    1    │
╘════════╧══════════════╧══════════╧══════════╧═══════════╧══════════════╧═════════╛

Axis Army
╒══════════╤══════════════╤══════════╤══════════╤═══════════╤══════════════╤═════════╕
│ Name     │ Profession   │  Health  │  Damage  │  Defense  │  Experience  │  Level  │
╞══════════╪══════════════╪══════════╪══════════╪═══════════╪══════════════╪═════════╡
│ Zombie   │ Tanker       │   100    │    0     │     7     │      7       │    1    │
├──────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Zombie   │ Warrior      │   100    │    0     │    16     │      5       │    1    │
├──────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Zombie   │ Mage         │   100    │    0     │    14     │      1       │    1    │
├──────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Troll    │ Wizard       │   100    │    0     │    11     │      3       │    1    │
├──────────┼──────────────┼──────────┼──────────┼───────────┼──────────────┼─────────┤
│ Skeleton │ Warrior      │   100    │    0     │     9     │      5       │    1    │
╘══════════╧══════════════╧══════════╧══════════╧═══════════╧══════════════╧═════════╛
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,818
Messages
2,569,727
Members
45,661
Latest member
NadineBour

Latest Threads

Top