5
\$\begingroup\$

I have began to practice Python after a couple of years and for my first Project, i decided to make a fighting/rpg-like game with different characters. So far, I am only familiar with loops and functions, not classes or OOP. Please give me any feedback on how I could improve my code, through debugging, optimization, or adding more content (In case the game doesn't start due to the absence of highscore.txt, please make a text file called highscore, and of the first line insert an interger, and on the second put any name. This should not happen, but just in case :P).

import random as r
######Getting High Score#####
try:
 hs = open("highscore.txt","r+")
except:
 hs = open("highscore.txt","x")
 hs = open("highscore.txt","r+")
try:
 score = hs.readlines(1)
 score = int(score[0])
 leader = hs.readlines(2)
 leader = str(leader[0])
except:
 hs = open("highscore.txt","w")
 hs.write("0\n")
 hs.write("null")
 hs = open("highscore.txt","r")
 score = hs.readlines(1)
 score = int(score[0])
 leader = hs.readlines(2)
 leader = str(leader[0])
#####Introduction, Initializing player#####
print("\nWELCOME TO WONDERLANDS RPG!")
print("The High Score is:",score,"by",leader)
points = 0
player_name = input("\nEnter your hero's name: ")
#####Classes [health, attack 1 (only does set damage), attack 2 min, attack 2 max, attack 3 min, attack 3 max, heal min, heal max], Getting player's Class#####
knight = [100,10,5,15,0,25,5,10] #health: 100, attack 1: 10, attack 2: 5-15, attack 3: 5-25, heal: 5-10
mage = [50,15,10,20,-5,25,10,15] #health: 50, attack 1: 15, attack 2: 10-20, attack 3: -5-25, heal: 10-15
healer = [150,5,5,10,5,15,10,20] #health: 150, attack 1: 5, attack 2: 5-10, attack 3: 5-15, heal: 10-20
while True:
 print("\n1. Knight: Health: ",knight[0],"; Attack 1:",knight[1],"; Attack 2:",knight[2],"-",knight[3],"; Attack 3:",knight[4],"-",knight[5],"; Heal:",knight[6],"-",knight[7])
 print("2. Mage: Health: ",mage[0],"; Attack 1:",mage[1],"; Attack 2:",mage[2],"-",mage[3],"; Attack 3:",mage[4],"-",mage[5],"; Heal:",mage[6],"-",mage[7])
 print("3. Healer: Health: ",healer[0],"; Attack 1:",healer[1],"; Attack 2:",healer[2],"-",healer[3],"; Attack 3:",healer[4],"-",healer[5],"; Heal:",healer[6],"-",healer[7])
 player_class = input("\nSelect your class: 1, 2, or 3: ")
 if player_class == "1":
 player_class = knight
 print("You have selected the Knight")
 break
 if player_class == "2":
 player_class = mage
 print("You have selected the Mage")
 break
 if player_class == "3":
 player_class = healer
 print("You have selected the Healer")
 break
 else:
 print("Please select a valid class.")
 continue
player_heal_max = player_class[0]
#####Difficulty/Upgrade Functions#####
def level_up(player,health_max):
 while True:
 lv_choice = input("\nWould you like to:\n Increase max health by 20 (1)\n Increase Healing Factor by 5 (2)\n increase your damage by 5 (3) ")
 if lv_choice == "1":
 health_max += 20
 player[0] = health_max
 return player,health_max
 elif lv_choice == "2":
 player[6] +=5
 player[7] +=5
 player[0] = health_max
 return player, health_max
 elif lv_choice == "3":
 player[1] +=5
 player[2] +=5
 player[3] +=5
 player[4] +=5
 player[5] +=5
 player[0] = health_max
 return player, health_max
 else:
 print("Please enter in a valid number")
 continue
def difficulty(ai,health_max,level):
 if level == 1:
 return ai
 else:
 ai[0] = health_max+15*round(0.5*level+0.5)
 ai[1] +=5*round(0.5*level+0.5)
 ai[2] +=5*round(0.5*level+0.5)
 ai[3] +=5*round(0.5*level+0.5)
 ai[4] +=5*round(0.5*level+0.5)
 ai[5] +=5*round(0.5*level+0.5)
 ai[6] +=5*round(0.5*level+0.5)
 ai[7] +=5*round(0.5*level+0.5)
 return ai
def ai_stats(s):
 s[0] += r.randint(-20,20)
 s[1] += r.randint(-3,3)
 s[2] += r.randint(-3,3)
 s[3] += r.randint(-3,3)
 s[4] += r.randint(-3,3)
 s[5] += r.randint(-3,3)
 s[6] += r.randint(-3,3)
 s[7] += r.randint(-3,3)
 return s
#####Game Loop#####
level = 1
print("\n----------------------- GAME START -----------------------")
while True:
 #####Determining AI Class/Stats#####
 #####(AI classes must be in the Game loop otherwise if an enemy chooses the same class twice, it would have <=0 HP, thus being an instant win)#####
 ai_knight = [100,10,5,15,0,25,5,10] #health: 100, attack 1: 10, attack 2: 5-15, attack 3: 5-25, heal: 5-10
 ai_mage = [50,15,10,20,-5,25,10,15] #health: 50, attack 1: 15, attack 2: 10-20, attack 3: -5-25, heal: 10-15
 ai_healer = [150,5,5,10,5,15,10,20] #health: 150, attack 1: 5, attack 2: 5-10, attack 3: 5-15, heal: 10-20
 ai = r.randint(1,3)
 if ai == 1:
 ai = ai_stats(ai_knight)
 print("\nYou are fighiting a knight with",ai[0],"HP!")
 if ai == 2:
 ai = ai_stats(ai_mage)
 print("\nYou are fighiting a mage with",ai[0],"HP!")
 if ai == 3:
 ai = ai_stats(ai_healer)
 print("\nYou are fighiting a healer with",ai[0],"HP!")
 ai_heal_max = ai[0]
 ai = difficulty(ai,ai_heal_max,level)
 #####Gameplay Loop#####
 while True:
 #####Player Attack#####
 player_move = input("\nWould you like to use attack (1), attack (2), attack (3), or heal (4)? ")
 print("")
 if player_move == "1":
 player_damage = player_class[1]
 ai[0] = ai[0]- player_damage
 print(player_name," did",player_damage,"damage!")
 elif player_move == "2":
 player_damage = r.randint(player_class[2],player_class[3])
 ai[0] = ai[0]- player_damage
 print(player_name," did",player_damage,"damage!")
 elif player_move == "3":
 player_damage = r.randint(player_class[4],player_class[5])
 if player_damage<0:
 player_class[0] = player_class[0]+player_damage
 print(player_name," damaged themselves for",player_damage,"HP!")
 else:
 ai[0] = ai[0]- player_damage
 print(player_name," did",player_damage,"damage!")
 elif player_move == "4":
 player_heal = r.randint(player_class[6],player_class[7])
 if player_class[0] + player_heal > player_heal_max:
 player_class[0] = player_heal_max
 else:
 player_class[0] = player_class[0] + player_heal
 print(player_name," healed for",player_heal,"HP")
 else:
 print("Please enter in a valid move.")
 continue
 #####Detecting Death#####
 if player_class[0]<=0:
 break
 elif ai[0]<=0:
 points += player_class[0]*level
 level +=1
 print("You have bested your opponent! You Have",points,"points. \nNow starting level",level)
 player_class,player_heal_max = level_up(player_class,player_heal_max)
 break
 #####AI Turn#####
 if ai[0] <= (ai_heal_max/5):
 ai_move = r.sample(set([1,2,3,4,4,4]), 1)[0]
 elif ai[0] >= (ai_heal_max*.8):
 ai_move = r.sample(set([1,2,3,1,2,3,4]), 1)[0]
 elif ai[0] == ai_heal_max:
 ai_move = r.randint(1,3)
 else:
 ai_move = r.randint(1,4)
 if ai_move == 1:
 ai_damage = ai[1]
 player_class[0] = player_class[0]- ai_damage
 print("Your opponent did",ai_damage,"damage!")
 elif ai_move == 2:
 ai_damage = r.randint(ai[2],ai[3])
 player_class[0] = player_class[0]- ai_damage
 print("Your opponent did",ai_damage,"damage!")
 elif ai_move == 3:
 ai_damage = r.randint(ai[4],ai[5])
 if ai_damage<0:
 ai[0] = ai[0]+ai_damage
 print("Your opponent damaged themselves for",ai_damage,"HP!")
 else:
 player_class[0] = player_class[0]- ai_damage
 print("Your opponent did",ai_damage,"damage!")
 elif ai_move == 4:
 ai_heal = r.randint(ai[6],ai[7])
 if ai[0] + ai_heal > ai_heal_max:
 ai[0] = ai_heal_max
 else:
 ai[0] = ai[0] + ai_heal
 print("Your opponent healed for",ai_heal,"HP")
 #####Displaying HP##### 
 print("\nYour health is:",player_class[0],"HP")
 print("Your opponent's health is",ai[0],"HP")
 #####Detecting Loss#####
 if player_class[0]<=0:
 break
 elif ai[0]<=0:
 points += player_class[0]*level
 level +=1
 print("You have bested your opponent! You Have",points,"points. \nNow starting level",level)
 player_class,player_heal_max = level_up(player_class,player_heal_max)
 break
 else:
 continue
 #####Finishing Game, Checking/Updating High Score#####
 if player_class[0]<=0:
 print("\nYou Died! :(")
 if points>score:
 hs = open("highscore.txt","w")
 hs.write(str(points))
 hs.write("\n")
 print("You have the new high score of",points,"!")
 hs.write(player_name)
 else:
 print("\nYou finished with",points,"points.")
 print("The high score is:",score,"by",leader)
 input("")
 hs.close()
 break
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jul 11, 2019 at 2:56
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Really cool game here. Thanks for sharing. Expect an answer soon. \$\endgroup\$ Commented Jul 12, 2019 at 0:13

1 Answer 1

2
\$\begingroup\$

In your game, which I've played, you have 3 main warriors: knight, mage, and healer. These warriors all have similar behaviors, health, attacks, and heals - they are essentially objects of a class, Warrior.

Tip 1: Let's create a Warrior class:

  • You will be able to create new Warriors (ie Archers, Brutes, Zombies) later with ease.
  • You can interface your AI player as a Warrior.
  • You can simply control all of your Warrior objects.
class Warrior:
 def __init__(self, health, attack_1, attack_2, attack_3, heal):
 self.health = health
 self.attack_1 = attack_1
 self.attack_2 = attack_2 # tuple ie (5,25) representing range for attack value
 self.attack_3 = attack_3 # tuple ie (10,20) representing range for attack value
 self.heal = heal # tuple ie (10,20) representing range for health value
 def attributes(self):
 # string containing the attributes of the character
 string = "Health: "+ str(self.health) + " Attack 1: "+ str(self.attack_1) + " Attack 2: "+ str(self.attack_2[0]) + "-"+ str(self.attack_2[1])+ " Attack 3: "+ str(self.attack_3[0]) + "-"+ str(self.attack_3[1]) + " Heal:"+ str(self.heal[0]) + "-" + str(self.heal[0])
 return string
 def is_dead(self):
 return self.health <= 0

You may want to add other functions later. For instance, def attack_3(self), which would return the value of an attack. We then initialize the knight, mage, healer, and ai as so:

knight = Warrior(100, 10, (5,15), (5,25), (5,10))
mage = Warrior(50, 15, (10,20), (-5,25), (10,15))
healer = Warrior(150, 5, (5,10), (5,15), (10,20))
while True:
 # Determining AI Class/Stats
 ai_knight = Warrior(100, 10, (5,15), (5,25), (5,10))
 ai_mage = Warrior(50, 15, (10,20), (-5,25), (10,15))
 ai_healer = Warrior(150, 5, (5,10), (5,15), (10,20))
 ai_classes = [ai_knight, ai_mage, ai_healer]
 ai = ai_classes[r.randint(0,2)]
 randomize_ai(ai)
 if ai == ai_knight:
 print("\nYou are fighting a knight with ", ai.health,"HP!")
 elif ai == ai_mage:
 print("\nYou are fighting a mage with ", ai.health,"HP!")
 elif ai == ai_healer:
 print("\nYou are fighting a healer with ", ai.health,"HP!")

Tip 2: elif is your best friend. If your if statements are mutually exclusive, you can cut down on the complexity of your program, by using elif(which you used successfully in your program, just not always):

if ai == 1:
 #code
if ai == 2:
 #code
if ai == 3:
 #code
# should instead be...
# because ai can't be three values at once
if ai == 1:
 #code
elif ai == 2:
 #code
elif ai == 3:
 #code

Tip 3: The style in which you program is critical to your actual program. A few basic things you should know about coding styles:

  • Do not use too many # when you are commenting. Instead of ######Displaying HP####### try # Display HP. The latter is more readable for someone else or yourself reading/reviewing your code.
  • If you have a section header comment, you can try a special commenting style such as:
###########
# CLASSES #
###########
  • Do not add extra spaces to your code -- this makes your code longer than it needs to and should be. Make your code shorter if it doesn't reduce readability.
  • To improve the user experience, avoid typos when possible
  • And whatever you do, be consistent. It's easiest to read, review, and edit code that is consistent in style.
  • Style is one of those things that just takes experience and practice. You will get better over time.

With these three tips in mind, your final code should look more like:

import random as r
try:
 hs = open("highscore.txt","r+")
except:
 hs = open("highscore.txt","x")
 hs = open("highscore.txt","r+")
try:
 score = int(hs.readlines(1)[0])
 score = int(score[0])
 leader = hs.readlines(2)
 leader = str(hs.readlines(2)[0])
except:
 hs = open("highscore.txt","w")
 hs.write("0\nnull")
 hs = open("highscore.txt","r")
 score = int(hs.readlines(1)[0])
 leader = str(hs.readlines(2)[0])
# Introduce and name the player
print ("\nWELCOME TO WONDERLANDS RPG!")
print ("The High Score is:", score, "by", leader)
points = 0
player_name = input ("\nEnter your hero's name: ")
###########
# CLASSES #
###########
class Warrior:
 def __init__(self, health, attack_1, attack_2, attack_3, heal):
 self.health = health
 self.attack_1 = attack_1
 self.attack_2 = attack_2 # tuple ie (5,25) representing range for attack value
 self.attack_3 = attack_3 # tuple ie (10,20) representing range for attack value
 self.heal = heal # tuple ie (10,20) representing range for health value
 def attributes(self):
 # string containing the attributes of the character
 string = "Health: "+ str(self.health) + " Attack 1: "+ str(self.attack_1) + " Attack 2: "+ str(self.attack_2[0]) + "-"+ str(self.attack_2[1])+ " Attack 3: "+ str(self.attack_3[0]) + "-"+ str(self.attack_3[1]) + " Heal:"+ str(self.heal[0]) + "-" + str(self.heal[0])
 return string
 def is_dead(self):
 return self.health <= 0
knight = Warrior(100, 10, (5,15), (5,25), (5,10))
mage = Warrior(50, 15, (10,20), (-5,25), (10,15))
healer = Warrior(150, 5, (5,10), (5,15), (10,20))
while True:
 print("\n1. Knight: ", knight.attributes())
 print("\n2. Mage: ", mage.attributes())
 print("\n3. Healer: ", healer.attributes())
 player_class = input("\nSelect your class: 1, 2, or 3: ")
 if player_class == "1":
 player_class = knight
 print("You have selected the Knight class.")
 break
 elif player_class == "2":
 player_class = mage
 print("You have selected the Mage")
 break
 elif player_class == "3":
 player_class = healer
 print("You have selected the Healer")
 break
 else:
 print("Please select a valid class.")
 continue
player_heal_max = player_class.health
################################
# Difficulty/Upgrade Functions #
################################
def level_up(player,health_max):
 while True:
 lv_choice = input("\nWould you like to:\n 1. Increase max health by 20 \n 2. Increase Healing Factor by 5 \n 3. increase your damage by 5\n")
 if lv_choice == "1":
 health_max += 20
 player.health = health_max
 return player, health_max
 elif lv_choice == "2":
 player.heal += (5,5)
 player.health = health_max
 return player, health_max
 elif lv_choice == "3":
 player.attack_1 += 5
 player.attack_2 += (5,5)
 player.attack_3 += (5,5)
 player.health = health_max
 return player, health_max
 else:
 print("Please enter in a valid number")
 continue
def difficulty(ai,health_max,level):
 if level == 1:
 return ai
 else:
 ai.health = health_max + 15 * round(0.5 * level + 0.5)
 ai.attack_1 += 5 * round(0.5 * level + 0.5)
 ai.attack_2 += (5 * round(0.5 * level + 0.5),5 * round(0.5 * level + 0.5))
 ai.attack_3 += (5 * round(0.5 * level + 0.5),5 * round(0.5 * level + 0.5))
 ai.heal += (5 * round(0.5 * level + 0.5),5 * round(0.5 * level + 0.5))
 return ai
def randomize_ai(ai):
 ai.health += r.randint(-20,20)
 ai.attack_1 += r.randint(-3,3)
 ai.attack_2 += (r.randint(-3,3),r.randint(-3,3))
 ai.attack_3 += (r.randint(-3,3),r.randint(-3,3))
 ai.heal += (r.randint(-3,3),r.randint(-3,3))
 return ai
#############
# Game Loop #
#############
level = 1
print("\n----------------------- GAME START -----------------------")
while True:
 # Determining AI Class/Stats
 ai_knight = Warrior(100, 10, (5,15), (5,25), (5,10))
 ai_mage = Warrior(50, 15, (10,20), (-5,25), (10,15))
 ai_healer = Warrior(150, 5, (5,10), (5,15), (10,20))
 ai_classes = [ai_knight, ai_mage, ai_healer]
 ai = ai_classes[r.randint(0,2)]
 randomize_ai(ai)
 if ai == ai_knight:
 print("\nYou are fighting a knight with ", ai.health,"HP!")
 elif ai == ai_mage:
 print("\nYou are fighting a mage with ", ai.health,"HP!")
 elif ai == ai_healer:
 print("\nYou are fighting a healer with ", ai.health,"HP!")
 ai_heal_max = ai.health
 ai = difficulty(ai, ai_heal_max, level)
 # Gameplay Loop
 while True:
 # Player Attack
 player_move = input("\nWould you like to use attack (1), attack (2), attack (3), or heal (4)? ")
 print("")
 if player_move == "1":
 player_damage = player_class.attack_1
 ai.health = ai.health - player_damage
 print(player_name," did",player_damage,"damage!")
 elif player_move == "2":
 player_damage = r.randint(player_class.attack_2[0],player_class.attack_2[1])
 ai.health = ai.health - player_damage
 print(player_name," did",player_damage,"damage!")
 elif player_move == "3":
 player_damage = r.randint(player_class.attack_3[0],player_class.attack_3[1])
 ai.health = ai.health - player_damage
 print(player_name," did", player_damage, " damage!")
 elif player_move == "4":
 player_heal = r.randint(player_class.heal[0],player_class.heal[1])
 if player_class.health + player_heal > player_heal_max:
 player_class.health = player_heal_max
 else:
 player_class.health = player_class.health + player_heal
 print(player_name," healed for",player_heal,"HP")
 else:
 print("Please enter in a valid move.")
 continue
 # Detecting Death
 if player_class.is_dead():
 break
 elif ai.is_dead():
 points += player_class.health * level
 level += 1
 print("You have bested your opponent! You Have",points,"points. \nNow starting level",level)
 player_class, player_heal_max = level_up(player_class,player_heal_max)
 break
 # AI Turn
 if ai.health <= (ai_heal_max/5):
 ai_move = r.sample(set([1,2,3,4,4,4]), 1)[0]
 elif ai.health >= (ai_heal_max*.8):
 ai_move = r.sample(set([1,2,3,1,2,3,4]), 1)[0]
 elif ai.health == ai_heal_max:
 ai_move = r.randint(1,3)
 else:
 ai_move = r.randint(1,4)
 if ai_move == 1:
 ai_damage = ai.attack_1
 player_class.health = player_class.health - ai_damage
 print("Your opponent did",ai_damage,"damage!")
 elif ai_move == 2:
 ai_damage = r.randint(ai.attack_2[0],ai.attack_2[1])
 player_class.health = player_class.health- ai_damage
 print("Your opponent did ",ai_damage," damage!")
 elif ai_move == 3:
 ai_damage = r.randint(ai.attack_3[0],ai.attack_3[1])
 player_class.health = player_class.health - ai_damage
 print("Your opponent did ", ai_damage," damage!")
 elif ai_move == 4:
 ai_heal = r.randint(ai.heal[0],ai.heal[1])
 if ai.health + ai_heal > ai_heal_max:
 ai.health = ai_heal_max
 else:
 ai.health = ai.health + ai_heal
 print("Your opponent healed for ", ai_heal," HP")
 # Displaying HP 
 print("\nYour health is:", player_class.health,"HP")
 print("Your opponent's health is ", ai.health," HP ")
 # Detecting Death
 if player_class.is_dead():
 break
 elif ai.health <= 0:
 points += player_class.health * level
 level += 1
 print("You have bested your opponent! You Have",points,"points. \nNow starting level",level)
 player_class, player_heal_max = level_up(player_class,player_heal_max)
 break
 # Finishing Game, Checking/Updating High Score
 if player_class.health<=0:
 print(" \ nYou Died !: (")
 if points > score:
 hs = open(" highscore.txt "," w ")
 hs.write(str(points))
 hs.write(" \ n ")
 print(" You have the new high score of ",points," !")
 hs.write(player_name)
 else:
 print(" \ nYou finished with ",points," points.")
 print(" The high score is:",score," by ",leader)
 input(" ")
 hs.close()
 break
```
answered Jul 12, 2019 at 17:29
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I made lots of other small edits. If you're curious about one of them, leave a comment and I'll be sure to respond. \$\endgroup\$ Commented Jul 12, 2019 at 17:30

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.