Subtracting giving too little of a result

Viewed 31

Been trying to code a small game for the past week now and whenever I calculate the damage and print the enemy's hp and the damage dealt, theres a difference of 2 every single time. Enemy's Hp is 2 less than the supposed "damage dealt". Also, is there any way to round numbers up and down?

Main

#Imports
import os
from player import Player
from items import Item
from spells import Spells
from monsters import Monster
from gameplay import Fight
#Creating spells
# Type, Name, Damage, Cost
#Below are buff spells
buff_A = Spells("buff", "Buff", 1.1, 5)
buff_B = Spells("buff", "Stronger Buff", 1.3, 15)
buff_C = Spells("buff", "Strongest Buff", 1.5, 50)
#Below Are heal spells
heal_A = Spells("heal", "Heal", 5, 10)
heal_B = Spells("heal", "Stronger Heal", 20, 30)
heal_C = Spells("heal", "Strongest Heal", 50, 100)
#Creating Items
#Type, Name, Description, Amount
potion = Item("potion", "Health Potion", "Heals you for 10 HP", 10)
elixir = Item("elixir", "Mana Potion", "Regains 15 MP", 15)
#Assiging Variables For Player
player_spells = [buff_A, heal_A]
player_items = [potion, elixir]
#Creating player
#NAME, HP, MP, ATK, DEF, SPELLS, ITEMS
player = Player("Nathan", 10, 20, 5, 5, player_spells, player_items, 1, 0)
#Creating monster
cricket = Monster("Cricket", 3, 3, 7)
enemies = [cricket]
#Fight Setup
fighting = True
#gameplay
fight1 = Fight(player, cricket)
running = True
def player_hurt(enemy):
  edamage = enemy.damage_dealt()
  player.take_dmg(edamage)
  print("You have taken " + str(edamage) + " damage")
  print(str(player.hp) + " / " + str(player.maxhp))
def enemy_hurt(es):
  pdamage = player.generate_dmg()
  enemies[es].damage_taken(pdamage)
  print("Enemies HP is " + str(enemies[es].hp) + " / " + str(enemies[es].maxhp))
#action = input("Please select an action, Attack, Magic, Items ")
while running:
  
  print("1 for attack etc.")
  print("Please note that items are not available")
  choice = input(player.actions)
  list_chooser = int(choice) - 1
#ATTACK CHOOSE
  if list_chooser == 0:
    dmg = player.generate_dmg()
    enemy_hurt(0)
    print("You did " + str(dmg) + " damage")
    player_hurt(enemies[0])
    if cricket.hp == 0:
      os.system('clear')
      print("You have killed the cricket")
      player.hp = player.maxhp
      running = False
      #Add Exp element here later
#MAGIC CHOOSE
  if list_chooser == 1:
    print("Choose 1 for first spell, etc. ")
    magic_choice = input("Heal")
    magic_choice_real = int(magic_choice) - 1
    if magic_choice_real == 0:
      if player.mp < heal_A.cost:
        print("Insufficient mana")
      if player.mp >= heal_A.cost:
        player.heal(heal_A.dmg)
        print("You healed for " + str(heal_A.dmg))
        player.mp -= heal_A.cost
        print("You lost " + str(heal_A.cost) + " mana")
        player_hurt(cricket)
  if list_chooser == 3:
    player.get_stats()

Player

# IMPORTS

import random

#CLASS PLAYER

class Player():
  def __init__(self, name, hp, mp, atk, df, magic, items, lv, exp):
    self.lv = lv
    self.exp = exp
    self.exp_next = lv * 50
    self.maxhp = hp
    self.hp = hp
    self.maxmp = mp
    self.mp = mp
    self.atklow = atk - 2
    self.atkhigh = atk + self.lv
    self.df = df - 100
    self.dfc = df / 100
    self.magic = magic
    self.items = items
    self.actions = ["Attack", "Magic", "Items", "Stats"]
    self.name = name
    

#Dealing Damage
    
  def generate_dmg(self):  
    return random.randrange(self.atklow, self.atkhigh)
    
#Taking Damage
    
  def take_dmg(self, dmg):
    self.hp -= dmg
    if self.hp < 0:
      self.hp = 0
    return self.hp

  #Healing

  def heal(self, dmg):
    self.hp += dmg
    if self.hp > self.maxhp:
      self.hp = self.maxhp

  #Returning HP Values

  def get_hp(self):
    return self.hp

  def get_maxhp(self):
    return self.maxhp

  #Mana Cost Logic

  def reduce_mp(self, cost):
    self.mp -= cost

  #Actions
  def get_stats(self):
    print("HP")
    print(self.hp)
    print("--")
    print(self.maxhp)
    print("")
    print("MP")
    print(self.mp)
    print("--")
    print(self.maxmp)
    print("")
    print("ATK")
    print(self.atklow + self.atkhigh)
    print("LV")
    print(self.lv)
    print("EXP AND EXP TO NEXT")
    print(str(self.exp) + " / " +  str(self.exp_next))
    
  def level_up(self):
    self.lv += 1
    self.exp = 0
    self.maxhp += self.lv
    self.atk += self.lv
    

Monster

import random
class Monster:
  def __init__(self, name, atk, df, hp):
    self.name = name
    self.atk = atk
    self.hp = hp
    self.maxhp = hp
    self.atklow = self.atk - 2
    self.atkhigh = self.atk + 2
  def damage_dealt(self):
    return random.randrange(self.atklow, self.atkhigh)
  def damage_taken(self, dmg):
    self.hp -= dmg  
    if self.hp < 0:
      self.hp = 0
    return self.hp
  def get_hp(self):
    return self.hp
  def get_maxhp(self):
    return self.maxhp

items

    class Item:
      def __init__(self, type, name, desc, amount):
        self.type = type
        self.name = name
        self.desc = desc
        self.amount = amount
Spells
import random
class Spells:
  def __init__(self, type, name, dmg, cost):
    self.type = type
    self.name = name
    self.dmg = dmg
    self.cost = cost

  def generate_dmg(self):
    low = self.dmg + 3
    high = self.dmg - 3
    return random.randrange(low, high)

gameplay

import random
import os
class Fight:
  def __init__(self, enemy, player):
    self.enemy = enemy
    self.player = player
    self.playert = True
    self.enemyt = False
    self.player_action_allowed = False
    self.player_action_allowed = False
  def turns(self):
    if self.playert == True:
      self.player_action_allowed = True
      self.enemyt = True
      self.playert = False
    elif self.enemyt == True:
      enemy_action_allowed = True
      player_action_allowed = False
      playert = True
      enemyt = False
    else:
      playert = True
1 Answers

Your loop generates damage, and then calls enemy_hurt:

while running:
  
# ...
    dmg = player.generate_dmg()
    enemy_hurt(0)
    print("You did " + str(dmg) + " damage")

But enemy_hurt also generates damage of its own:

def enemy_hurt(es):
    pdamage = player.generate_dmg()
    enemies[es].damage_taken(pdamage)
    print("Enemies HP is " + str(enemies[es].hp) + " / " + str(enemies[es].maxhp))

Surely you want to only generate damage once, right? You're generating two different damage values, one you print, the other you actually subtract from the enemy's health.

Related