"""
"""
------------------------------------------------------------------------------------------------------------------------
Nathaniel Hu
ICS4U0
Python Assignment #2: Python Object Oriented Programming Introduction
Ms. S. Pais
Version 2.4.5
------------------------------------------------------------------------------------------------------------------------
This is World Of Wizards; a text-based game where users can purchase wizards, level them up and fights monsters and
other wizards.
"""
# import time and random modules to supplement the wizard and monster generators, and add real time delay effects
import time
import random
# Player class: contains all possible attributes related to the player (game user) in the game
class Player:
# creates local list to store all possible player rank titles the player can attain
player_rank_titles = ["Apprentice", "Adept", "Mage", "Enchanter", "Sorcerer", "Necromancer", "Summoner",
"Trickster", "Arch-Mage", "Spellbinder", "Arcane Wizard", "Grand Master"]
# creates local lists to store all possible items in the player's inventory
player_currency_inv = ["Wizard Stones: ", "Earth Stones: ", "Water Stones: ", "Fire Stones: ", "Air Stones: ",
"Gold: "]
player_health_potions_inv = ["Basic Potions: ", "Supreme Potions: ", "Master Potions: ", "Revive Potions: "]
# init function; initiates instance of the Player class, and states all of the attributes of the player; function
# imports generated player attributes, and assigns values to corresponding self variables
def __init__(self, name, rank_title, earth_stones, water_stones, fire_stones, air_stones, player_level,
level_progress, wizard_stones, gold, basic_potions, supreme_potions, master_potions, revive_potions):
# assigns imported values to the following Player class specific variables (player attributes): name, rank
# title, elemental stones inventory (earth, water. fire and air stones), player level, level progress, wizard
# stones, gold and healing potions inventory (basic, supreme, master and revival health potions)
self.name = name
self.rank_title = rank_title
self.stones_inv = [earth_stones, water_stones, fire_stones, air_stones]
self.player_level = player_level
self.level_progress = level_progress
self.wizard_stones = wizard_stones
self.gold = gold
self.healing_potions = [basic_potions, supreme_potions, master_potions, revive_potions]
# Wizard class: contains all possible methods and attributes related to the player summoned wizard characters
class Wizard:
# creates variable lists to store possible wizard attributes (i.e. wizard name, attacks, attack types, damage
# values (per attack), talents and buffs); lists used for generating wizards with unique sets of attributes
wiz_names = ["Avoxius", "Uxar", "Urim", "Talin", "Uvae", "Agaell", "Enisinore", "Izedeis"]
wiz_attacks = ["Razor Rocks", "Mountain Mash", "Stone Smash", "Dust Devils",
"Fireball Frenzy", "Blitzkrieg Blaze", "Searing Strike", "Combustion Charge",
"Water Whip", "Hailstorm ", "Icy Incursion", "Frozen Fusillade",
"Tempest Tornado", "Aerial Avalanche", "Lightning Lash", "Whirlwind Waste"]
wiz_atk_types = ["Earth", "Earth", "Earth", "Earth", "Fire", "Fire", "Fire", "Fire",
"Water", "Water", "Water", "Water", "Air", "Air", "Air", "Air"]
wiz_damages = [2, 4, 6, 8, 2, 4, 6, 8, 2, 4, 6, 8, 2, 4, 6, 8]
wiz_talents = ["Endurance", "Healing", "Might", "Flying"]
wiz_buffs = ["Armour", "Health", "Damage", "Speed"]
# init method; initiates instance of the Wizard class, and states all of the attributes of each wizard; function
# imports randomly generated wizard attributes, and assigns values to corresponding self variables
def __init__(self, name, cost_earth, cost_water, cost_fire, cost_air, wizard_level, wizard_level_progress, max_hp,
current_hp, wizard_attacks, wizard_attack_types, wizard_damage_values, wizard_talent, wizard_buff,
buff_amount, iff):
# assigns imported values to the following Wizard class specific variables (wizard attributes): name, cost
# (in earth, water, fire and air stones), wizard level and level progress, max/current hp, wizard attacks and
# attack types, damage values (per attack), the wizard talent, wizard buff specs (buff and amount) and iff
self.name = name
self.cost = [cost_earth * wizard_level, cost_water * wizard_level, cost_fire * wizard_level, cost_air *
wizard_level]
self.wizard_level = wizard_level
self.wizard_level_progress = wizard_level_progress
self.max_hp = max_hp
self.current_hp = current_hp
self.attacks = wizard_attacks
self.attack_types = wizard_attack_types
self.damages = wizard_damage_values
self.wizard_talent = wizard_talent
self.wizard_buff_specs = [wizard_buff, buff_amount]
self.iff = iff
# attack method; randomly chooses a wizard attack, retrieves its associated damage value, and applies any wizard
# talents/buffs to the outputted raw damage; referenced whenever a wizard is attacking a monster or another wizard
def attack(self):
# randomly generates integer value between 0 and 3 (possible integer values: 0, 1, 2, 3); stored in rand_num
rand_num = random.randint(0, 3)
# randomly generated integer value used as index value to retrieve wizard attack, attack type and damage value
attack_name = self.attacks[rand_num]
attack_type = self.attack_types[rand_num]
attack_damage = self.damages[rand_num]
# creates variable iff; stands for identification friend or foe, used by program to determine whether wizard is
# friendly (player owned) or foe (enemy wizard in arena)
iff = ""
# tests for wizard talent; runs if wizard talent affects damage dealt by wizard (i.e. Might)
if self.wizard_talent == "Might":
# randomly generates integer value between 0 and 1 (possible integer values: 0, 1)
rand_num = random.randint(0, 1)
# tests randomly generated integer value; runs if integer value is 1
if rand_num == 1:
# increases attack damage dealt by 2 points
attack_damage += 2
# runs if integer value is not 1 (is 0)
else:
# passes onto next code block
pass
# runs if wizard talent does not affect damage dealt by wizard (i.e. Endurance, Healing or Flying)
else:
# passes onto next code block
pass
# tests for wizard buff; runs if wizard buff affects damage dealt by wizard (i.e. Damage)
if self.wizard_buff_specs[0] == "Damage":
# increases attack damage dealt by the wizard buff amount (1 buff point = 1 added damage point)
attack_damage += self.wizard_buff_specs[1]
# runs if wizard buff does not affect damage dealt by wizard (i.e. Armour, Health or Speed)
else:
# passes onto next code block
pass
# test iff variable value of the attacking wizard (Wizard class instance); runs if value is "friend"
if self.iff == "friend":
# assigns the string value "Your wizard, " to variable iff; to be used in final wizard attack output message
iff = "Your wizard, "
# runs if iff variable value of the attacking wizard (Wizard class instance) is value "foe" (only other option)
else:
# passes on to next code block
pass
# prints output message, displaying wizard name, iff indicator, attack name, attack type and raw damage dealt
print("----------------------------------------------------------------\n" + iff + self.name + " used the " +
attack_type + " type attack, " + attack_name + ", and dealt " + str(attack_damage) + " points of raw " +
"damage.")
# returns the raw attack damage dealt to the referencing variable (used to reference this method)
return attack_damage
# defend method; takes in the raw damage dealt by the monster or other wizard, applies wizard talents/buffs (which
# affect the net damage taken by the wizard) before outputting the damage taken (and amount healed as applicable)
def defend(self, raw_damage):
""" (int) -> int, int
returns net damage taken (and amount healed) by wizard after talents/buffs are applied
defend(5)
if buff == "Endurance":
3, 0
defend(7)
if buff == "Healing":
7, 2
"""
# raw_damage value retrieved and stored in variable damage_taken
damage_taken = raw_damage
# damage_healed variable value initially set to 0
damage_healed = 0
# creates variable rand_num; to be used to store integer values to determine effect of wizard talents/buffs
rand_num = int()
# creates variable iff; stands for identification friend or foe, used by program to determine whether wizard is
# friendly (player owned) or foe (enemy wizard in arena)
iff = ""
# tests for wizard talent; runs if talent affects damage taken by wizard (i.e. Endurance, Healing or Flying)
if self.wizard_talent != "Might":
# assigns randomly chosen number (0 or 1) to variable rand_num; to be used in determining talent effects
rand_num = random.randint(0, 1)
# runs if wizard talent does not affect damage taken by wizard (i.e. Might)
else:
# wizard damage dealt and healing are unaffected; code passes onto next block
pass
# tests rand_num variable value; runs if tested value is 1 (wizard talent will take effect)
if rand_num == 1:
# tests for wizard talent; runs if talent is "Endurance" or "Flying"
if (self.wizard_talent == "Endurance") or (self.wizard_talent == "Flying"):
# reduces damage taken by 2 points per wizard level (talent effect)
damage_taken -= 2 * self.wizard_level
# tests damage taken value, runs if it is less than 0 (is a negative integer value)
if damage_taken < 0:
# assigns value of 0 to damage value variable
damage_taken = 0
# runs assuming damage taken value is greater than 0
else:
# passes onto next code block
pass
# runs assuming talent is "Healing" (only other talent affecting damage taken by wizard)
else:
# increases damage healed by 2 points per wizard level (talent effect)
damage_healed += 2 * self.wizard_level
# runs if rand_num value is tested to be 0 (wizard talent will not take effect)
else:
# wizard damage dealt and healing are unaffected; code passes onto next block
pass
# tests for wizard buff; runs if buff affects damage taken by wizard (i.e. Armour, Speed or Health)
if self.wizard_buff_specs[0] != "Damage":
# assigns randomly chosen number (0 or 1) to variable rand_num; to be used in determining buff effects
rand_num = random.randint(0, 1)
# runs if wizard buff does not affect damage taken by wizard (i.e. Damage)
else:
# wizard damage dealt and healing are unaffected; code passes onto next block
pass
# tests rand_num variable value; runs if tested value is 1 (wizard buff will take effect)
if rand_num == 1:
# tests for wizard buff; runs if buff is "Armour" or "Speed"
if (self.wizard_buff_specs[0] == "Armour") or (self.wizard_buff_specs[0] == "Speed"):
# reduces damage taken by 2 points per wizard level (buff effect)
damage_taken -= self.wizard_buff_specs[1] * self.wizard_level
# runs assuming buff is "Health" (other other buff affecting damage taken by wizard)
else:
# increases damage healed by 2 points per wizard level (buff effect)
damage_healed += self.wizard_buff_specs[1] * self.wizard_level
# tests damage value, runs if it is less than 0 (wizard cannot take negative damage)
if damage_taken < 0:
# adjusts damage taken value to 0 (wizard takes no damage)
damage_taken = 0
# runs assuming damage value is greater than 0
else:
# passes onto next code
pass
# updates the current hp of the wizard by applying the amounts of damage taken/healed
self.current_hp -= damage_taken
self.current_hp += damage_healed
# tests if current hp of the wizard is smaller than 0 (is an invalid amount of hp)
if self.current_hp < 0:
# updates current hp to 0 (absolute minimum hp value)
self.current_hp = 0
# tests if current hp of the wizard is greater than its maximum health (is an invalid amount of hp)
elif self.current_hp > self.max_hp:
# updates current hp to the wizard's maximum health (absolute maximum hp value)
self.current_hp = self.max_hp
# runs assuming current hp of the wizard is greater than or equal to 0 (is a valid amount of hp)
else:
# wizard's current health is unaffected; code passes onto next block
pass
# tests value of variable iff; runs if variable value is string "friend"
if self.iff == "friend":
# assigns string value "Your wizard, " to variable iff (for use in damage message to user)
iff = "Your wizard, "
# runs assuming the value of iff is "foe" (the only other possibility)
else:
# passes onto next code block
pass
# prints output message, displaying iff indicator, wizard name, damage taken/healed and current/max hp of wizard
print("----------------------------------------------------------------\n" + iff + self.name + " has taken " +
str(damage_taken) + " points of damage, and has been healed for " + str(damage_healed) + " health points."
+ "\nWizard HP: " + str(self.current_hp) + " / " + str(self.max_hp))
# Monster class; contains all possible methods and attributes related to the program generated enemy monsters
class Monster:
# creates global lists to store all possible monster attributes, including monster name, attacks, damage values (per
# attack); lists to be used for generating monsters with unique sets of attributes
monster_names = ["Orc", "Troll", "Bandersnatch", "Ogre", "Gremlin", "Banshee", "Revenant", "Golem", "Werewolf",
"Basilisk"]
monster_attacks = ["Brute Bite", "Crooked Claw", "Skull Smash", "Club Crunch", "Blood Burn"]
monster_damage_values = [2, 4, 6, 8, 9]
# init method; initiates instance of the Monster class; and states all of the attributes of the monster; function
# imports randomly generated monster attributes, and assigns values to corresponding self variables
def __init__(self, name, level, monster_hp, mons_attacks, damages, rewards):
# assigns imported values to the following Monster class specific variables (monster attributes): name, level,
# health points, attack names, damage values and rewards (earth, water, air and fire stones, gold and xp)
self.name = name
self.level = level
self.monster_hp = monster_hp
self.monster_max_hp = monster_hp
self.monster_attacks = mons_attacks
self.damages = damages
self.rewards = rewards
# attack method; randomly chooses a monster attack and retrieves its associated damage value, and assigns it as the
# outputted raw damage; referenced whenever a monster is attacking a wizard
def attack(self):
# random integer value chosen between 0 and 3 (possible integer values: 0, 1, 2, 3); stored in rand_num
rand_num = random.randint(0, 3)
# randomly generated integer value used as index value to retrieve monster attack and damage value
attack_name = self.monster_attacks[rand_num]
attack_damage = self.damages[rand_num]
# prints output message, displaying monster name, attack and raw damage dealt
print("----------------------------------------------------------------\nThe " + self.name +
" used the attack, " + attack_name + ", and dealt " + str(attack_damage) + " points of raw damage.")
# returns the raw attack damage dealt to the referencing variable (used to reference this method)
return attack_damage
# defend method; takes in the raw damage dealt by the wizard, applies and outputs it as the damage taken
def defend(self, raw_damage):
# raw_damage value retrieved and stored in variable damage_taken
damage_taken = raw_damage
# updates the current hp of the monster by applying the amount of damage taken
self.monster_hp -= damage_taken
# tests if current monster hp is less than 0 (is an invalid amount of hp)
if self.monster_hp < 0:
# updates current monster hp to 0 (absolute minimum hp value)
self.monster_hp = 0
# runs assuming current hp of the monster is equal to or greater than 0 (is a valid amount of hp)
else:
# monster's health is unaffected; passes onto next code block
pass
# print final output message, displaying the monster name, damage taken and remaining/max hp
print("----------------------------------------------------------------\nThe " + self.name + " has taken " +
str(damage_taken) + " points of damage.\nMonster HP: " + str(self.monster_hp) + " / " +
str(self.monster_max_hp))
# GameMainframeCode class; contains all possible methods and attributes related to running the entire game
class GameMainframeCode:
# init class method; runs at class instantiation, displays intro message and allows user to choose to play the game
def __init__(self):
# displays game header and starting game description to the console; text spread over multiple lines
print("\n===================================== World Of Wizards Game ====================================\n\n"
+ "Welcome to the game, World Of Wizards.\nIn World Of Wizards, you have the opportunity to recruit and "
+ "train wizards, level up/upgrade\nwizard attacks and buffs, while fighting monsters and other wizards.")
# referencing play quit function (player chooses to play/quit game)
self.play_quit()
# creates attribute to store 1 instance of Player class (for the game player)
self.player = ()
# creates attributes to store 6 instances of Wizard class (5 for player wizards, 1 for arena rogue wizard)
self.wizard1, self.wizard2, self.wizard3, self.wizard4, self.wizard5, self.wizard_rogue = (), (), (), (), (), ()
# creates used names attributes list to hold used names (prevents duplicate wizard name use by wizard generator)
self.used_names = []
# creates attributes list to store player's existing wizards
self.wizards = []
# creates attribute to store 1 instance of Monster class (for forest monster)
self.monster = ()
# delay of 1 second
time.sleep(1)
# references and runs player generation method (creates player inventory/stats and 2 starter wizards)
self.player_generation()
# infinite while loop
while True:
# referencing in game function (in game main menu allowing player to makes choices while playing the game)
self.in_game()
# referencing play quit function (player chooses to continue to play/quit game)
self.play_quit()
# play/quit class method; allows player to choose to either play or quit the game
def play_quit(self):
# delay of 3 seconds
time.sleep(3)
# displays user choice input prompts; takes user string inputs (play/quit), converts all letters to lowercase
quit_play = input("--------------------------------------------------------------------------------------------"
+ "----\nWould you like to (continue to) play the game, or quit?\nPlease enter your choice " +
"(play/quit), here: ").lower()
# while loop runs if user input is not "play" nor "quit" (limits valid user inputs to those two)
while (quit_play != "play") and (quit_play != "quit"):
# delay of 0.5 seconds
time.sleep(0.5)
# displays re-entry prompt to console; retakes user inputs (play/quit), converts all letters to lowercase
quit_play = input("Sorry, but that input was invalid. Please re-enter a valid choice (play/quit), here: "
).lower()
# if statement tests if user input is string "play"
if quit_play == "play":
# continues on to run the main program processing function
pass
# else statement runs; assumes user input is string "quit" (since there is no other valid option)
else:
# references and runs the quit function
self.quit_function()
# player generation function; references player and wizard functions; sets up player's stats and wizards
def player_generation(self):
# referencing player generator class method; generates new player values and stores in below variables
player_name, rank_title, earth_stones, water_stones, fire_stones, air_stones, player_level, level_progress, \
wizard_stones, gold, basic_potion, supreme_potion, master_potion, revive_potion = self.player_generator()
# generated values used to instantiate Player class; class instance stored in class attribute player
self.player = Player(player_name, rank_title, earth_stones, water_stones, fire_stones, air_stones, player_level,
level_progress, wizard_stones, gold, basic_potion, supreme_potion, master_potion,
revive_potion)
# delay of 1.5 seconds
time.sleep(1.5)
# displays player stats, including player name, rank title, level, current progress and wizard/elemental stone
# and health potion inventories
print("----------------------------------------------------------------\nHere are your player stats.\n" +
"--------------------------------\nName:", player_name, "\nRank Title:", rank_title, "\nPlayer Level:",
str(player_level), "\nLevel Progress:", str(level_progress), "/", str(player_level * 10), "\n" +
"--------------------------------\nPlayer Inventory:\nWizard Stones:", str(wizard_stones),
"\nEarth Stones:",
str(earth_stones), "\nWater Stones:", str(water_stones), "\nFire Stones:", str(fire_stones),
"\nAir Stones:",
str(air_stones), "\n\nGold:", str(gold), "\n\nBasic Health Potions:", str(basic_potion),
"\nSupreme Health Potions:", str(supreme_potion), "\nMaster Health Potions:", str(master_potion),
"\nRevival Potions:", str(revive_potion))
# variable iff assigned string value of "friend"; used by code to differentiate between friendly/enemy wizards
iff = "friend"
# referencing wizard generator class method; generates new wizard values and stores in below variables
name, cost_earth, cost_water, cost_fire, cost_air, wizard_level, wizard_level_progress, max_hp, current_hp, \
wizard_attacks, wizard_attack_types, wizard_damage_values, wizard_talent, wizard_buff, buff_amount = \
self.wizard_generator()
# generated values used to instantiate Wizard class; class instance stored in class attribute wizard1
self.wizard1 = Wizard(name, cost_earth, cost_water, cost_fire, cost_air, wizard_level, wizard_level_progress,
max_hp, current_hp, wizard_attacks, wizard_attack_types, wizard_damage_values,
wizard_talent, wizard_buff, buff_amount, iff)
# referencing wizard generator class method; generates new wizard values and stores in below variables
name, cost_earth, cost_water, cost_fire, cost_air, wizard_level, wizard_level_progress, max_hp, current_hp, \
wizard_attacks, wizard_attack_types, wizard_damage_values, wizard_talent, wizard_buff, buff_amount = \
self.wizard_generator()
# generated values used to instantiate Wizard class; class instance stored in class attribute wizard2
self.wizard2 = Wizard(name, cost_earth, cost_water, cost_fire, cost_air, wizard_level, wizard_level_progress,
max_hp, current_hp, wizard_attacks, wizard_attack_types, wizard_damage_values,
wizard_talent, wizard_buff, buff_amount, iff)
# extends class attribute list wizards with Wizard class instances wizard1 and wizard2
self.wizards.extend([self.wizard1, self.wizard2])
# delay of 2.5 seconds
time.sleep(2.5)
# print line separator and message to tell user that wizard stats will be displayed next
print("----------------------------------------------------------------\nHere are your wizards' stats.")
# for loop; iterates for number of wizards stored in global list, wizards
for wizard in self.wizards:
# delay of 5 seconds
time.sleep(5)
# displays wizard stats: name, earth/water/fire/air value, level, progress, current/max hp, talent and buff
print("----------------------------------------\nName: " + wizard.name + "\nWizard Value:\n" +
str(wizard.cost[0]) + " Earth Stones\n" + str(wizard.cost[1]) + " Water Stones\n" +
str(wizard.cost[2]) + " Fire Stones\n" + str(wizard.cost[3]) + " Air Stones" +
"\n------------------------\nWizard Level: " + str(wizard.wizard_level) + "\nLevel Progress: " +
str(wizard.wizard_level_progress) + " / " + str(wizard_level * 5) + "\n------------------------" +
"\nCurrent/Max Health Points: " + str(wizard.current_hp) + " / " + str(wizard.max_hp) +
"\n------------------------\nWizard Talent: " + wizard.wizard_talent + "\nWizard Buff: " +
wizard.wizard_buff_specs[0] + "\nWizard Buff Amount: " + str(wizard.wizard_buff_specs[1]) +
"\n------------------------\nWizard Attacks: (name/type/damage)")
# for loop; iterates for number of wizard attacks stored in selected wizards attacks attribute
for counter in range(0, len(wizard.attacks)):
# displays attack number, name, type and current damage value
print(str(counter + 1) + ". " + wizard.attacks[counter] + " / " + wizard.attack_types[counter] + " / " +
str(wizard.damages[counter]))
# player generator function; takes import values (player name and rank titles) and generates the starting attributes
# of the starting instance of the Player class
def player_generator(self):
# displays prompt message to get player inputted game player name; stores inputted name to variable name
name = input("------------------------------------------------------------------------------------------------"
+ "\nI am pleased that you could join us today. Please enter in your player name, here: ")
# level assigned starting value of 1; level progress assigned starting value of 0
lvl, lvl_progress = 1, 0
# very first rank title in list rank titles is assigned to variable rank
rank = Player.player_rank_titles[0]
# starting inventory of earth, water, fire and air stones are all assigned a value of 0
wizard_stones, earth_stones, water_stones, fire_stones, air_stones = 0, 0, 0, 0, 0
# starting amount of gold is assigned a starting value of 500
gold = 500
# starting inventory of basic, supreme, master and revival health potions are all assigned a value of 2
basic_potions, supreme_potions, master_potions, revive_potions = 2, 2, 2, 2
# returns the following values to the variable referencing this function (the player object); player name, rank
# title, earth/water/fire/air stones inventory, level and level progress, wizard stones inventory, starting gold
# amount and health potions inventory (basic, supreme, master and revival potions)
return name, rank, earth_stones, water_stones, fire_stones, air_stones, lvl, lvl_progress, wizard_stones, \
gold, basic_potions, supreme_potions, master_potions, revive_potions
# wizard generator function; takes imported lists of values (wizard names, attacks, attack types, damage values,
# talents and buffs) and randomly generates some variable/unique attributes for each Wizard class instance
def wizard_generator(self):
# randomly chooses integer value between 0 and 7 (possible integer values: 0, 1, 2, 3, 4, 5, 6, 7); assigned to
# variable wiz_rand_num; random integer then used as index value to retrieve wizard name from names list
wiz_rand_num = random.randint(0, 7)
wiz_name = Wizard.wiz_names[wiz_rand_num]
# while loop; iterates while current retrieved wizard name has already been used (is in used_names list)
while wiz_name in self.used_names:
# randomly chooses integer between 0 and 7, uses as index value to retrieve wizard name from names list
wiz_rand_num = random.randint(0, 7)
wiz_name = Wizard.wiz_names[wiz_rand_num]
# appends current wiz_name to the attribute list used_names
self.used_names.append(wiz_name)
# wizard level assigned to value 1; level progress assigned to value 0; wizard max_hp set to base of 50 (plus 25
# additional health points per wizard level past level 1); max_hp value also assigned to wizard's current hp
wiz_level, wiz_level_prog = 1, 0
wiz_max_hp = 50 + (wiz_level - 1) * 25
wiz_current_hp = wiz_max_hp
# randomly chooses an integer value between 0 and 3 (possible integer values: 0, 1, 2, 3); assigned to variable
# wiz_rand_num; random integer then used as an index value to retrieve wizard talent and buff
wiz_rand_num = random.randint(0, 3)
wiz_talent = Wizard.wiz_talents[wiz_rand_num]
wiz_buff = Wizard.wiz_buffs[wiz_rand_num]
# wizard buff effect amount is set by multiplying wizard_level by 2; value assigned to variable wiz_buff_amount
wiz_buff_amount = wiz_level * 2
# lists created wiz_attacks_num to store index values (to retrieve wizard attacks); # wiz_attacks_names to store
# attacks; wiz_attack_types to store attack types; wiz_damage_values to store attack damage values
wiz_attacks_num, wiz_attack_names, wiz_attack_types, wiz_damage_values = [], [], [], []
# creates variables to store wizard elemental stones worth/value, in terms of earth, water, fire and air stones
earth_price, water_price, fire_price, air_price = int(), int(), int(), int()
# while loop; iterates while there are less than 4 attacks stored in the index values list wiz_attacks_num
while len(wiz_attacks_num) < 4:
# randomly chooses integer value between 1 and 15 (possible integer values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
# 10, 11, 12, 13, 14, 15); value stored in attack_num; stored in wiz_attacks_num list if not already in list
attack_num = random.randint(0, 15)
# tests if attack_num value already exists in the list wiz_attacks_num; runs if it already does
if attack_num in wiz_attacks_num:
# passes onto next code; duplicate numbers not entered into the list (unique digits only entered once)
pass
# runs assuming attack_num value does not already exist in the list wiz_attacks_num
else:
# appends integer value in variable attack_num to the list wiz_attacks_num; to be used as index numbers
wiz_attacks_num.append(attack_num)
# for loop; iterates for quantity of integer index values stored in the list wiz_attacks_num
for num in wiz_attacks_num:
# num variable value used as index value to retrieve an attack, its associated type and damage value; the
# retrieved values appended to the following lists: wiz_attack_names. wiz_attack_types, wiz_damage_values
wiz_attack_names.append(Wizard.wiz_attacks[num])
wiz_attack_types.append(Wizard.wiz_atk_types[num])
# wizard damage values increased based upon wizard level
wiz_damage_values.append(Wizard.wiz_damages[num] + (wiz_level - 1))
# for loop; iterates per attack type stored in the list wiz_attack_types
for a_type in wiz_attack_types:
# tests attack type; runs if type is "Earth"
if a_type == "Earth":
# increases earth stones value of wizard by 5 stones
earth_price += 5
# tests attack type; runs if type is "Water"
elif a_type == "Water":
# increases water stones value of wizard by 5 stones
water_price += 5
# tests attack type; runs if type is "Fire"
elif a_type == "Fire":
# increases fire stones value of wizard by 5 stones
fire_price += 5
# runs assuming that attack type is "Air" (the only other attack type not yet tested)
else:
# increases air stones value of wizard by 5 stones
air_price += 5
# returns following values to variable referencing method; wizard name, earth/water/fire/air stones values,
# level, level progress, max/current hp, attack names, types and damage values, talent, buff and buff amount
return wiz_name, earth_price, water_price, fire_price, air_price, wiz_level, wiz_level_prog, wiz_max_hp, \
wiz_current_hp, wiz_attack_names, wiz_attack_types, wiz_damage_values, wiz_talent, wiz_buff, wiz_buff_amount
# monster generator function; takes monster names and player level, randomly generates variable/unique attributes
# for the Monster class instance
def monster_generator(self):
# randomly chooses integer value between 0 and 9 (possible integer values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); stored
# in variable mons_rand_num; to be index number to retrieve monster name, to be stored in mons_name
mons_rand_num = random.randint(0, 9)
mons_name = Monster.monster_names[mons_rand_num]
# tests player's level; runs if player's level is equal to or smaller than 2
if self.player.player_level <= 2:
# randomly chooses value between 1 and 2 higher than the player's level; assigns value as monster level
mons_level = random.randint(1, self.player.player_level + 2)
# runs assuming player level is greater than 2
else:
# randomly chooses value between 2 higher/lower than the player's level; assigns value as monster level
mons_level = random.randint(self.player_level - 2, self.player.player_level + 2)
# generates monster hp by multiplying monster level by 20; assigns end value to variable mons_hp
mons_hp = mons_level * 20
# randomly generates the possible quantities of rewards that come from successfully slaying this monster; reward
# stones start at 1 and gold starts at 10, increased by chance; reward xp is equal to monster level * 5
earth_stone = 1 + random.randint(0, 2)
water_stone = 1 + random.randint(0, 2)
fire_stone = 1 + random.randint(0, 2)
air_stone = 1 + random.randint(0, 2)
gold_pieces = 1 + random.randint(0, 2)
xp = mons_level * 5
# randomly generated reward quantities then stored in list mons_rewards; all multiplied by monster level
mons_rewards = [earth_stone * mons_level, water_stone * mons_level, fire_stone * mons_level,
air_stone * mons_level,
gold_pieces * 10 * mons_level, xp]
# returns the following values to the variable referencing this function; monster name, level, hp and rewards
return mons_name, mons_level, mons_hp, mons_rewards
# in_game function; controls all in game functions (fight in forest/fight in arena, review inventory or shop)
def in_game(self):
# creates list player_choices; stores all possible player options (forest, arena, review or shop)
player_choices = ["forest", "arena", "review", "shop"]
# delay of 1.5 seconds
time.sleep(1.5)
# displays line separator and starting message to player, informing him/her of all possible in game options
print("------------------------------------------------------------------------------------------------\n" +
"Welcome to World Of Wizards. You may go and fight monsters in the forest, fight other wizards\nin the " +
"arena, review your wizards/inventory, or visit the Druid Shop.")
# displays prompt message, intakes player choice of in game options, converts all input letters to lowercase
player_choice = input("----------------------------------------\nPlease input your choice, (forest/arena/" +
"review/shop) here: ").lower()
# while loop; iterates while player's input choice not in list player_choices (thus not a valid choice)
while player_choice not in player_choices:
# displays prompt error message, retakes player's choice of in game options, converts input to lowercase
player_choice = input("Sorry, but that was an invalid input. Please re-input your choice, (forest/arena/" +
"review/shop) here: ").lower()
# tests player choice; runs if player choice is "forest"
if player_choice == "forest":
# references and runs the fight_forest() function
self.fight_forest()
# tests player choice; runs if player choice is "arena"
elif player_choice == "arena":
# references and runs the fight_arena() function
self.fight_arena()
# tests player choice; runs if player choice is "review"
elif player_choice == "review":
# references and runs the review_wiz_inv() function
self.review_wiz_inv()
# runs assuming player choice is "shop" (the only other valid option)
else:
# references and runs the druid_shop() function
self.druid_shop()
# fight_forest function; allows the player to have his/her wizards fight monsters in the forest
def fight_forest(self):
# referencing monster_generator class method; randomly generates monster name, level, hp and reward values
monster_name, monster_level, monster_hp, monster_rewards = self.monster_generator()
# generated values user to instantiate Monster class; class instance stored in the class attribute monster
self.monster = Monster(monster_name, monster_level, monster_hp, Monster.monster_attacks,
Monster.monster_damage_values, monster_rewards)
# creates player choices list to store player options (fight or flee)
player_choices = ["fight", "flee"]
# displays message to player indicating that band of wizards has encountered a specific monster (level included)
print("------------------------------------------------------------------------------------------------\n" +
"You and your band of wizards wander into the forest... and come upon... a level " +
str(self.monster.level), self.monster.name + "!")
# displays prompt message, takes player choice (either fight or flee); converts all input letters to lowercase
player_choice = input("----------------------------------------\nYou can choose to either fight the monster, " +
"or flee to return to fight another day.\nEnter your choice (fight/flee), here: ").lower()
# while loop; iterates while player choice is not in the list player choices (is not "fight" or "flee")
while player_choice not in player_choices:
# displays prompt message, retakes player choice (fight or flee); converts all input letters to lowercase
player_choice = input("Sorry, but that choice was invalid. Please re-enter a valid input (fight/flee), " +
"here: ").lower()
# tests player choice; runs if player choice is "fight"
if player_choice == "fight":
# displays line separator and short message informing the player that his/her wizards will be displayed
print("----------------------------------------------------------------\nHere are your band's wizards:")
# for loop; iterates for number of wizards stored in list wizards
for wiz in range(0, len(self.wizards)):
# displays the wizard's band number and name
print(str(wiz + 1) + ". " + str(self.wizards[wiz].name))
# creates variable wiz_options, for use in player wizard choice prompt message (see below)
wiz_options = "(1/2)"
# creates list user_choices, for use in player wizard choice algorithm (see below)
player_choices = [1, 2]
# tests length of wizards list (# of wizards); runs if length is 2
if len(self.wizards) == 2:
# passes onto next code block (number of wizards and options remain unchanged)
pass
# tests length of wizards list (# of wizards); runs if length is 3
elif len(self.wizards) == 3:
# assigns string value with numbers 1, 2 and 3; to indicate to player possible player wizard choices
wiz_options = "(1/2/3)"
# appends integer value 3 to list player_choices (adds 3 as possible wizard choice)
player_choices.append(3)
# tests length of wizards list (# of wizards); runs if length is 4
elif len(self.wizards) == 4:
# assigns string value with numbers 1, 2, 3 and 4; to indicate to player possible player wizard choices
wiz_options = "(1/2/3/4)"
# extends list player_choices with integer values 3 and 4 (adds 3, 4 as possible wizard choices)
player_choices.extend([3, 4])
# runs assuming length of wizards list (# of wizards) is 5
else:
# assigns string value with numbers 1, 2, 3, 4, 5; to indicate to player possible player wizard choices
wiz_options = "(1/2/3/4/5)"
# extends list player_choices with integer values 3, 4, 5 (adds 3, 4, 5 as possible wizard choices)
player_choices.extend([3, 4, 5])
# while loop; iterates infinitely (until code breaks out of loop)
while True:
# try logic structure; attempts to complete program functions
try:
# displays prompt message with possible options, takes player choice of wizard (wizard band number)
player_choice = int(input("----------------------------------------------------------------\nWhich "
+ "one of your wizards would you like to fight the " + self.monster.name +
"?\nPlease indicate your choice " + wiz_options + ", here: "))
# tests player choice; runs if player choice (integer value) is not a possible wizard option
if player_choice not in player_choices:
# tests player choice, runs if it is greater than 5 or less than 0 (outside valid range of 1-5)
if (player_choice > 5) or (player_choice < 0):
# displays specific prompt error message to player that selection is outside valid range
print("Sorry, but that wizard band slot was outside the allotted range of 1-5 band slots.")
# runs assuming player choice is within the valid range of 1-5
else:
# displays specific error prompt message to player that band slot empty (no stored wizard)
print("Sorry, but that wizard band slot is empty; no wizard currently stored there.")
# runs assuming player has inputted integer value that is a possible wizard option
else:
# breaks out of infinite while loop
break
# except logic structure; runs if value error raised (i.e. player inputs non-integer characters)
except ValueError:
# displays specific error prompt message to player that specific wizard does not exist
print("Sorry, but that was an invalid choice; that wizard does not exist in your current band.")
# reduces player choice value by 1; end value to be used as index value to select the corresponding wizard
player_choice -= 1
# displays message to player indicating the name of the wizard who was chosen and accepted the call to fight
print("Your wizard, " + self.wizards[player_choice].name + ", has accepted the call to fight the level " +
str(self.monster.level) + " " + self.monster.name + ".")
# while loop; iterates while both selected wizard's and monster's remaining health are greater than 0
while (self.wizards[player_choice].current_hp > 0) and (self.monster.monster_hp > 0):
# delay for 2 seconds
time.sleep(2)
# runs attack() method for Wizard class instance (fighting wizard); damage stored in wiz_damage
wiz_damage = self.wizards[player_choice].attack()
# runs defend() method for Monster class instance (defending monster); intakes damage from wiz_damage
self.monster.defend(wiz_damage)
# tests monster's current health; runs if it is equal to 0
if self.monster.monster_hp == 0:
# breaks out of the while loop immediately
break
# runs assuming monster's current health is not equal to 0 (is greater than 0)
else:
# passes onto next code block
pass
# delay of 2 seconds
time.sleep(2)
# runs attack() method for Monster class instance (fighting monster); damage stored in mons_damage
mons_damage = self.monster.attack()
# runs defend() method for Wizard class instance (defending wizard); intakes damage from mons_damage
self.wizards[player_choice].defend(mons_damage)
# tests selected wizard's remaining health; runs if it is 0 (wizard has been defeated)
if self.wizards[player_choice].current_hp == 0:
# prints message to player, indicating that chosen wizard has been defeated by monster
print("----------------------------------------------------------------\nYour wizard, " +
self.wizards[player_choice].name + ", has been defeated by the " + self.monster.name + "!" +
"\nYour band has been defeated, and you retreat back to fight again another day.")
# runs assuming monster's remaining health is 0 (monster defeated; wizard's remaining health greater than 0)
else:
# prints message to player, indicating that chosen wizard has defeated the monster
print("----------------------------------------------------------------\nYour wizard, " +
self.wizards[player_choice].name + ", has defeated the " + self.monster.name + "!" +
"\nYour band is victorious, and you leave the forest, bound to return to fight again.")
# takes monster reward values (# of stones, gold and xp), stores in temporary reward storage variables
reward_earth_stones, reward_water_stones = self.monster.rewards[0], self.monster.rewards[1]
reward_fire_stones, reward_air_stones = self.monster.rewards[2], self.monster.rewards[3]
reward_gold, reward_xp = self.monster.rewards[4], self.monster.rewards[5]
# prints message to player, listing all rewards received from successfully defeating monster
print("----------------------------------------------------------------\nYou have received the " +
"following rewards:\nEarth Stones: " + str(reward_earth_stones) + "\nWater Stones: " +
str(reward_water_stones) + "\nFire Stones: " + str(reward_fire_stones) + "\nAir Stones: " +
str(reward_air_stones) + "\nGold: " + str(reward_gold) + "\nXP: " + str(reward_xp))
# takes values stored in temporary reward variables; adds to player's inventory/level (stones, gold, xp)
self.player.stones_inv[0] += reward_earth_stones
self.player.stones_inv[1] += reward_water_stones
self.player.stones_inv[2] += reward_fire_stones
self.player.stones_inv[3] += reward_air_stones
self.player.gold += reward_gold
self.player.level_progress += reward_xp
# tests player level progress; runs if meets/exceeds current level threshold (current player level * 10)
if self.player.level_progress >= self.player.player_level * 10:
# player level progress reduced by value of current level threshold (xp reset for next level)
self.player.level_progress -= self.player.player_level * 10
# player level is increased by 1 (player levels up)
self.player.player_level += 1
# player rank title is updated to the title associated with the player's new level
self.player.rank_title = Player.player_rank_titles[self.player.player_level - 1]
# prints message to player, indicating that he/she has leveled up, and new rank title received
print("----------------------------------------\nYou have leveled up! You are now level " +
str(self.player.player_level) + ", and have received the rank title, " +
self.player.rank_title + ". Congratulations!")
# runs assuming that player level progress does not meet/exceed level threshold
else:
# passes onto next code block
pass
# print message to user, indicating the amount of xp that the selected wizard has received
print("----------------------------------------------------------------\nYour wizard, " +
self.wizards[player_choice].name + ", has received " + str(reward_xp) + " XP points.")
# adds amount of received xp to wizard's current xp (level progress)
self.wizards[player_choice].wizard_level_progress += reward_xp
# tests selected wizard's level progress; runs if meets/exceeds current level threshold (wiz level * 5)
if self.wizards[player_choice].wizard_level_progress >= self.wizards[player_choice].wizard_level * 5:
# wizard level progress is reduced by value of current level threshold (xp reset for next level)
self.wizards[player_choice].wizard_level_progress -= self.wizards[player_choice].wizard_level * 5
# wizard level is increased by 1 (wizard levels up)
self.wizards[player_choice].wizard_level += 1
# prints message to player, indicating that selected wizard has leveled up (message with level #)
print("----------------------------------------\nYour wizard, " + self.wizards[player_choice].name +
", has leveled up, and is now level " + str(self.wizards[player_choice].wizard_level) +
".\nYour wizard's max hp and attack damages have been increased, and your wizard has been " +
"fully healed. Congratulations!")
# selected wizard's max hp is increased by 25 health points
self.wizards[player_choice].max_hp += 25
# selected wizard's current hp is increased to the wizard's new max hp
self.wizards[player_choice].current_hp = self.wizards[player_choice].max_hp
# all of the selected wizard's attacks damage values are increased by 1 additional damage point each
self.wizards[player_choice].damages = [self.wizards[player_choice].damages[0] + 1,
self.wizards[player_choice].damages[1] + 1,
self.wizards[player_choice].damages[2] + 1,
self.wizards[player_choice].damages[3] + 1]
# selected wizard's buff amount (2nd value in buff specs list) is increased by 2 additional points
self.wizards[player_choice].wizard_buff_specs[1] += 2
# runs assuming wizard's level progress does not meet/exceed level threshold
else:
# passes onto next code block
pass
# runs assuming player choice is "flee" (the only other possible option)
else:
# prints message to player, indicating that the band of wizards (lead by player) has fled from the monster
print("You and your band have fled from the " + self.monster.name + ". You and your band plan to return " +
"again.")
# fight arena function; allows the player to have his/her wizards fight other wizards in the arena
def fight_arena(self):
# player choices list storing possible player options (fight or forfeit)
player_choices = ["fight", "forfeit"]
# referencing wizard generator class method; generates new wizard values and stores in below variables
name, cost_earth, cost_water, cost_fire, cost_air, wizard_level, wizard_level_progress, max_hp, current_hp, \
wizard_attacks, wizard_attack_types, wizard_damage_values, wizard_talent, wizard_buff, buff_amount = \
self.wizard_generator()
# tests player's level; runs if it is smaller than 3
if self.player.player_level < 3:
# passes onto next code block
pass
# runs assuming player's level is greater than 3
else:
# randomly selects integer value between -2 and 2 (possible values: -2, -1, 0, 1, 2); assigns to rand_num
rand_num = random.randint(-2, 2)
# adjusts wizard level (increase/decrease) using the integer value stored in rand_num
wizard_level += rand_num
# sets damage increase value to one less than wizard level
dmg_inc = wizard_level - 1
# adjusts wizard attack damage values (increase/decrease) using damage increase value in variable dmg_inc
wizard_damage_values = [wizard_damage_values[0] + dmg_inc, wizard_damage_values[1] + dmg_inc,
wizard_damage_values[2] + dmg_inc, wizard_damage_values[3] + dmg_inc]
# assigns string value "foe" to variable iff (for use by program to indicate friendly/enemy wizards)
iff = "foe"
# generated values used to instantiate Wizard class; class instance stored in class attribute wizard_rogue
self.wizard_rogue = Wizard(name, cost_earth, cost_water, cost_fire, cost_air, wizard_level,
wizard_level_progress, max_hp, current_hp, wizard_attacks, wizard_attack_types,
wizard_damage_values, wizard_talent, wizard_buff, buff_amount, iff)
# displays arena intro message to player, indicating to the player the level and name of the opponent wizard
print("------------------------------------------------------------------------------------------------\n" +
"You and you band of wizards enter the arena and sign up in the tournament.\nFor your battle, you will " +
"be facing off against a level " + str(self.wizard_rogue.wizard_level) + " wizard by the name of " +
self.wizard_rogue.name + ".")
# displays message to player, intakes player choice (fight/forfeit); converts all input letters to lowercase
player_choice = input("----------------------------------------\nYou can choose to either fight the wizard, or "
+ "forfeit the battle and return to fight another day.\nWhat do you do? Enter your " +
"choice (fight/forfeit), here: ").lower()
# while loop; iterates while the player's input choice not in the list player choices (is not fight or forfeit)
while player_choice not in player_choices:
# displays error prompt message to player, retakes player choice (fight or flee), converts all to lowercase
player_choice = input("Sorry, but that was an invalid choice. Please re-enter a valid input (fight/forfeit)"
+ ", here: ").lower()
# tests player choice; runs if it is "fight"
if player_choice == "fight":
# displays message to player, indicating to him/her that all band wizards will be displayed shortly
print("\nHere is a list of all wizards in your tournament band. ")
# for loop; iterates for to number of wizards currently in the band
for counter in range(1, len(self.wizards) + 1):
# displays wizard band number and name to player (counter less 1 used as index value to get names)
print(str(counter) + ". " + self.wizards[counter - 1].name)
# infinite while loop
while True:
# try structure attempts to take and process player input
try:
# displays prompt message to player, takes the integer band number value of player's selected wizard
player_choice = int(input("Please enter the band number of the wizard you would like to have fight "
+ "in the arena, here: "))
# reduces player input by 1 (is to be used as index value to retrieve the appropriate wizard)
player_choice -= 1
# tests player choice; runs if player choice integer value is between 0 and length of wizards list
if 0 <= player_choice < len(self.wizards):
# breaks out of infinite while loop
break
# runs assuming player choice integer value outside of valid integer range (> 0 or < wizards length)
else:
# displays error message to player, and redirects player back to re-enter his/her wizard choice
print("Sorry, but that was an invalid wizard band number. Please choose another wizard.")
# except structure runs if value error raised (i.e. player enters non-integer characters/float values)
except ValueError:
# displays error message to player, and redirects player back to re-enter his/her wizard choice
print("Sorry, but that input was invalid. Please re-enter a valid integer to choose a wizard.")
# displays message to player, indicating that selected wizard has accepted call to fight opposing wizard
print("Your wizard, " + self.wizards[player_choice].name + ", has accepted the call to fight the wizard, " +
self.wizard_rogue.name + ".")
# while loop; iterates while both friendly and opposing wizard's hp are greater than 0 (are able to fight)
while (self.wizards[player_choice].current_hp > 0) and (self.wizard_rogue.current_hp > 0):
# delay of 2 seconds
time.sleep(2)
# runs attack() method for Wizard class instance (friendly wizard); damage stored in variable wiz_damage
wiz_damage = self.wizards[player_choice].attack()
# runs defend() method for Wizard class instance (enemy wizard); intakes damage stored in wiz_damage
self.wizard_rogue.defend(wiz_damage)
# tests enemy wizard's current health; runs if it is equal to 0
if self.wizard_rogue.current_hp == 0:
# breaks out of while loop immediately
break
# runs assuming enemy wizard's health is not equal to 0 (is gretaer than 0)
else:
# passes onto next code block
pass
# delay of 2 seconds
time.sleep(2)
# runs attack() method for Wizard class instance (enemy wizard); damage stored in variable wiz_damage
wiz_damage = self.wizard_rogue.attack()
# runs defend() method for Wizard class instance (friendly wizard); intakes damage stored in wiz_damage
self.wizards[player_choice].defend(wiz_damage)
# tests player selected wizard's current health; runs if current health is 0 (friendly wizard defeated)
if self.wizards[player_choice].current_hp == 0:
# displays message to player indicating that his/her wizard has been defeated by the enemy wizard
print("----------------------------------------------------------------\nYour wizard, " +
self.wizards[player_choice].name + ", has been defeated by the wizard, " + self.wizard_rogue.name
+ "!\nYour band has been defeated, and you retreat back to fight again another day.")
# runs assuming enemy wizard's current health is 0 (only other possible reason previous loop is ended)
else:
# displays message to player indicating that his/her wizard has defeated the enemy wizard
print("----------------------------------------------------------------\nYour wizard, " +
self.wizards[player_choice].name + ", has defeated the wizard, " + self.wizard_rogue.name + "!" +
"\nYour band is victorious, and you leave the arena, bound to return to fight again.")
# retrieves the rewards of defeating the enemy wizard and storing them in temporarily reward variables;
# rewards retrieved include wizard, earth, fire, water and air stones, gold and xp
reward_wizard_stones = self.wizard_rogue.wizard_level
reward_earth_stones = self.wizard_rogue.cost[0] + random.randint(0, 1) * self.wizard_rogue.wizard_level
reward_water_stones = self.wizard_rogue.cost[1] + random.randint(0, 1) * self.wizard_rogue.wizard_level
reward_fire_stones = self.wizard_rogue.cost[2] + (random.randint(0, 1) * self.wizard_rogue.wizard_level)
reward_air_stones = self.wizard_rogue.cost[3] + (random.randint(0, 1) * self.wizard_rogue.wizard_level)
reward_gold = (self.wizard_rogue.wizard_level + random.randint(0, 1)) * 10
reward_xp = (self.wizard_rogue.wizard_level + random.randint(0, 1)) * 5
# displays message to player, showing aforementioned rewards he/she has received for winning the fight
print("----------------------------------------------------------------\nYou have received the " +
"following rewards:\nWizard Stones: " + str(reward_wizard_stones) + "\nEarth Stones: " +
str(reward_earth_stones) + "\nWater Stones: " + str(reward_water_stones) + "\nFire Stones: " +
str(reward_fire_stones) + "\nAir Stones: " + str(reward_air_stones) + "\nGold: " +
str(reward_gold) + "\nXP: " + str(reward_xp))
# adds the aforementioned rewards to the variables containing the active player's inventory
self.player.wizard_stones += reward_wizard_stones
self.player.stones_inv[0] += reward_earth_stones
self.player.stones_inv[1] += reward_water_stones
self.player.stones_inv[2] += reward_fire_stones
self.player.stones_inv[3] += reward_air_stones
self.player.gold += reward_gold
self.player.level_progress += reward_xp
# tests player's current level progress; runs if it meets/exceeds the current level threshold
if self.player.level_progress >= self.player.player_level * 10:
# player's current level progress is reduced by a value equal to the current level threshold (reset)
self.player.level_progress -= self.player.player_level * 10
# player's level is increased by 1 (player has leveled up)
self.player.player_level += 1
# retrieves and assigns new player rank title to rank_title (player level used as index value)
self.player.rank_title = Player.player_rank_titles[self.player.player_level - 1]
# displays message to player, indicating that he/she has leveled up; shows his/her new rank title
print("----------------------------------------\nYou have leveled up! You are now level " +
str(self.player.player_level) + ", and have received the rank title, " +
self.player.rank_title + ". Congratulations!")
# runs assuming that player's current level progress does not meet/exceed the current level threshold
else:
# passes onto next code block
pass
# displays message to player, indicating amount of xp points that the selected wizard has received
print("----------------------------------------------------------------\nYour wizard, " +
self.wizards[player_choice].name + ", has received " + str(reward_xp) + " XP points.")
# adds the received xp points to the selected wizard's current xp level progress
self.wizards[player_choice].wizard_level_progress += reward_xp
# tests wizard's level progress; runs if progress meets/exceeds the current level progress threshold
if self.wizards[player_choice].wizard_level_progress >= self.wizards[player_choice].wizard_level * 5:
# reduces level progress by current progress threshold value (resets level progress for next level)
self.wizards[player_choice].wizard_level_progress -= self.wizards[player_choice].wizard_level * 5
# adds one level to selected wizard (wizard has leveled up)
self.wizards[player_choice].wizard_level += 1
# displays message to player, indicating that wizard has leveled up (fully healed, improved stats)
print("----------------------------------------\nYour wizard, " + self.wizards[player_choice].name +
", has leveled up, and is now level " + str(self.wizards[player_choice].wizard_level) +
". Congratulations! Your wizard has also been fully healed, and received stat improvements!")
# selected wizard's max hp is increased by 25 health points (stat improvement)
self.wizards[player_choice].max_hp += 25
# selected wizard's current hp is reset to new max health points (full heal)
self.wizards[player_choice].current_hp = self.wizards[player_choice].max_hp
# selected wizard's attack damages increased by 1 damage point per attack (stat improvements)
self.wizards[player_choice].damages = [self.wizards[player_choice].damages[0] + 1,
self.wizards[player_choice].damages[1] + 1,
self.wizards[player_choice].damages[2] + 1,
self.wizards[player_choice].damages[3] + 1]
# selected wizard's buff amount increased by 2 buff points (stat improvement)
self.wizards[player_choice].wizard_buff_specs[1] += 2
# runs assuming wizard's level progress does not meet/exceed teh current level progress threshold
else:
# passes onto next code block
pass
# runs assuming player choice is "forfeit" (the only other option)
else:
# displays message to user, indicating that the arena battle has been forfeited
print("You and your band have forfeited the tournament challenge. You and your band plan to return again.")
# review wiz inv function; allows player to review his/her wizards or current inventory, or return to the main menu
def review_wiz_inv(self):
# player choices list storing possible player options (wizs, inv or exit)
player_choices = ["wizs", "inv", "exit"]
# delay of 1.5 seconds
time.sleep(1.5)
# displays review intro to player; displays all review options, converts all player input letters to lowercase
player_choice = input("----------------------------------------------------------------------------------------"
+ "--------\nWelcome to your wizards/inventory review.\nYou can choose to either review "
+ "your wizards individual stats (wizs), review your player inventory (inv), or exit the "
+ "review (exit).\n----------------------------------------\nPlease input your choice " +
"(wizs/inv/exit), here: ").lower()
# while loop; iterates while player choice input is not in list player choices (thus is an invalid choice)
while player_choice not in player_choices:
# displays error message to player, retakes player choice input and converts all letters to lowercase
player_choice = input("Sorry, but that was an invalid choice. Please re-enter a valid choice (wizs/inv/" +
"exit), here: ").lower()
# tests player choice; runs if it is "wizs"
if player_choice == "wizs":
# delay of 1.5 seconds
time.sleep(1.5)
# displays welcome message to player for wizards review function; indicates reviewable wizard stats
print("----------------------------------------------------------------\nWelcome to your wizards review. " +
"Here, you can review your wizards stats, inclusive of name, attacks, elemental value, xp, levels " +
"and buffs.")
# for loop; iterates for number of wizards stored in wizards list
for counter in range(0, len(self.wizards)):
# displays wizard's band number and name to the player in a list form
print(str(counter + 1) + ". " + self.wizards[counter].name)
# creates empty list to be stored in variable wizs_to_dis (to used to hold the wizards to be displayed)
wizs_to_dis = []
# creates empty list to be stored in variable wiz_nums (to be used to store selected wizard band numbers)
wiz_nums = []
# creates tuple with valid integers player can enter (1, 2, 3, 4 and/or 5); stored in variable valid_ints
valid_ints = ("1", "2", "3", "4", "5")
# displays prompt message to player with possible valid inputs; takes player input and converts to lowercase
player_choice = input("----------------------------------------\nPlease indicate the wizards that you " +
"would like to see the stats for (type in the numbers from the names list above with "
+ "spaces in between numbers), or type \"all\", if you would like to see the stats " +
"of all of your wizards.\n----------------------------------------\nPlease indicate "
+ "your choice (1/2/3/4/5/all), here: ").lower()
# tests player choice; runs if player input is string "all" or string input contains the word "all" in it
if (player_choice == "all") or ("all" in player_choice):
# for loop; iterates for number of wizards stored in wizards list
for counter in range(0, len(self.wizards)):
# appends each wizard in player's wizard band to the list wizs_to_dis (counter used as index value)
wizs_to_dis.append(self.wizards[counter])
# appends each wizard's band number to the list wiz_nums (index value (counter) plus 1)
wiz_nums.append(counter + 1)
# runs assuming player input is not string "all" or string input does not contain the word "all" in it
else:
# for loop; iterates for number of characters in the player's input string
for char in player_choice:
# tests character in player's input string; runs if it is a valid integer (in valid_ints list)
if char in valid_ints:
# tests character's integer value; runs if it is greater than length of wizards list
if (int(char) > len(self.wizards)) and (int(char) <= 5):
# displays error message to player, indicating that the selected wizard does not exist
print("Sorry, but that wizard band slot is empty; no wizard is in slot #" + char + ".")
# tests character's integer value; runs if it is greater than 5 (thus invalid)
elif (int(char) > 5) or (int(char) < 1):
# displays error message to player, indicating inputted number outside possible slot range
print("Sorry, but that wizard slot number " + char + ", is outside of the possible slots " +
"range minimum of wizard slot #1, maximum of wizard slot #5).")
# runs assuming character's integer value is between 1 and 5 inclusive (thus is valid)
else:
# appends the wizard with the associated band slot number to the list wizs_to_dis
wizs_to_dis.append(self.wizards[int(char) - 1])
# appends the wizard's band slot number to the list wiz_nums
wiz_nums.append(int(char))
# runs assuming character in player's input string not valid integer value (not in valid_ints list)
else:
# passes onto next character in player's input string (onto next code once last letter tested)
pass
# for loop; iterates for number of number of wizard numbers in list wiz_nums
for num in wiz_nums:
# delay of 2 seconds
time.sleep(2)
# wizard number less 1 used as index value to retrieve Wizard class instance from wizards list
wizard = self.wizards[num - 1]
# displays the retrieved wizard's slot #, name, wizard value (earth, water, fire and air stones), level,
# level progress, current/max hp, talent, buff, buff amount and wizard attacks names, types and damages
print("----------------------------------------\nBand Slot #" + str(num) + ":\nName: " + wizard.name +
"\nWizard Value:\n" + str(wizard.cost[0]) + " Earth Stones\n" + str(wizard.cost[1]) +
" Water Stones\n" + str(wizard.cost[2]) + " Fire Stones\n" + str(wizard.cost[3]) + " Air Stones" +
"\n------------------------\nWizard Level: " + str(wizard.wizard_level) + "\nLevel Progress: " +
str(wizard.wizard_level_progress) + " / " + str(
wizard.wizard_level * 5) + "\n----------------------"
+ "--" + "\nCurrent/Max Health Points: " + str(wizard.current_hp) + " / " + str(wizard.max_hp) +
"\n------------------------\nWizard Talent: " + wizard.wizard_talent + "\nWizard Buff: " +
wizard.wizard_buff_specs[0] + "\nWizard Buff Amount: " + str(wizard.wizard_buff_specs[1]) +
"\n------------------------\nWizard Attacks: (name/type/damage)")
# each of retrieved wizard's attacks' specs (name/type/damages) displayed in list format using for loop
for counter in range(0, len(wizard.attacks)):
print(str(counter + 1) + ". " + wizard.attacks[counter] + " / " + wizard.attack_types[
counter] + " / " +
str(wizard.damages[counter]))
# tests player choice; runs if it is "inv"
elif player_choice == "inv":
# delay of 1.5 seconds
time.sleep(1.5)
# displays welcome message to player for inventory review function; indicates viewable player inv/specs
print("----------------------------------------------------------------\nWelcome to your player inventory "
+ "review.\nHere, you can review your player inventory and stats, inclusive of all stones, gold, " +
"player level, xp, rank title, and health potions.\n----------------------------------------\nHere " +
"is an overview of your player inventory: ")
# displays player's stones inventory and health potions inventory
print("----------------------------------------\nWizard Stones: " + str(self.player.wizard_stones) +
"\nEarth Stones: " + str(self.player.stones_inv[0]) + "\nWater Stones: " +
str(self.player.stones_inv[1]) + "\nFire Stones: " + str(self.player.stones_inv[2]) + "\nAir Stones: "
+ str(self.player.stones_inv[3]) + "\n\nGold: " + str(self.player.gold) + "\n\nBasic Health Potions: "
+ str(self.player.healing_potions[0]) + "\nSupreme Health Potions: " +
str(self.player.healing_potions[1]) + "\nMaster Health Potions: " +
str(self.player.healing_potions[2]) + "\nRevival Potions: " + str(self.player.healing_potions[3]))
# displays message separator and indicates that player stats will be displayed next
print("----------------------------------------\nHere is an overview of your player stats: ")
# displays the player's name, rank title, level and level progress
print("----------------------------------------\nName: " + self.player.name + "\nRank Title: " +
self.player.rank_title + "\nLevel: " + str(self.player.player_level) + "\nLevel Progress: " +
str(self.player.level_progress) + " / " + str(self.player.player_level * 10))
# runs assuming player choice is "exit"
else:
# delay of 1.5 seconds
time.sleep(1.5)
# displays message indicating to user that he/she is exiting review and will be redirected to the main menu
print("----------------------------------------------------------------\nYou are now exiting the " +
"wizard/inventory review, and will be returned to the main menu momentarily.")
# druid shop function; allows player to buy shop items, exchange resources, heal wizards or exit back to main menu
def druid_shop(self):
# infinite while loop
while True:
# player choices list storing possible player options (buy, exchange, heal or exit)
player_choices = ["buy", "exchange", "heal", "exit"]
# displays intro message to player, indicates all possible in game choices and describes functions of each
print("------------------------------------------------------------------------------------------------" +
"\nWelcome to the Druid Shop.\nHere, you can choose to make purchases (buy), exchange currency/" +
"resources (exchange), review/heal your wizards after battles (heal), or exit the Druid Shop (exit).")
# displays prompt message, intake player choice (buy/exchange/heal/exit); converts all letters to lowercase
player_choice = input("----------------------------------------\nPlease input your choice (buy/exchange/" +
"heal/exit), here: ").lower()
# while loop; iterates while player input is not in list player choices (thus is not a valid choice)
while player_choice not in player_choices:
# displays prompt error message to use, retakes in user input choice; converts all letters to lowercase
player_choice = input("Sorry, but that was an invalid input. Please re-enter your choice (buy/exchange/"
+ "heal/exit), here: ").lower()
# tests player choice input value; runs if it is "buy"
if player_choice == "buy":
# updates player choices list with player shop items; variables created to store amount to buy and cost
player_choices = ["wzs", "es", "ws", "fs", "as", "bhp", "shp", "mhp", "rp"]
amount, cost = int(), int()
# creates matrix options info to store the specific info to display per item (name, price, player inv)
options_info = [["Wizard Stones", 250, self.player.wizard_stones],
["Earth Stones", 100, self.player.stones_inv[0]],
["Water Stones", 100, self.player.stones_inv[1]],
["Fire Stones", 100, self.player.stones_inv[2]],
["Air Stones", 100, self.player.stones_inv[3]],
["Basic Health Potions", 50, self.player.healing_potions[0]],
["Supreme Health Potions", 75, self.player.healing_potions[1]],
["Master Health Potions", 125, self.player.healing_potions[2]],
["Revival Health Potions", 200, self.player.healing_potions[3]]]
# displays message to player, indicating sale items with sale prices (player gold also displayed)
print("----------------------------------------------------------------\nWelcome, " + self.player.name +
". At the Druid Shop, you can spend gold and purchase: \nWizard Stones (wzs): to summon wizards "
+ "to join your band, or upgrade your wizards\n\tCost: 250 Gold-> 1 Wizard Stone\nElemental " +
"Stones (es/ws/fs/as): earth, water, fire or air stones to upgrade your wizards' moves\n\tCost: "
+ "100 Gold -> 1 Elemental Stone\nHealth Potions (bhp/shp/mhp/rp): to heal your wizards after " +
"battle\n\tCost: 50 Gold -> 1 Basic Potion; 75 Gold -> 1 Supreme Potion; 125 Gold -> 1 Master " +
"Potion; 200 Gold -> 1 Revival Potion\n\nYou have " + str(self.player.gold) + " Gold to spend " +
"here; spend it all wisely.")
# displays prompt message to player, intakes choice for purchase item; converts letters to lowercase
player_choice = input("Please enter what you would like to buy (wzs/es/ws/fs/as/bhp/shp/mhp/rp), here: "
).lower()
# while loop; iterates while player choice not in list player choices (thus is not a valid input choice)
while player_choice not in player_choices:
# displays prompt error message, retakes input choice for item to purchase; converts to lowercase
player_choice = input("Sorry, but that was an invalid choice.\nPlease re-enter what you would like "
+ "to buy (wzs/es/ws/fs/as/bhp/shp/mhp/rp), here: ").lower()
# uses player input to retrieve necessary information/variables related to buying chosen shop item
if player_choice == "wzs":
# retrieves necessary information/variables from options info matrix for buying wizard stones
player_choice, exchange_rate, player_option = options_info[0]
elif player_choice == "es":
# retrieves necessary information/variables options info matrix for buying earth stones
player_choice, exchange_rate, player_option = options_info[1]
elif player_choice == "ws":
# retrieves necessary information/variables options info matrix for buying water stones
player_choice, exchange_rate, player_option = options_info[2]
elif player_choice == "fs":
# retrieves necessary information/variables options info matrix for buying fire stones
player_choice, exchange_rate, player_option = options_info[3]
elif player_choice == "as":
# retrieves necessary information/variables options info matrix for buying air stones
player_choice, exchange_rate, player_option = options_info[4]
elif player_choice == "bhp":
# retrieves necessary information/variables options info matrix for buying basic health potions
player_choice, exchange_rate, player_option = options_info[5]
elif player_choice == "shp":
# retrieves necessary information/variables options info matrix for buying supreme health potions
player_choice, exchange_rate, player_option = options_info[6]
elif player_choice == "mhp":
# retrieves necessary information/variables options info matrix for buying master health potions
player_choice, exchange_rate, player_option = options_info[7]
else:
# retrieves necessary information/variables options info matrix for buying revival health potions
player_choice, exchange_rate, player_option = options_info[8]
# infinite while loop
while True:
# try structure attempts to take in player input
try:
# displays the unit price for player's chosen shop item to purchase, and player's current gold;
# displays prompt message to player, intakes input for quantity of chosen shop item to buy
amount = int(input(player_choice + "cost " + str(exchange_rate) + " Gold each. You currently " +
"have " + str(self.player.gold) + " Gold.\nPlease indicate how many " +
player_choice + " you would like to buy (enter 0 if you want to cancel the "
+ "purchase), here: "))
# tests integer value of variable amount; runs if it is 0 (player wants to cancel purchase)
if amount == 0:
# breaks out of infinite while loop
break
# tests integer value of variable amount; runs if it is smaller than 0 (invalid input)
elif amount <= 0:
# displays prompt error message to user, indicating that negative values are invalid inputs
print(
"Sorry, but that was an invalid negative integer value. Please re-enter a value below.")
# runs assuming player inputted valid positive integer value
else:
# calculates cost by multiplying amount to purchase with price per unit/item, stores in cost
cost = amount * exchange_rate
# compares player purchase cost with player's gold reserves; runs if cost exceeds reserves
if cost > self.player.gold:
# displays prompt error message to player, indicating that he/she cannot afford price
print("Sorry, but you do not have enough Gold (" + str(self.player.gold) + ") to make "
+ "that purchase (" + str(cost) + ").\nPlease re-enter an amount that you can " +
"afford below.")
# runs assuming player purchase cost does not exceed player's gold reserves (is affordable)
else:
# breaks out of infinite while loop
break
# runs assuming a ValueError was encountered in try structure's attempt to take in player input
except ValueError:
# displays prompt error message to player, prompting for re-entry of valid integer value
print(
"Sorry, but that was an invalid input. Please re-enter a valid integer amount to buy below.")
# updates player gold and inventory amounts, subtracting spent gold and adding purchased inventory items
self.player.gold -= cost
self.player_option += amount
# displays message to player, indicating that the shop item(s) purchase was successfully completed
print("You have successfully bought " + str(amount) + " " + player_choice + " for a grand total of " +
str(cost) + " Gold. ")
# displays prompt message to player, intakes choice to either buy or exit shop; coverts to lowercase
player_choice = input("Would you like to buy something else from the Druid Shop (buy), or leave (exit)?"
+ "\nPlease indicate your choice (buy/exit), here: ").lower()
# while loop; iterates while player choice input is not "buy" or "exit"
while (player_choice != "buy") and (player_choice != "exit"):
# displays prompt error message, retakes input choice, converts all input letters to lowercase
player_choice = input("Sorry, but that was an invalid choice. Please re-enter your choice (buy/" +
"leave), here: ").lower()
# displays message separator
print("----------------------------------------------------------------")
# tests player choice input value; runs if it is "buy"
if player_choice == "buy":
# displays message, indicates to player that he/she will be redirected to the druid shop momentarily
print("You will be redirected back to the Druid Shop momentarily...")
# runs assuming player choice input value is "exit"
else:
# delay of 1.5 seconds
time.sleep(1.5)
# displays message, indicates to player that he/she will be redirected to the main menu momentarily
print("You will be redirected back to the main menu momentarily...")
# breaks out of druid shop infinite while loop
break
# tests player choice input value; runs if it is "exchange"
elif player_choice == "exchange":
# updates player choices list, has items that player can exchange for gold (wizard/elemental stones)
player_choices = ["wz2g", "e2g", "w2g", "f2g", "a2g"]
# creates choices info matrix to store stones variables/names and exchange rates
choices_info = [[self.player.wizard_stones, "Wizard Stone(s)", 250],
[self.player.stones_inv[0], "Earth Stone(s)", 100],
[self.player.stones_inv[1], "Water Stone(s)", 100],
[self.player.stones_inv[2], "Fire Stone(s)", 100],
[self.player.stones_inv[3], "Air Stone(s)", 100]]
# creates variable choice_no to store player's choice (as integer value) and gold earned from exchange
choice_no, gold_earned = int(), int()
# displays message to player, and shows exchange rates for wizard/elemental stones to gold
print("----------------------------------------------------------------\nWelcome, " + self.player.name +
". At the Druid Shop, you can make the following currency/resource exchanges at the following " +
"rates:\n1 Wizard Stone -> 250 Gold (wz2g)\n1 Earth/Water/Fire/Air Stone -> 100 Gold (e2g/w2g/f2g"
+ "/a2g)")
# displays prompt message to player, intakes player choice for stones, converts letters to lowercase
player_choice = input("----------------------------------------\nPlease input your choice (wz2g/e2g/w2g"
+ "/f2g/a2g), here: ").lower()
# while loop; iterates while player choice input is not in list player choices (thus input is invalid)
while player_choice not in player_choices:
# displays prompt error message to player, retakes in user input choice, converts all to lowercase
player_choice = input("Sorry, but that was an invalid input. Please re-input your choice (wz2g/e2g"
+ "/w2g/f2g/a2g), here: ").lower()
# tests player choice input value; runs if it is "wz2g" (exchanging Wizard Stones for Gold)
if player_choice == "wz2g":
# assigns value 0 to choice_no (to be used as index value to retrieve Wizard Stones Exchange Info)
choice_no = 0
# tests player choice input value; runs if it is "e2g" (exchanging Earth Stones for Gold)
elif player_choice == "e2g":
# assigns value 1 to choice_no (to be used as index value to retrieve Earth Stones Exchange Info)
choice_no = 1
# tests player choice input value; runs if it is "w2g" (exchanging Water Stones for Gold)
elif player_choice == "w2g":
# assigns value 2 to choice_no (to be used as index value to retrieve Water Stones Exchange Info)
choice_no = 2
# tests player choice input value; runs if it is "f2g" (exchanging Fire Stones for Gold)
elif player_choice == "f2g":
# assigns value 3 to choice_no (to be used as index value to retrieve Fire Stones Exchange Info)
choice_no = 3
# runs assuming player choice input value is "a2g" (exchanging Air Stones for Gold)
else:
# assigns value 4 to choice_no (to be used as index value to retrieve Air Stones Exchange Info)
choice_no = 4
# infinite while loop
while True:
# try structure attempts to intake player input integer value for quantity of stones to exchange
try:
# displays message separator and prompt message to player, intakes integer quantity value
input_num = int(input("----------------------------------------\nYou currently have " +
str(choices_info[choice_no][0]) + " " + choices_info[choice_no][1] + "." +
"\nPlease input the number of " + choices_info[choice_no][
1] + " that you " +
"would like to exchange for gold (1 stone -> " +
str(choices_info[choice_no][2]) + " gold), here: "))
# tests value of player integer input; runs if greater than player's current inventory quantity
if input_num > choices_info[choice_no][0]:
# displays prompt error message to player, indicating that chosen quantity exceeds inventory
print("Sorry, but you do not have that quantity of",
choices_info[choice_no][1] + " to trade.")
# tests value of player integer input; runs if less than 0 (invalid negative integer value)
elif input_num < 0:
# displays prompt error message to player, indicating chosen quantity can't be exchanged
print("Sorry, but you cannot trade a negative quantity of " + choices_info[choice_no][
1] + ".")
# runs assuming value of player integer input is greater than 0, doesn't exceed player inventory
else:
# calculates gold earned from stones exchange; stores amount in variable gold earned
gold_earned = input_num * choices_info[choice_no][2]
# breaks out of infinite while loop
break
# except structure runs if try structure raises ValueError in attempt to intake player integer value
except ValueError:
# displays error prompt message to player, indicating that input made was invalid
print("Sorry, but that was an invalid input. Please re-enter a valid integer input below.")
# removes number of stones from player stones inventory, adds earned gold amount to player gold reserve
choices_info[choice_no][0] -= input_num
self.player.gold += gold_earned
# displays message to player, indicating that chosen exchange of stones was successful
print("You have successfully exchange " + str(input_num) + " " + choices_info[choice_no][1] + "for " +
str(gold_earned) + " gold.\nYou will return to browsing the Druid Shop momentarily...")
# tests player choice input value; runs if it is "heal"
elif player_choice == "heal":
# infinite while loop
while True:
# updates player choices list to contain possible player options for this particular function
player_choices = ["heal", "lvl_wz", "summon", "up_wz_atc"]
# creates valid ints list to store valid integers for player input and function use
valid_ints = []
# displays message separator and welcome message to player to druid shop, lists possible options
print("----------------------------------------------------------------\nWelcome, " +
self.player.name + ". At the Druid Shop, you can review your wizards, and use:\n" +
"----------------------------------------------------------------\nHealth Potions: to " +
"restore wizards' health to varying degrees (depends on potion)\nWizard Stones: to level up "
+ "wizards, or summon new ones\nElemental Stones: to level up wizards' attacks, "
+ "using corresponding stones")
# displays prompt message to player, intakes player choice input, converts all letters to lowercase
player_choice = input("----------------------------------------------------------------\n" +
"Please indicate whether you would like to heal wizards (heal), level up or "
+ "summon wizards (lvl_wz/summon) or upgrade wizard attacks (up_wz_atc), " +
"here: ").lower()
# while loop; runs while player choice input is not in list "player choices" (thus is invalid)
while player_choice not in player_choices:
# displays prompt error message to player, retakes player input, converts input to lowercase
player_choice = input("Sorry, but that was an invalid input. Please indicate your choice (heal/"
+ "lvl_wz/summon/up_wz_atc), here: ").lower()
# tests player choice input value; runs if it is "heal"
if player_choice == player_choices[0]:
# displays message to player, indicating overview of his/her wizard's healths will be shown
print("----------------------------------------------------------------\nHere is an overview " +
"of the current health of all of your wizards in your band:")
# for loop; iterates for number of wizards in list wizards
for counter in range(0, len(self.wizards)):
# prints wizard band slot number, wizard's name and current vs. max hp values
print(str(counter + 1) + ". " + self.wizards[counter].name + " -> Current/Max HP: " +
str(self.wizards[counter].current_hp) + " / " + str(self.wizards[counter].max_hp))
valid_ints.append(str(counter + 1))
# displays prompt message to player, intakes reference number of wizard player wants to heal
player_choice = input("----------------------------------------------------------------\n" +
"Please input the # of the wizard that you would like to heal, here: ")
# while loop; iterates while player choice input not in list valid_ints (thus an invalid input)
while player_choice not in valid_ints:
# displays prompt error message to player, retakes reference number for wizard to heal
player_choice = input("Sorry. but that was an invalid input. Please input the number of " +
"the wizard that you would like to heal, here: ")
# retrieves instance of wizard to be healed from wizards attribute using player choice input
wiz_2_heal = self.wizards[int(player_choice) - 1]
# creates lists defining the valid choices of healing potions and the amount healed by each
player_choices = ["bhp", "shp", "mhp", "rp"]
player_options = ["Basic Health Potions: ", "Supreme Health Potions: ",
"Master Health Potions: ", "Revival Potions: "]
player_option_values = ["20 HP", "30 HP", "50 HP", "MAX HP"]
# displays message to player, indicating that his/her health potions inventory will be displayed
print("----------------------------------------------------------------\n" +
"Here is an overview of your current inventory of health potions:")
# for loop; iterates four times
for counter in range(0, 4):
# displays health potions inventory message with specific potion name and quantity available
print(player_options[counter] + str(self.player.healing_potions[counter]) +
"\nAmount Healed (HP): " + player_option_values[counter])
# displays prompt to player; intakes player choice input, converts all letters to lowercase
player_choice = input("Which potion would you like to use for your wizard, " + wiz_2_heal.name +
"?\nPlease indicate your choice (bhp/shp/mhp/rp), here: ").lower()
# while loop; iterates while player choice input not in player_choices list (thus is invalid)
while player_choice not in player_choices:
# displays prompt error message to player; retakes player input and converts to lowercase
player_choice = input("Sorry, but that was an invalid input.\nPlease indicate your choice "
+ "(bhp/shp/mhp/rp), here: ").lower()
# tests player choice; runs if it is "bhp" (player wants to use a basic health potion)
if player_choice == "bhp":
# heals selected wizard for 20 health points, using up a basic health potion
wiz_2_heal.current_hp += 20
self.player.healing_potions[0] -= 1
# tests player choice; runs if it is "shp" (player wants to use a supreme health potion)
elif player_choice == "shp":
# heals selected wizard for 30 health points, using up a supreme health potion
wiz_2_heal.current_hp += 30
self.player.healing_potions[1] -= 1
# tests player choice; runs if it is "mhp" (player wants to use a master health potion)
elif player_choice == "mhp":
# heals selected wizard for 50 health points, using up a master health potion
wiz_2_heal.current_hp += 50
self.player.healing_potions[2] -= 1
# runs assuming player choice is "rp" (last valid choice; player wants to use a revival potion)
else:
# heals selected wizard up to maximum health, using up a revival potion
wiz_2_heal.current_hp = wiz_2_heal.max_hp
self.player.healing_potions[3] -= 1
# compares selected wizard's current hp and max hp; runs if current hp is greater than max hp
if wiz_2_heal.current_hp > wiz_2_heal.max_hp:
# adjusts wizard's current hp to be equal to its max hp
wiz_2_heal.current_hp = wiz_2_heal.max_hp
# runs assuming selected wizard's current hp is equal to or less than its max hp
else:
# passes onto next code
pass
# tests player choice input value; runs if it is "lvl_wz"
elif player_choice == player_choices[1]:
# displays message to player, indicating overview of his/her wizard's levels will be shown
print("----------------------------------------------------------------\nHere is an overview " +
"of the current levels of all of your wizards in your band:")
# for loop; iterates for number of wizards in list wizards
for counter in range(0, len(self.wizards)):
# prints wizard band slot number, wizard's name and wizard's current level
print(str(counter + 1) + ". " + self.wizards[counter].name + " -> Wizard Level: " +
str(self.wizards[counter].wizard_level))
valid_ints.append(str(counter + 1))
# displays prompt message to player, intakes reference number of wizard player wants to level up
player_choice = input("----------------------------------------------------------------\n" +
"Please input the # of the wizard you would like to level up, here: ")
# while loop; iterates while player choice input not in list valid_ints (thus an invalid input)
while str(player_choice) not in valid_ints:
# displays prompt error message to player, retakes reference number for wizard to level up
player_choice = input("Sorry. but that was an invalid input. Please input the number of " +
"the wizard that you would like to level up, here: ")
# retrieves instance of wizard to be leveled up from wizards attribute using player choice input
wiz_2_lvl_up = self.wizards[int(player_choice) - 1]
# displays message to player, indicating number of Wizards Stones that he/she has for use
print("----------------------------------------------------------------\nYou have " +
str(self.player.wizard_stones))
while True:
try:
stones_to_use = int(input("Please input the number of Wizard stones that you would " +
"like to use (1 stone -> 1 level), here: "))
if stones_to_use < 0:
print("Sorry, but that is an invalid amount of wizard stones to be used.")
elif stones_to_use > self.player.wizard_stones:
print("Sorry, but you do not have that many wizard stones available for use.")
else:
break
except ValueError:
print("Sorry, but that was an invalid input. Please re-enter a valid input below.")
# selected wizard's level increased by number of wizard stones used
wiz_2_lvl_up.wizard_level += stones_to_use
# selected wizard's max hp is increased by 25 health points per level gained
wiz_2_lvl_up.max_hp += stones_to_use * 25
# selected wizard's current hp is increased to the wizard's new max hp
wiz_2_lvl_up.current_hp = wiz_2_lvl_up.max_hp
# all of selected wizard's attacks damage values increased by 1 damage point per level gained
wiz_2_lvl_up.damages = [wiz_2_lvl_up.damages[0] + stones_to_use,
wiz_2_lvl_up.damages[1] + stones_to_use,
wiz_2_lvl_up.damages[2] + stones_to_use,
wiz_2_lvl_up.damages[3] + stones_to_use]
# selected wizard's buff amount increased by 2 points per level gained
wiz_2_lvl_up.wizard_buff_specs[1] += stones_to_use * 2
# displays message to player, outputting leveled up wizard's updated stats
print("Your wizard, " + wiz_2_lvl_up.name + ", has been successfully leveled up to level " +
str(wiz_2_lvl_up.wizard_level) + ".\n----------------------------------------\n Here is "
+ "an updated preview of " + wiz_2_lvl_up.name + "'s current stats: ")
# wizard stones value, level progress, current/max health points, wizard attacks specifications
print("\nWizard Value:\n" + str(wiz_2_lvl_up.cost[0]) + " Earth Stones\n" +
str(wiz_2_lvl_up.cost[1]) + " Water Stones\n" +
str(wiz_2_lvl_up.cost[2]) + " Fire Stones\n" +
str(wiz_2_lvl_up.cost[3]) + " Air Stones" +
"\n------------------------\nWizard Level: " + str(wiz_2_lvl_up.wizard_level) +
"\nLevel Progress: " + str(wiz_2_lvl_up.wizard_level_progress) + " / " +
str(wiz_2_lvl_up.wizard_level * 5) + "\n------------------------" +
"\nCurrent/Max Health Points: " + str(wiz_2_lvl_up.current_hp) + " / " +
str(wiz_2_lvl_up.max_hp) + "\n------------------------\nWizard Talent: " +
wiz_2_lvl_up.wizard_talent + "\nWizard Buff: " +
wiz_2_lvl_up.wizard_buff_specs[0] + "\nWizard Buff Amount: " +
str(wiz_2_lvl_up.wizard_buff_specs[1]) +
"\n------------------------\nWizard Attacks: (name/type/damage)")
# each of retrieved wizard's attacks' specs (name/type/damages) displayed in list format
for counter in range(0, len(wiz_2_lvl_up.attacks)):
print(str(counter + 1) + ". " + wiz_2_lvl_up.attacks[counter] + " / " +
wiz_2_lvl_up.attack_types[counter] + " / " + str(wiz_2_lvl_up.damages[counter]))
# for summoning new wizards
elif player_choice == player_choices[2]:
pass
# for upgrading wizard attacks
else:
pass
# displays prompt message to player, intakes player choice input; converts all letters to lowercase
player_choice = input("----------------------------------------------------------------\n" +
"Would you like to continue to heal/level up/upgrade other wizards, or " +
"return back to browsing the Druid Shop?\nPlease indicate your choice " +
"(stay/return), here: ").lower()
# while loop; iterates while player choice is neither "stay" nor "return" (thus is an invalid input)
while (player_choice != "stay") and (player_choice != "return"):
# displays error prompt message to player, retakes user input; converts letters to lowercase
player_choice = input("Sorry, but that was an invalid input. Please re-enter a valid choice, " +
"here: ").lower()
# tests player choice input; runs if it is "stay"
if player_choice == "stay":
# runs next iteration of infinite while loop controlling heal function of druid shop
continue
# runs assuming player choice input is "return"
else:
# displays message to player, indicating he/she will be returned to the druid shop momentarily
print("You will return to browsing the Druid Shop momentarily...")
# breaks out of infinite while loop
break
# runs assuming player choice input value is "exit"
else:
# delay of 1.5 seconds
time.sleep(1.5)
# displays message separator and message, telling player that he/she will be redirected to main menu
print("----------------------------------------------------------------\nYou will be redirected back " +
"to the main menu momentarily...")
# breaks out of druid shop infinite while loop
break
# quit function; runs whenever the player indicates that he/she would like to quit the game
def quit_function(self):
# delay of 1 second
time.sleep(1)
# displays prompt message to player, to get quit confirmation
quit_confirm = input(
"------------------------------------------------\nYou have indicated that you would like " +
"to quit the game.\nPlease confirm this by entering either \"yes\" to confirm quitting, " +
"or \"no\" to return back to playing the game, here: ")
# while loop runs while player input is neither "yes" nor "no"
while (quit_confirm != "yes") and (quit_confirm != "no"):
# delay of 0.5 seconds
time.sleep(0.5)
# displays prompt to player, and retakes in player input (yes/no)
quit_confirm = input(
"Sorry, by that was an invalid choice. Please re-enter a valid choice (yes/no), here: ")
# tests if player input is yes (confirming player choice to quit)
if quit_confirm == "yes":
# delay of 1 second
time.sleep(1)
# prints game termination message to the console
print("------------------------------------------------------------------------------------------------" +
"\nThe game will now terminate. Thank you for playing World Of Wizards, and have a nice day.\n" +
"\n=============================== World Of Wizards Game Termination ==============================")
# delay of 1 second
time.sleep(1)
# terminates the running game
quit()
# else statement runs, assuming that the player's choice was to return back to playing the game
else:
# passes to return back to playing the game
pass
# references and instantiates an instance of the class GameMainframeCode (code that controls the entire game program)
gmc = GameMainframeCode()