Python Forum
Looking for feedback on a game I made
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Looking for feedback on a game I made
#1
I'm a beginner python programmer and was looking for some feedback/improvements/criticism on a game I made. The game itself is a Pokemon-like turn-based battle with varied attack stats and a potion system. Thanks in advance for any thoughts and ideas.

Code:
#Last Edited - 1/25/18
#Version History
#6/16/17 - 1.0
#1/25/18 - 1.2 Naming feature. Set enemy potion amount. Varied the attack stat. General improvents
#1/26/18 - 1.21 Random player/enemy function

#Cheatcodes for debugging: 'cheathealth' 'cheatattack' 'nothing'

print("\n" * 100)
print('#########################')
print('##--*Medieval Battle*--##')
print('#-M1st3rPuncak3-6/16/17-#')
print('######-Version 1.21-######')
print('#########################')

from random import randint
#randint(min,max)
import time
#time.sleep(sec)
global potions
global epotions
#defines Character class
class Character:
  def __init__(self, name):
    self.name = name
    self.health = []
    self.maxhealth = []
    self.tdmg = []
    self.sdmg = []

  def add_tdmg(self, t):
    self.tdmg.append(t)

  def add_sdmg(self, s):
    self.sdmg.append(s)

  def add_health(self, h):
    self.health.append(h)

  def add_maxhealth(self, m):
    self.maxhealth.append(m)


#names char
hunter = Character('Hunter')
knight = Character('Knight')
heavy = Character('Heavy')

###ADD RANDint dmg in attack phase###

#gives dmgs
hunter.add_tdmg('3-5')
hunter.add_sdmg('5-7')
knight.add_tdmg('2-4')
knight.add_sdmg('4-6')
heavy.add_tdmg('1-3')
heavy.add_sdmg('3-5')
#gives health
hunter.add_health(20)
knight.add_health(25)
heavy.add_health(30)

#gives max health
hunter.add_maxhealth(20)
knight.add_maxhealth(25)
heavy.add_maxhealth(30)

#names char
ehunter = Character('Hunter')
eknight = Character('Knight')
eheavy = Character('Heavy')

#gives dmgs
ehunter.add_tdmg('3-5')
ehunter.add_sdmg('5-7')
eknight.add_tdmg('2-4')
eknight.add_sdmg('4-6')
eheavy.add_tdmg('1-3')
eheavy.add_sdmg('3-5')
#gives health
ehunter.add_health(20)
eknight.add_health(25)
eheavy.add_health(30)

#gives max health
ehunter.add_maxhealth(20)
eknight.add_maxhealth(25)
eheavy.add_maxhealth(30)


time.sleep(2)
print("\n")

#choose char
print("1. %r (%rhp)[Thrust(%rdmg) Swing(%rdmg)]"%(hunter.name, hunter.maxhealth[0], hunter.tdmg[0], hunter.sdmg[0]))
print("2. %r (%rhp)[Thrust(%rdmg) Swing(%rdmg)]"%(knight.name, knight.maxhealth[0], knight.tdmg[0], knight.sdmg[0]))
print("3. %r (%rhp)[Thrust(%rdmg) Swing(%rdmg)]"%(heavy.name, heavy.maxhealth[0], heavy.tdmg[0], heavy.sdmg[0]))
print("4. Random")
print("\n")

x = input("Choose your character: ")
if x == "1":
  player = hunter
if x == "2":
  player = knight
if x == "3":
  player = heavy
if x == "4":
  rand = randint(1,3)
  if rand == 1:
    player = hunter
    print("Player is a Hunter")
  if rand == 2:
    player = heavy 
    print("Player is a Heavy")
  if rand == 3:
    player = knight
    print("Player is a Knight")
#sets player name
pname = input('Name your character: ')
player.name = pname
#choose opponent
print("\n")

y = input("Choose your opponent: ")
if y == "1":
  enemy = ehunter
if y == "2":
  enemy = eknight
if y == "3":
  enemy = eheavy
if y == "4":
  erand = randint(1,3)
  if erand == 1:
    enemy = ehunter
    print("Enemy is a Hunter")
  if erand == 2:
    enemy = eheavy
    print("Enemy is a Heavy")
  if erand == 3:
    enemy = eknight
    print("Enemy is a Knight")
#sets enemy name
ename = input('Name your enemy: ')
enemy.name = ename
#Gives the default 3 potions
potions = 3
epotions = 3
#The phase where player chooses action and it calculates the action
def battle():
  import time
  from random import randint
  global potions
  #checks for player death
  if player.health[0] <= 0:
    print("You died!")
    time.sleep(1)
  else:
    #prints player and enemy health
    print("\n")
    print("%r health:"%(player.name),"%r/%r"%(player.health[0],player.maxhealth[0]))
    print("Player potions remaining: " + str(potions))
    time.sleep(1)
    print("%r health:"%(enemy.name),"%r/%r"%(enemy.health[0],enemy.maxhealth[0]))
    print("Enemy potions remaining: " + str(epotions))
    time.sleep(1)
    print("\n")
    #player chooses action
    print("Thrust, Swing, or Heal!")
    time.sleep(1)
    print("{1.Small Thrust - %r damage(75%% to hit)}"%(player.tdmg[0]))
    print("{2.Large Swing - %r damage(50%% to hit)}"%(player.sdmg[0]))
    print("{3.Heal-10hp, %r potions left}"%(potions))
    print("\n")
    decide = input('1, 2, or 3 > ')
    time.sleep(1)
    #Adds a blank space
    print("\n" * 100)
    #thrust calculation
    if decide == "1":
      #calculates the pseudo-random miss chance
      chance = randint(1,4)
      #miss
      if chance == 1:
        print("Your thrust missed!")
        time.sleep(1)
        e_attack()
      #hit
      #adds attack values
      else:
        if player == hunter:
          player.add_tdmg(randint(3,5))
        if player == knight:
          player.add_tdmg(randint(2,4))
        if player == heavy:
          player.add_tdmg(randint(1,3))
        print("Your thrust hit!")
        time.sleep(1)
        print("You dealt %r damage!"%player.tdmg[-1])
        time.sleep(1)
        #Changes enemy health
        enemy.health[0] -= player.tdmg[-1]
        e_attack()
    #swing calculation
    if decide == "2" or decide == "large swing" or decide == "Large Thrust":
      #calculates the pseudo-random miss chance
      chance2 = randint(1,2)
      #miss
      if chance2 == 1:
        print("Your swing missed!")
        time.sleep(1)
        e_attack()
      #hit
      else:
        if player == hunter:
          player.add_sdmg(randint(5,7))
        if player == knight:
          player.add_sdmg(randint(4,6))
        if player == heavy:
          player.add_sdmg(randint(3,5))
        print("Your swing hit!")
        time.sleep(1)
        print("You dealt %r damage!"%player.sdmg[-1])
        time.sleep(1)
      #changes enemy health
        enemy.health[0] -= player.sdmg[-1]
        e_attack()
    #healing calculations
    if decide == "3":
      #checks for potions
      if potions > 0:
        print("You drank a potion!")
        time.sleep(1)
        #adds health
        player.health[0] += 10
        potions -= 1
        #checks for health being over max
        if player.health[0] > player.maxhealth[0]:
          #sets health to max if over max
          player.health[0] = player.maxhealth[0]
          print("Your health:",player.health[0],"/",player.maxhealth[0])
          e_attack()
        else:
          print("Your health:",player.health[0],"/",player.maxhealth[0])
          e_attack()
      else:
        print("Out of potions!")
        time.sleep(1)
        battle()
    #'nothing' = do nothing
    #This is used as a test if I dont want to attack the enemy
    if decide == "nothing":
      print("You did nothing!")
      time.sleep(1)
      e_attack()
    #Cheat used to heal player for testing
    if decide == "cheatheal":
      print("Health raised")
      player.health = player.maxhealth
      battle()
    if decide == "cheatattack":
      print("Enemy weakened")
      enemy.health[0] = randint(1,10)
      e_attack()
def e_hit():
  #Calculates whether enemy will thrust or swing
  echance = randint(1,2)
  #Thrust
  if echance == 1:
      #Calcualates enemy thrust hit rate
    schance = randint(1,4)
    #miss
    if schance == 1:
      print("Enemy thrust missed!")
      time.sleep(1)
      battle()
    #hit
    else:
      if enemy == ehunter:
        enemy.add_tdmg(randint(3,5))
      if enemy == eknight:
        enemy.add_tdmg(randint(2,4))
      if enemy == eheavy:
        enemy.add_tdmg(randint(1,3))
      print("Enemy thrust hit!")
      time.sleep(1)
      print("Enemy dealt %r damage!" %enemy.tdmg[-1])
      time.sleep(1)
      #deals damage to player
      player.health[0] -= enemy.tdmg[-1]
      battle()
  #Swing
  if echance == 2:
    #Calculates enemy swing hit rate
    lchance = randint (1,2)
    #miss
    if lchance == 1:
      print("Enemy swing missed!")
      time.sleep(1)
      battle()
    #hit
    else:
      if enemy == ehunter:
        enemy.add_sdmg(randint(5,7))
      if enemy == eknight:
        enemy.add_sdmg(randint(4,6))
      if enemy == eheavy:
        enemy.add_sdmg(randint(3,5))
      print("Enemy swing hit!")
      time.sleep(1)
      print("Enemy dealt %r damage!" %enemy.sdmg[-1])
      time.sleep(1)
      #deals damage to player
      player.health[0] -= enemy.sdmg[-1]
      battle()

def e_attack():
  import time
  from random import randint
  global epotions
  #checks for enemy death
  if enemy.health[0] <= 0:
    print("Enemy Killed!")
    time.sleep(1)
  elif enemy.health[0] <= 10:
    if epotions <= 0:
      e_hit()
    else:
      hchance = randint(1,3)
      if hchance == 1:
        print("Enemy drank a potion!")
        epotions -= 1
        print("Enemy potions remaining: " + str(epotions))
        time.sleep(1)
        enemy.health[0] += 10
        battle()
      else:
        e_hit()
  else:
    e_hit()


#begins battle
battle()
Reply
#2
Im not going to sugar coat it. Your code is spaghetti code. But all of ours was when we first started. Its a process.


Just pass your values to Character through the dunder init method __init__ like you did with name. You dont need them in lists anyways. Use the python format method. All imports should be at the top of the file.Towards the end you code is quite unorganized. Get rid of most of the comments. Some help, while a lot just clutter the code. Most python code is self explanatory.
Recommended Tutorials:
Reply
#3
@metulburr Thanks for the tips. I haven't been properly taught in python and don't have enough time to really get invested in it, but I was just putting this semi-old creation out there to get some feedback.

I'll have to look into understanding how to condense the code more but I'm probably going to leave the comments for myself, just as a way to organize it and reteach myself in case I forget some basic python concepts.
Reply
#4
its not about condensing the code. Its about restructuring it. While restructuring it you will also condense it. But condensing it should not be the main goal....organization is.

Also another thing i see now that i copied and paste the code is you should use 4 spaced indents as its the normal. More info here
https://www.python.org/dev/peps/pep-0008/

an example of the beginning class structure
class Character:
    def __init__(self, name, health, maxhealth, tdmg, sdmg):
        self.name = name
        self.health = health
        self.maxhealth = maxhealth
        self.tdmg = tdmg
        self.sdmg = sdmg

hunter = Character('Hunter', 20, 20, '3-5', '4-6')
knight = Character('Knight', 25, 25, '5-7', '1-3')
heavy = Character('Heavy', 30, 30, '5-7', '3-5')
Recommended Tutorials:
Reply
#5
That makes much more sense than the way I did it... Thanks for that! Ill have to look further into how to properly style the code. Not too worried about this script in particular, only because it's just a small game I made for myself.
Reply
#6
Yeah but the more fixes you make early the less mistakes on a later game. The ultimate goal would be to write code where you dont have to restructure it because you already have the structure organized in your head. But until then you have to keep reworking it.
Recommended Tutorials:
Reply
#7
Any feedback on the game itself? Perhaps balancing issues or possible features? I was thinking of making an adventure game that would use the battle() function for the numerous encounters
Reply
#8
Hey guys,

I like it. I've been meaning to finish something similar for a while now. My very own Dungeons and Dragons Dice Rolling Bot

https://python-forum.io/Thread-Best-Prac...wo-Classes

So I posted that over there. What is best practice to pass variables in a scenario like this? What is best practice for the "game" mechanics. Anywho awesome start.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Hangman game, feedback appreciated WolfWayfarer 10 7,758 Jul-19-2018, 08:59 AM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020