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 :wink::wink:

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

https://replit.com/@JackAdem/Day-028-Project-28-Battle-Time?v=1

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.

Repl link:

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")
c1=input("Name your legend: ")
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
c2=input("Name your legend: ")
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.

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()
name1 = input("Name your Legend:\n")
type1 = input("Character Type (Human, Elf, Wizard, Orc):\n")
print()
print(name1)
health1 = health() 
print("HEALTH:", health1)
strength1 = strength() 
print("STRENGTH:", strength1)
print()
print("Who will your hero battle?")
print()
name2 = input("Name your Legend:\n")
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.

Thanks for your help

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 =- Result1and 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.

To address this I just added another time.sleep(2) to the end of your while True loop.


2 Likes

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

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")
    main_menu()
  else:
    print("Thanks for playing! That was a great game! Goodbye. ")
    exit()
    
  
#Main Menu
def main_menu():
  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
    
    

main_menu()
1 Like

Which calculations are you exactly talking about?

When I did the calculations they seemed off. With regards to calculating the new health after a dice roll.

1 Like