2023 Coding Competition Entries
About
Enter!
The Arena of Heroes
by Danny from Woodleigh School
X
Code
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ THE ARENA OF HEROES A simple text-based combat game based around slaying enemies and gaining resources to survive as long as possible! """ #imports from time import sleep import random from csinsc import * #welcome print(f"{Colour.cyan}Welcome to the Heroes Arena!\n") print(f"Survive as as many {Colour.red}battles{Colour.cyan} as possible to win points!") print(f"Choose your {Colour.red}weapons{Colour.reset} and {Colour.red}potions{Colour.reset} wisely to survive!") sleep(2) input("Press any button to start...") #score calculation score=1 #character creation #player_name=input("Enter your character's name: ") class Weapon: def __init__(self, name, dmg,acc): self.name=name self.dmg=dmg self.acc=acc def tryAttackValue(self): self.toHit=random.randint(1,self.acc)+self.acc/2 if self.toHit % 2 == 0: return self.toHit else: return int(round(self.toHit)) def damageValue(self): self.toDmg=random.randint(1,self.dmg)+self.dmg/2 if self.toDmg % 2 == 0: return self.toDmg else: return int(round(self.toDmg)) def wep_attributes(self): wep_str = (f"{Colour.magenta}{self.name} \n{Colour.red}Damage: {self.dmg} \n{Colour.blue}Accuracy: {self.acc}{Colour.reset}") return wep_str class Potion: def __init__(self,name,heal): self.name=name self.heal=heal def healValue(self): self.healNum=random.randint(1,self.heal)+self.heal/2 if self.healNum % 2 == 0: return self.healNum else: return int(round(self.healNum)) def potAttributes(self): pot_str = f"{Colour.magenta}{self.name}{Colour.reset}\n{Colour.green}Potency: {self.heal}\n{Colour.reset}\n" return pot_str #healing potions supremeHeal=Potion("Supreme healing potion",8) greaterHeal=Potion("Greater healing potion",5) lesserHeal=Potion("Lesser healing potion",3) #weapons shortsword=Weapon(f'{Colour.magenta}Shortsword{Colour.reset}',3,8) warHammer=Weapon(f"{Colour.magenta}Warhammer{Colour.reset}",7,4) longsword=Weapon(f"{Colour.magenta}Longsword{Colour.reset}",6,7) mace=Weapon(f"{Colour.magenta}Mace{Colour.reset}",7,6) dagger=Weapon(f"{Colour.magenta}Dagger{Colour.reset}",2,9) claws=Weapon(f"{Colour.magenta}Claw{Colour.reset}",3,8) fist=Weapon(f"{Colour.magenta}Fist{Colour.reset}",3,8) bite=Weapon(f"{Colour.magenta}Bite{Colour.reset}",4,7) weapons=[shortsword,warHammer,longsword,mace,dagger] class Entity(): def __init__(self, name, hp, maxhp, ac, mana, currentWeapon): self.name=name self.maxhp=maxhp self.hp=maxhp self.ac=ac self.mana=mana self.currentWeapon=currentWeapon def isDead(self): return self.hp <= 0 #need to find a way to add a list that can be appended to for each entity's inventory def attributes(self): string = Colour.reset + "---- Your Stats ---- \n" + Colour.green + "Health: " + str(self.hp) + Colour.cyan + "\nArmour level: " + str(self.ac) + Colour.magenta + "\nEquipped weapon: " + str(self.currentWeapon.name) + Colour.reset return string class Enemy(Entity): def __init__(self, name, hp, maxhp, ac, currentWeapon, attack1,attack2,attack3): self.name=name self.hp=hp self.maxhp=maxhp self.ac=ac self.currentWeapon=currentWeapon self.attack1=attack1 self.attack2=attack2 self.attack3=attack3 #defining enemies orc=Enemy(f"{Colour.red}Orc{Colour.reset}",10,10, 7, None, warHammer,longsword,fist) darkKnight=Enemy(f"{Colour.red}Dark Knight{Colour.reset}",7,7,10,None,warHammer,longsword,shortsword) wolf=Enemy(f"{Colour.red}Wolf{Colour.reset}",12,12,5,None,claws,claws,bite) vampire=Enemy(f"{Colour.red}Vampire{Colour.reset}",11,11,6,None,dagger,dagger,bite) zombie=Enemy(f"{Colour.red}Zombie{Colour.reset}",13,13,4,None,claws,claws,bite) cyclops=Enemy(f"{Colour.red}Cyclops{Colour.reset}",11,11,6,None,warHammer,shortsword,fist) #list of all enemies so they can be randomly chosen from a list monsters=[orc,darkKnight,wolf,vampire,zombie,cyclops] #defining player player=Entity("player_name",10,10,8,0,shortsword) #%% #player inventory player_inventory=[] player_inventory.append(player.currentWeapon) player_inventory.append(warHammer) player_inventory.append(greaterHeal) player_inventory_visual=[] indexNum=0 for e in player_inventory: indexNum+=1 if isinstance(e,Weapon): player_inventory_visual.append(f"({indexNum}) {e.wep_attributes()}\n\n") elif isinstance(e,Potion): player_inventory_visual.append(f"({indexNum}) {e.potAttributes()}") vis_inv_str = (f"---- Inventory ----\n" + ''.join(player_inventory_visual)) #player weapons inventory player_weapons_inventory=[i for i in player_inventory if isinstance(i,Weapon)] player_weapons_visual_inventory=[] wepindexNum=0 for e in player_weapons_inventory: wepindexNum+=1 player_weapons_visual_inventory.append(f"({wepindexNum}) {e.wep_attributes()}\n\n") wep_inv_vis_str = (f"{Colour.reset}---- Weapons ----\n" + ''.join(player_weapons_visual_inventory)) #player potion bag player_potion_inventory=[d for d in player_inventory if isinstance(d,Potion)] player_potion_visual_inventory=[] potindexNum=0 for f in player_potion_inventory: potindexNum+=1 visStrPot=f"({potindexNum}) {f.potAttributes()}\n\n" player_potion_visual_inventory.append(visStrPot) pot_bag_str = (f"{Colour.reset}---- Potions ----\n" + ''.join(player_potion_visual_inventory)) #%% def attack(dealer,taker): if dealer==player: if dealer.currentWeapon.tryAttackValue()<taker.ac: print(f"\nYour {player.currentWeapon.name} misses!") else: print(f"\nYour {player.currentWeapon.name} hits!") taker.hp-=dealer.currentWeapon.damageValue() print(f"You dealt {player.currentWeapon.damageValue()} damage!") else: if dealer.currentWeapon.tryAttackValue()<taker.ac: print(f"\nThe {dealer.name}'s {dealer.currentWeapon.name} misses you!\n") else: print(f"\nThe {dealer.name}'s {dealer.currentWeapon.name} hits!") taker.hp-=dealer.currentWeapon.damageValue() print(f"You took {dealer.currentWeapon.damageValue()} damage!\n") return taker.hp #%% #determining enemy while True: #detecting player death early to stop them playing while dead if player.isDead(): break #determining enemy from monsters list defined above enemy=random.choice(monsters) #print randomised encounter text mean_adjectives=["wild","dangerous","menacing","fiery","nasty","beastly"] encounterNames=["You have come across a","You have stumbled across a", "You have found yourself in front of a","You have been approached by a"] #clear screen after each battle print(f"{Colour.reset}{random.choice(encounterNames)} {random.choice(mean_adjectives)} {enemy.name}!\n") sleep(2) #combat loop while True: #updating inventory player_inventory_visual=[] indexNum=0 for e in player_inventory: indexNum+=1 if isinstance(e,Weapon): player_inventory_visual.append(f"({indexNum}) {e.wep_attributes()}\n\n") elif isinstance(e,Potion): player_inventory_visual.append(f"({indexNum}) {e.potAttributes()}") vis_inv_str = (f"---- Inventory ----\n" + ''.join(player_inventory_visual)) #player weapons inventory player_weapons_inventory=[i for i in player_inventory if isinstance(i,Weapon)] player_weapons_visual_inventory=[] wepindexNum=0 for e in player_weapons_inventory: wepindexNum+=1 player_weapons_visual_inventory.append(f"({wepindexNum}) {e.wep_attributes()}\n\n") wep_inv_vis_str = (f"{Colour.reset}---- Weapons ----\n" + ''.join(player_weapons_visual_inventory)) #player potion bag player_potion_inventory=[d for d in player_inventory if isinstance(d,Potion)] player_potion_visual_inventory=[] potindexNum=0 for f in player_potion_inventory: potindexNum+=1 visStrPot=f"({potindexNum}) {f.potAttributes()}\n\n" player_potion_visual_inventory.append(visStrPot) pot_bag_str = (f"{Colour.reset}---- Potions ----\n" + ''.join(player_potion_visual_inventory)) if player_potion_visual_inventory == []: pot_bag_str = (f"{Colour.reset}---- Potions ----\n{Colour.red}Empty!{Colour.reset}") print(f"{enemy.name} health: {Colour.green}{enemy.hp}\n") sleep(2) #print player options (loop for invalid inputs) while True: print(player.attributes()) sleep(2) player_turn = input(f"\n---- Actions ---- \n(1) Attack with {player.currentWeapon.name} \n(2) Open {Colour.green}inventory\n{Colour.reset}(3) Change {Colour.red}equipped weapon\n{Colour.reset}(4) Open {Colour.blue}potion bag{Colour.reset}\nType 1,2,3 or 4:\n") if player_turn == '1': attack(player,enemy) sleep(2) break #takes turn to attack - breaks player loop elif player_turn == '3': sleep(0.4) print("\n",wep_inv_vis_str) sleep(2) #catching errors with integer input while True: try: newWep = int(input(f"New {Colour.red}weapon{Colour.reset} (Type corresponding {Colour.blue}number{Colour.reset}): \n")) player.currentWeapon=player_weapons_inventory[newWep-1] "\n" break except (ValueError,NameError,IndexError): print(f"{Colour.red} Invalid input!{Colour.reset}") continue elif player_turn == '2': sleep(0.4) print("\n",vis_inv_str) sleep(1) input("Press enter to continue...") elif player_turn == '4': while True: sleep(0.4) print("\n",pot_bag_str) sleep(0.5) try: use_potion=int(input(f"Type corresponding {Colour.blue}number{Colour.reset} to use potion,\nType {Colour.cyan}'0' to close {Colour.blue}potion bag{Colour.reset}.\nInput: ")) if use_potion == 0: break else: drink_phrases=["guzzle down",'gulp down','chug','drink'] print(f"You {random.choice(drink_phrases)} the {Colour.red}{player_potion_inventory[use_potion-1].name}{Colour.reset}, healing {Colour.green}{player_potion_inventory[use_potion-1].healValue()}{Colour.reset} health points.\n") sleep(2) if player_potion_inventory[use_potion-1].healValue() < player.maxhp-player.hp: player.hp += player_potion_inventory[use_potion-1].healValue() else: player.hp = player.maxhp player_inventory.remove(player_potion_inventory[use_potion-1]) break except (ValueError,IndexError): print("Invalid input!") if use_potion != 0: break #drinking takes turn - breaks player turn loop else: continue else: sleep(1) print(f"\n{Colour.red}Invalid input!{Colour.reset}\n") sleep(1) #enemy turn #detecting enemy death if enemy.isDead(): bested_lines=["bested the","defeated the","slain the"] valiant_adjectives=["valiantly","heroically","masterfully","skillfully"] print(f"\nYou have {random.choice(valiant_adjectives)} {random.choice(bested_lines)} {enemy.name}!") drops = [enemy.attack1,enemy.attack2] drop = random.choice(drops) print(f"The {enemy.name} left behind its {drop.name}.") while True: take = str(input(f"Take {drop.name}? [Yes/No]")).lower() if take == "yes": player_inventory.append(drop) break if take == "no": break else: print("Invalid input!") potion_choice=random.randint(1,6) new_potion = None if potion_choice == 1: new_potion=supremeHeal elif potion_choice == 2 or 3: new_potion=greaterHeal else: new_potion=lesserHeal print(f"The {enemy.name} also dropped a {new_potion.name}.") while True: take = str(input(f"Take {new_potion.name}? [Yes/No]")).lower() if take == "yes": player_inventory.append(new_potion) break if take == "no": break else: print("Invalid input!") sleep(1) score *= 2 #multiplies current score - gets harder as the game goes on, so more score should be awarded print(f"Your score is {score}\n") sleep(2.5) enemy.hp=enemy.maxhp break #randomising attack used enemyAction = random.randint(1,3) if enemyAction == 1: enemy.currentWeapon=enemy.attack1 elif enemyAction == 2: enemy.currentWeapon=enemy.attack2 elif enemyAction == 3: enemy.currentWeapon = enemy.attack3 attack(enemy,player) sleep(2) #detecting player death if player.isDead(): break #death messages and final score print("You were {Colour.red}slain{Colour.reset} combat.") sleep(1.5) print("\nYou ascend to the {Colour.red}hall of heroes!{Colour.reset}") sleep(1.5) print(f"Final score: {Colour.green}{score}{Colour.reset}")