# Day 028 - Project 28 : Battle Time

If you have any questions, comments or issues with this project please post them here!

Doing this project took a lot of effort. But anyways I did it. Maybe itâ€™s not picture perfect but Iâ€™m trying to do better

Ready to battle it out with the characters I built in the previous day.

Day 28 of #Replit100DaysOfCode #100DaysOfCode.

1 Like

**Hi guys, I am struggling with Day 28 in creating a battle ground with two players.
The area I am struggling at is where we have to take the difference between the two players+1 and then minus it from the losing characterâ€™s health.
I cannot seem to get my head wrapped around it , no matter how much I try.
I would really appreciate if someone can help me out with this code.

Thank you.

``````import random
import os,time

def rollDice(sides):
result=random.randint(1,sides)
return result

#player1 and player 2 health stat
def healthstat():
roll6sided=rollDice(6)
roll8sided=rollDice(8)
health=roll6sided*roll8sided/2+10
return health

# player 1 and player 2 strength stat
def strengthstat():
roll6sided=rollDice(6)
roll8sided=rollDice(8)
strength=roll6sided*roll8sided/2+12
return strength

#character1
print("Character generator")
type=input("Choose your type: Human, Elf, Wizard or Orc: ")
print(c1,"the",type)
c1health=str(healthstat())
c1strength=str(strengthstat())
print("Health: ", c1health)
print("Strength: ", c1strength)
print("")

print("Who are you battling?")
#character2
type2=input("Choose your type: Human, Elf, Wizard or Orc: ")
print(c2,"the",type2)
c2health=str(healthstat())
c2strength=str(strengthstat())
print("Health: ", c2health)
print("Strength: ", c2strength)
print("")

round=0

while True:
os.system("clear")
time.sleep(1)
print("Battle time")
difference=c1strength-c2strength
winner=c2health-difference
if c1strength>c2strength:
c2health-=difference
if round==1:
print(c1, "wins the first blow")
else:
print(c1, "wins round", round)``````

@tjhummun What seems to be going wrong with your program? Is their an error, a concept you donâ€™t understand or something else?

this battling game requires you to calculate the difference between the strength+1 and then take it away from the losingcharâ€™s health. And I just donâ€™t understand how to make it work or how to carry on after that.

this step:

``````difference=c1strength-c2strength
winner=c2health-difference
``````

is not working for me.

and without this step ,i cannot determine the health of my characters hence wonâ€™t read the end of the game.

1 Like

What error exactly does the code raise?

That seems to be your issue, youâ€™re not adding 1 to the strength difference here.

1 Like

This is day 28 of the 100 days of code.

I know there is a bug because sometimes immediately after a tie roll one of the characters dies, this shouldnâ€™t be possible.

Can anyone identify the bug?

``````import random, os, time

def rollDice(side):
result = random.randint(1,side)
return result

def health():
healthStat = ((rollDice(6)*rollDice(12))/2)+10
return healthStat

def strength():
strengthStat = ((rollDice(6)*rollDice(8))/2)+12
return strengthStat

print("âš”ď¸Ź BATTLE TIME âš”ď¸Ź")
print()
type1 = input("Character Type (Human, Elf, Wizard, Orc):\n")
print()
print(name1)
health1 = health()
print("HEALTH:", health1)
strength1 = strength()
print("STRENGTH:", strength1)
print()
print()
type2 = input("Character Type (Human, Elf, Wizard, Orc):\n")
print()
print(name2)
health2 = health()
print("HEALTH:", health2)
strength2 = strength()
print("STRENGTH:", strength2)
print()
print("âš”ď¸Ź Let's get ready to rumble! âš”ď¸Ź")
print()
time.sleep(3)
os.system("clear")

if strength1 > strength2:
strength_diff = (strength1 - strength2) + 1
elif strength1 < strength2:
strength_diff = (strength2 - strength1) + 1
else:
strength_diff = 1

deaths = 0

while deaths == 0:
p1_roll = rollDice(6)
p2_roll = rollDice(6)
if p1_roll > p2_roll:
print(name1, "attacks,", name2, "dealing", strength_diff, "points of damage\n")
health2 -= strength_diff
time.sleep(1)
if health1 <= 0 or health2 <= 0:
deaths = 1
if p2_roll > p1_roll:
print(name2, "attacks", name1, "dealing", strength_diff, "points of damage\n")
health1 -= strength_diff
time.sleep(1)
if health1 <= 0 or health2 <= 0:
deaths = 1
else:
print("It's a tie, re-rolling!\n")
time.sleep(1)

if health1 <=0:
print(name1, "lost!")
time.sleep(1)
elif health2 <= 0:
print(name2, "lost!")
time.sleep(1)
else:
print("Uh oh, we fucked up some how!")
time.sleep(5)

time.sleep(1)
os.system("clear")
``````

When p1_roll is equal to p2_roll, neither of the first two if conditions is met. So, the else will be executed.
But! In this case, there is no re-rolling, it just prints â€śItâ€™s a tie, re-rollingâ€ť but it doensâ€™t re-roll.

Itâ€™s better to add a separate condition to re-roll the dice when a tie occurs, instead of using an `else` clause attached to the second `if` statement.

Correct this and everything else should fix too.

2 Likes

it seems to me that ur code is malfunctioning acording to the trajejtory of the areodynamics

I donâ€™t follow, itâ€™s a loop that repeats while deaths = 0. THe re-roll is at the top of the loop. What am I missing?

The problem is not with the re-rolling mechanism itself, is with the way the tie situation is handled within the loop.

When a tie occurs (like p1 equals p2), the else block is executed, which just prints â€śItâ€™s a tieâ€ť.
So, after this message, the loop continues to your death check (if hp1 <=0 or hp2 <=0). But, if either char health is already 0 or negative (because of the previus round), the death condition is met and the loops ends.

The problem is that it looks like the dice are re-rolled after the tie because the loop starts over, but itâ€™s not. The death check happens after the tie message and before the next roll. This will make the characterâ€™s death being announced immediately after a tie, even though no additional damage was dealt in that particular round.

So to fix this:

``````while deaths == 0:
p1_roll = rollDice(6)
p2_roll = rollDice(6)

if p1_roll > p2_roll:
# Player 1 deals damage
health2 -= strength_diff
elif p2_roll > p1_roll:
# Player 2 deals damage
health1 -= strength_diff
else:
# Tie situation, re-roll in next iteration
print("It's a tie, re-rolling!\n")
continue

# Check for death after resolving the round
if health1 <= 0 or health2 <= 0:
deaths = 1

``````

This way, after announcing a tie, no death check occurs until the next round of attacks, after a new set of rolls.

I get what youâ€™re saying but what I donâ€™t understand is why that mattersâ€¦

The problem is that it looks like the dice are re-rolled after the tie because the loop starts over, but itâ€™s not. The death check happens after the tie message and before the next roll. This will make the characterâ€™s death being announced immediately after a tie, even though no additional damage was dealt in that particular round.

Why would even need a death check to occur after a tie? After a tie no health has changed therefore a death check should not be needed right? We re-roll and then fight and then check for death again?

I guess I also donâ€™t really understand what happens differently if there is a â€ścontinueâ€ť after â€śelseâ€ť or not. It seems to repeat either way otherwise the script wouldnâ€™t be working at all.

I understand where are you coming from, Ill try to clarify a little better.

In your original code, after a tie is announced, the loop does not immediately re-roll the dice. Thatâ€™s a fact. And instead, it continues to the death check. However, as you already pointed out, no health changes during a tie, so this death check is indeed unnecessary right after a tie. Itâ€™s more logical to check for death only after one of the players has dealt damage.

Then we have the function of the `continue`. The continue, if added after announcing a tie, would skip the rest of the loopâ€™s and start the next iteration immediately. This means that the death check would not occur until after the next round of dice rolls and potential damage dealing.

Now, without continue, the loop still repeats, but it first executes the death check even when no new damage has been dealt (for example, after a tie). You see the problem? This is redundant and can be misleading, as it suggests the possibility of a character dying right after a tie, even though no attack has occurred in that iteration.

Now, why Iâ€™m pressing the issue. The main thing here, is not the functionality of the loop itself but the clarity and logic of the game flow. While the game will function correctly without the continue (because the loop will repeat either way), adding continue makes the game logic clearer and more intuitive. It ensures that a death check only happens after a player has had the chance to attack and possibly reduce the opponentâ€™s health.

So, while your code from the beggining does work as intended in terms of repeating the loop and eventually determining a winner, adding continue after announcing a tie would better clarify the gameâ€™s flow by ensuring that death checks are only made after an attack has occurred.

3 Likes

I get what you mean but actually it wasnâ€™t working. Thatâ€™s what made me take notice. Sometimes I would get a death immediately after a tie which should have been impossible.

Hello, I need help, when it comes to the health being printed out after the battle and the damage being done to the 2 players, the player that Is supposed to lose heart hit points goes straight into negative thus causing the code to end because of my if loop at the end. How do I make it subtract the damage from the starting health and then print it out at the end which allows the while loop to carry on until one of the players is really at 0 health.

When you update the health after taking the damage, you had
`health2 =- Result1`and `health1 =- Result2`, the issue is just that `=-` should be `-=`, so you wrote it backwards.

ChatGPT
(In Python, when you use the = sign, it signifies assignment, instructing Python to assign the value on the right to the variable on the left. So, when you write X =- Y, Python interprets it as assigning negative Y to X, rather than subtracting Y from X.

On the other hand, when you use the -= operator, Python interprets it as performing an in-place subtraction operation. This operator combines subtraction with assignment, indicating to Python to subtract Y from X and assign the result back to X.

The order of symbols in the operation is crucial for Python to correctly interpret your intentions. In Python, the order determines whether youâ€™re performing assignment followed by a unary negation or performing subtraction followed by assignment. This distinction is vital for writing correct and understandable code.)

To illustrate this you can try the following code

``````x = 5
while x > 0:
x =- 1
print(x)
``````

This will just output negative 1, because all weâ€™re doing is saying if x is greater than 0,which it is because itâ€™s 5, then x is negative 1.

Whereas

``````x = 5
while x > 0:
x -= 1
print(x)
``````

Will output the numbers 4,3,2,1,0 since it is saying subtract 1 from x until it reaches 0.

You also have os.system(â€śclearâ€ť) at the start of your while True loop, which is fine, but you havenâ€™t added a time.sleep() delay before this, meaning at the end of every round of die rolls, the results of that round flash on the screen but are cleared faster than you can read it.

2 Likes

Something is off with my calculations, I have spent about 5 days trying to fix it. Is there a better way? TIA

``````import random, time, os

#subroutine 1: character name and type

def character_name_and_type():
character_name = input("Name your Legend: ")
character_type = input("Character Type (Human, Elf, Wizard, Orc): ")
return character_name, character_type

#subroutine 2: health stats

def health_stats():
health_stats = (random.randint(1,6) * random.randint(1,12))/2 + 10
return health_stats

#subroutine 3: strength stats

def strength_stats():
strength_stats = (random.randint(1,6) * random.randint(1,12))/2 + 12
return strength_stats

#subroutine 4: random sided dice

def dice_roll():
dice_roll = random.randint(1,6)
return dice_roll

#subroutine 5: battle damage

def battle_damage():
strength_stats1 = strength_stats()
strength_stats2 = strength_stats()
battle_damage = abs(strength_stats1 - strength_stats2) + 1
return battle_damage

#play again
def play_again():
play_again = input("Do you want to play again? ")
if play_again == "yes" or play_again == "Yes" or play_again == "Y":
os.system("clear")
else:
print("Thanks for playing! That was a great game! Goodbye. ")
exit()

print("âš”ď¸Ź BATTLE TIME âš”ď¸Ź")
print()
character1, _ = character_name_and_type()
healthstats1 = health_stats()
strength_stats1 = strength_stats()
print(character1, "H: ", healthstats1, "S: ",strength_stats1)
print()
print("Who are they battling?")
character2, _ = character_name_and_type()
healthstats2 = health_stats()
strength_stats2 = strength_stats()
print(character2,"H: ", healthstats2, "S: ", strength_stats2)
print()
time.sleep(1)
#os.system("clear")
print("âš”ď¸Ź BATTLE TIME âš”ď¸Ź")
print()
print("The battle begins!")
print()
round = 0
while True:
character1_roll = dice_roll()
character2_roll = dice_roll()
round += 1
if character1_roll > character2_roll:
print("Nice,", character1, "wins the first blow with a roll of", character1_roll)
print("Darn,", character2, "takes a hit, with", battle_damage(), "damage. A weak roll of: ", character2_roll)
print()
print(character1, "wins round", round, ".")
print("HEALTH:", healthstats1)
print()
print(character2)
print("HEALTH:", healthstats2 - battle_damage())
print()
if (healthstats1 - battle_damage()) <= 0:
print ("Oh no", character1, "has died!")
print()
print("Game over!", character2, "wins!")
play_again()
else:
print("And they're both standing for the next round!")
time.sleep(1)
#os.system("clear")
continue
elif character1_roll < character2_roll:
print(character2, "wins the first blow with a strong roll of: ", character2_roll)
print(character1, "takes a hit, with", battle_damage(), "damage, too bad you rolled: ", character1_roll)
print()
print(character2, "wins round", round, ".")
print("HEALTH:", healthstats2)
print()
print(character1)
print("HEALTH:", healthstats1 - battle_damage())
print()
if (healthstats2 - battle_damage()) <= 0:
print ("Oh no", character2, "has died!")
print()
print("Game over!", character1, "wins!")
play_again()
else:
print("And they're both standing for the next round!")
time.sleep(1)
#os.system("clear")
continue
else:
print("It's a draw! Re-roll, both attacks were equally strong!")
time.sleep(1)
#os.system("clear")
continue