From cccdf5f2d59e4389c1bf435e6173428e6725ebc3 Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Tue, 24 May 2022 10:23:06 +0200 Subject: [PATCH 1/3] improve gitignore --- .gitignore | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1cf4b93..22b77aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.idea PyRPG_Mini.iml markdown-navigator.xml misc.xml @@ -7,3 +6,50 @@ vcs.xml workspace.xml markdown-navigator inspectionProfiles + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# csv-files +*.csv + +# certificates +*.crt + +# PyCharm +.idea/ + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Translations +*.mo +*.pot + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ From d5cab8fc15f9e5458927abb14f18c013d5cbb2d1 Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Tue, 24 May 2022 12:41:06 +0200 Subject: [PATCH 2/3] PEP-8, Type-Hinting, Refactoring, General Cleanup --- Armor.py | 139 ++++---- dbsetup.py => Database.py | 53 +-- Enemy.py | 85 ++--- Game.py | 662 +++++++++++++++++++------------------- Hero.py | 398 +++++++++++------------ Item.py | 35 +- Shield.py | 153 +++++---- __init__.py | 2 +- 8 files changed, 793 insertions(+), 734 deletions(-) rename dbsetup.py => Database.py (77%) diff --git a/Armor.py b/Armor.py index 49f2a92..261e0a5 100644 --- a/Armor.py +++ b/Armor.py @@ -1,112 +1,131 @@ -import Game import random +from enum import Enum +from texttools import * + + +class ArmorType(Enum): + OUTFIT = 'outfit' + PLATE = 'plate' + ROBE = 'robe' + + +class ArmorQuality(Enum): + RUSTY = 'rusty' + COMMON = 'common' + GREAT = 'great' + MAGICAL = 'magical' + LEGENDARY = 'legendary' class Armor: - # level,classtype,name,type,basedef,durability - def __init__(self, armorlevel, armorclasstype, armorname, armortype, armorbasedef, armordur): + def __init__(self, + armor_level: int, + armor_class_type: str, + armor_name: str, + armor_type: ArmorType, + armor_base_def: int, + armor_dur: int): # level - self.level = armorlevel + self.level: int = armor_level # hero Class - self.classtype = armorclasstype + self.class_type: str = armor_class_type # hero Class - self.type = armortype - self.name = armorname + self.type: ArmorType = armor_type + self.name: str = armor_name # Armor Quality (rusty, common, great, magical, legendary) - chance = random.randint(1, 100) + chance: int = random.randint(1, 100) if chance < 20: - self.quality = 'Rusty' + self.quality = ArmorQuality.RUSTY elif chance >= 21 or chance < 65: - self.quality = 'Common' + self.quality = ArmorQuality.COMMON elif chance >= 66 or chance < 86: - self.quality = 'Great' + self.quality = ArmorQuality.GREAT elif chance >= 85 or chance < 96: - self.quality = 'Magical' + self.quality = ArmorQuality.MAGICAL elif chance >= 96 or chance < 100: - self.quality = 'Legendary' + self.quality = ArmorQuality.LEGENDARY # Defense Values - self.basedefn = armorbasedef + self.base_defn = armor_base_def if self.quality == 'Rusty': - self.basedefn = int(self.basedefn * 0.9) + self.base_defn = int(self.base_defn * 0.9) elif self.quality == 'Common': - self.basedefn = int(self.basedefn * 1) + self.base_defn = int(self.base_defn * 1) elif self.quality == 'Great': - self.basedefn = int(self.basedefn * 1.25) + self.base_defn = int(self.base_defn * 1.25) elif self.quality == 'Magical': - self.basedefn = int(self.basedefn * 1.6) + self.base_defn = int(self.base_defn * 1.6) elif self.quality == 'Legendary': - self.basedefn = int(self.basedefn * 2) + self.base_defn = int(self.base_defn * 2) - self.defn = self.basedefn + self.defn = self.base_defn # armor durability value - self.maxdur = armordur + self.max_dur = armor_dur if self.quality == 'Rusty': - self.maxdur = int(self.maxdur * 0.9) + self.max_dur = int(self.max_dur * 0.9) elif self.quality == 'Common': - self.maxdur = int(self.maxdur * 1) + self.max_dur = int(self.max_dur * 1) elif self.quality == 'Great': - self.maxdur = int(self.maxdur * 1.25) + self.max_dur = int(self.max_dur * 1.25) elif self.quality == 'Magical': - self.maxdur = int(self.maxdur * 1.6) + self.max_dur = int(self.max_dur * 1.6) elif self.quality == 'Legendary': - self.maxdur = int(self.maxdur * 2) - self.dur = self.maxdur + self.max_dur = int(self.max_dur * 2) + self.dur = self.max_dur # damage durability, and check to see if broken - def damagedur(self, aug, curve): + def damage_dur(self, aug, curve) -> None: self.dur -= int(aug * curve * .1) - self.isbroken() - pass + self.is_broken() # restore dur and check to see if fixed - def restoredur(self, aug): + def restore_dur(self, aug) -> None: self.dur += aug - if self.dur > self.maxdur: - self.dur = self.maxdur - if not self.isbroken(): - self.defn = self.basedefn + if self.dur > self.max_dur: + self.dur = self.max_dur + if not self.is_broken(): + self.defn = self.base_defn # repair entirely - def repair(self): - self.defn = self.basedefn - self.dur = self.maxdur + def repair(self) -> None: + self.defn = self.base_defn + self.dur = self.max_dur # 15% durability = stat reduction - def isbroken(self): + def is_broken(self) -> bool: if self.dur <= 0: - self.gearbreak() + self.gear_break() return True - elif self.dur > 0: - return False + return False # this breaks the gear - def gearbreak(self): - self.atk = int(self.basedefn * .3) + def gear_break(self) -> None: + # Possible FixMe: self.atk seems to serve no purpose + self.atk = int(self.base_defn * .3) # prints all armor info - def printarmorinfo(self): - Game.marqueeprint('ARMOR') - print(Game.lr_justify('Level:', str(self.level), 60)) - print(Game.lr_justify('Name:', str(self.name), 60)) - print(Game.lr_justify('Type:', str(self.type), 60)) - print(Game.lr_justify('Defense:', str(self.defn) + '/' + str(self.basedefn), 60)) - print(Game.lr_justify('Dur:', str(self.dur) + '/' + str(self.maxdur), 60)) - print(Game.lr_justify('Broken?:', str(self.isbroken()), 60)) - print(Game.lr_justify('Quality:', str(self.quality()), 60)) - - # ['Level', 'Name', 'Type', 'Defense', 'Dur', 'Broken?', 'Power'] - def datadict(self): + def print_armor_info(self) -> None: + marqueeprint('ARMOR') + print(lr_justify('Level:', str(self.level), 60)) + print(lr_justify('Name:', str(self.name), 60)) + print(lr_justify('Type:', str(self.type), 60)) + print(lr_justify('Defense:', str(self.defn) + '/' + str(self.base_defn), 60)) + print(lr_justify('Dur:', str(self.dur) + '/' + str(self.max_dur), 60)) + print(lr_justify('Broken?:', 'Yes' if self.is_broken() else 'No', 60)) + print(lr_justify('Quality:', str(self.quality), 60)) + + # {'Level', 'Name', 'Type', 'Defense', 'Dur', 'Broken?', 'Power'} + def datadict(self) -> dict: return {'Level': str(self.level), - 'Name': str(self.name) + ' ' + str(self.type), + 'Name': f'{self.name} {self.type}', 'Def': str(self.defn), - 'Dur': str(self.dur) + '/' + str(self.maxdur), - 'Broken?': str(self.isbroken()), - 'Repair Cost': str(self.maxdur - self.dur) + ' gold', + 'Dur': f'{self.dur} / {self.max_dur}', + 'Broken?': str(self.is_broken()), + 'Repair Cost': f'{str(self.max_dur - self.dur)} gold', 'Quality': str(self.quality) } diff --git a/dbsetup.py b/Database.py similarity index 77% rename from dbsetup.py rename to Database.py index 00d6458..2558f40 100644 --- a/dbsetup.py +++ b/Database.py @@ -1,24 +1,25 @@ import csv import os from sqlite3 import connect +from texttools import centerprint -import Game - -class dbsetup(): +class Database: def __init__(self): - self.dbpath = './db/game.db' + self.db_path: str = './db/game.db' # import and create our player database - self.gamedb = connect(self.dbpath) - self.conn = self.gamedb.cursor() + self.game_db = connect(self.db_path) + self.conn = self.game_db.cursor() # used to delete the current database - def deletedbifexists(self): + @staticmethod + def delete_db_if_exists() -> None: if os.path.exists('./db/game.db'): os.remove('./db/game.db') - def setupdb(self): - # If you set this to 1, it will print out all data as it populates the datbase. + @staticmethod + def setup_db(): + # If you set this to 1, it will print out all data as it populates the database. debugging = 0 # make a database connection to the game database @@ -35,7 +36,8 @@ def setupdb(self): if debugging: print('creating table for armor') cur.execute( - '''CREATE TABLE IF NOT EXISTS armor (level INTEGER, class TEXT, name TEXT, type TEXT, basedef INTEGER, durability INTEGER)''') + 'CREATE TABLE IF NOT EXISTS armor ' + '(level INTEGER, class TEXT, name TEXT, type TEXT, base_def INTEGER, durability INTEGER)') # insert our armor table in the database if debugging: @@ -56,7 +58,9 @@ def setupdb(self): if debugging: print('creating table for enemies') cur.execute( - '''CREATE TABLE IF NOT EXISTS enemies(level INT, firstname TEXT, middlename TEXT, lastname TEXT, attack INTEGER, xp INTEGER, gold INTEGER, hp INTEGER, def INTEGER, status TEXT)''') + 'CREATE TABLE IF NOT EXISTS enemies ' + '(level INT, firstname TEXT, middlename TEXT, lastname TEXT, attack INTEGER, ' + 'xp INTEGER, gold INTEGER, hp INTEGER, def INTEGER, status TEXT)') # insert our enemy table in the database if debugging: @@ -73,13 +77,13 @@ def setupdb(self): for row in rows: print('QUERY ALL: ' + str(row)) - # create our items table in the database + # create our item's table in the database if debugging: print('creating table for items') cur.execute( - '''CREATE TABLE IF NOT EXISTS items(level INT, grade INT,name TEXT,effect INT,value INT)''') + 'CREATE TABLE IF NOT EXISTS items(level INT, grade INT,name TEXT,effect INT,value INT)') - # insert our items table in the database + # insert our item's table in the database if debugging: print('inserting items into database') with open('./csv/items.csv', 'r') as fin: @@ -94,15 +98,15 @@ def setupdb(self): for row in rows: print('QUERY ALL: ' + str(row)) - # create our levelnotes table in the database + # create our level notes table in the database if debugging: - print('creating table for levelnotes') + print('creating table for level notes') cur.execute( - '''CREATE TABLE IF NOT EXISTS levelnotes(Level INT,HP INT,ATK INT,DEF INT,xptonextlevel INT, dodge INT )''') + 'CREATE TABLE IF NOT EXISTS levelnotes(Level INT,HP INT,ATK INT,DEF INT,xptonextlevel INT, dodge INT )') - # insert our levelnotes table in the database + # insert our level notes table in the database if debugging: - print('inserting levelnotes into database') + print('inserting level notes into database') with open('./csv/levelnotes.csv', 'r') as fin: dr = csv.reader(fin) for i in dr: @@ -115,13 +119,13 @@ def setupdb(self): for row in rows: print('QUERY ALL: ' + str(row)) - # create our shields table in the database + # create our shield's table in the database if debugging: print('creating table for shields') cur.execute( - '''CREATE TABLE IF NOT EXISTS shields (level INT,class TEXT,name TEXT,type TEXT,basedef INT,durability INT)''') + 'CREATE TABLE IF NOT EXISTS shields (level INT,class TEXT,name TEXT,type TEXT,base_def INT,durability INT)') - # insert our shields table in the database + # insert our shield's table in the database if debugging: print('inserting shields into database') with open('./csv/shields.csv', 'r') as fin: @@ -140,7 +144,8 @@ def setupdb(self): if debugging: print('creating table for weapons') cur.execute( - '''CREATE TABLE IF NOT EXISTS weapons ( level INTEGER ,class TEXT ,name TEXT ,type TEXT,baseattack INTEGER ,durability INTEGER ,power TEXT)''') + 'CREATE TABLE IF NOT EXISTS weapons ' + '(level INTEGER ,class TEXT ,name TEXT ,type TEXT,baseattack INTEGER ,durability INTEGER ,power TEXT)') # insert our weapons table in the database if debugging: @@ -181,4 +186,4 @@ def setupdb(self): conn.commit() # close the database connection to let other operations use it conn.close() - Game.centerprint('...Have fun') + centerprint('...Have fun') diff --git a/Enemy.py b/Enemy.py index 1bd6824..e46dbbe 100644 --- a/Enemy.py +++ b/Enemy.py @@ -1,77 +1,84 @@ +from typing import Optional + import Game class Enemy: - def __init__(self, enemylevel, enemyname1, enemyname2, enemyname3, enemyatk, enemyxp, enemygold, enemyhp, enemydefn, - enemystatuseffect): - self.level = enemylevel - if enemyname2 == enemyname3: - enemyname3 = '' - self.name = str(enemyname1) + ' ' + str(enemyname2) + ' ' + str(enemyname3) - self.atk = enemyatk - self.xp = enemyxp - self.gold = enemygold - self.maxhp = enemyhp - self.hp = self.maxhp - self.defn = enemydefn - self.effect = enemystatuseffect + def __init__(self, + enemy_level: int, + enemy_name_1: str, + enemy_name_2: str, + enemy_name_3: str, + enemy_atk: int, + enemy_xp: int, + enemy_gold: int, + enemy_hp: int, + enemy_defn: int, + enemy_status_effect: Optional[str]): + self.level = enemy_level + if enemy_name_2 == enemy_name_3: + enemy_name_3 = '' + self.name: str = f'{enemy_name_1} {enemy_name_2} {enemy_name_3}' + self.atk: int = enemy_atk + self.xp: int = enemy_xp + self.gold: int = enemy_gold + self.max_hp: int = enemy_hp + self.hp: int = self.max_hp + self.defn: int = enemy_defn + self.effect: Optional[str] = enemy_status_effect # UNUSED # Heals user up to max health - def heal(self, hpup): - Game.centerprint('Enemy heals for ' + str(int(hpup)) + ' HP') - print('') - self.hp += hpup - if self.hp > self.maxhp: - self.hp = self.maxhp + def heal(self, hp_up: int) -> None: + Game.centerprint(f'Enemy heals for {hp_up} HP\n') + self.hp += hp_up + if self.hp > self.max_hp: + self.hp = self.max_hp # take damage - def damage(self, hpdown, curve): - effatk = hpdown + (hpdown * curve) - self.hp -= int(effatk) - Game.centerprint(str(self.name) + ' takes ' + str(int(effatk)) + ' damage!') + def damage(self, hp_down: int, curve: int) -> None: + eff_atk = hp_down + (hp_down * curve) + self.hp -= int(eff_atk) + Game.centerprint(f'{self.name} takes {eff_atk} damage!') if self.hp < 0: self.hp = 0 # resets enemy to max HP (done after a fight) - def reset(self): - self.hp = self.maxhp + def reset(self) -> None: + self.hp = self.max_hp # check if enemy is alive - def isalive(self): - if self.hp > 0: - return True - else: - return False + def is_alive(self) -> bool: + return self.hp > 0 # enemy running away awards normal XP/Gold to hero for now - def run(self): + def run(self) -> None: self.hp = 0 # enemy could get stronger - def anger(self): - Game.centerprint(str(self.name) + ' got Angrier!') + def anger(self) -> None: + Game.centerprint(f'{self.name} got angrier!') self.atk += self.atk * .14 # enemy could get weaker - def weaker(self): - Game.centerprint(str(self.name) + ' got Weaker!') + def weaker(self) -> None: + Game.centerprint(f'{self.name} got weaker!') self.atk -= self.atk * .14 # prints out all enemy detail - def printenemyinfodetail(self): + def print_enemy_info_detail(self) -> None: print(str(self.name)) print('\tLevel:\t' + str(self.level)) print('\tAttack:\t' + str(self.atk)) print('\tXP:\t\t' + str(self.xp)) print('\tGold:\t' + str(self.gold)) - print('\tMaxHP:\t' + str(self.maxhp)) + print('\tMaxHP:\t' + str(self.max_hp)) print('\tHP:\t\t' + str(self.hp)) - def datadict(self): + def datadict(self) -> dict: return {'Level': str(self.level), 'Attack': str(self.atk), 'XP': str(self.xp), 'Gold': str(self.gold), - 'MaxHP': str(self.maxhp), + 'MaxHP': str(self.max_hp), 'HP': str(self.hp) } diff --git a/Game.py b/Game.py index 55d5383..7e29b34 100644 --- a/Game.py +++ b/Game.py @@ -4,9 +4,11 @@ import random import time from sqlite3 import connect +from typing import Optional + +from Hero import Hero, HeroClass import Enemy -import Hero -import dbsetup +from Database import Database from texttools import * @@ -15,46 +17,43 @@ class Game: def __init__(self): # adds a little suspense # TODO: add suspense option to some printing methods? - self.suspensemode = 0 + self.suspense_mode: bool = False # provides inner workings of game, some live-comments # TODO: add more comments and stats as game goes on - self.debugging = 0 centerprint('Debugging Mode? [1] for yes, [ENTER] for no') - self.debugging = input() + self.debugging: bool = input() == "1" # riddle mode 0 - optional, 1 - mandatory centerprint('Riddles Mandatory? [1] for yes, [ENTER] for no') - self.riddlemode = input() - if self.riddlemode == '': - self.riddlemode = 0 + self.riddle_mode: bool = input() == "1" # provides a way to speed through battle (risky!) - self.autoattack = 0 + self.auto_attack: bool = False - # make blank hero and enemy objects - self.ourhero = 0 - self.ourenemy = 0 + # initialize variables for hero and enemy objects + self.our_hero: Optional[Hero] = None + self.our_enemy: Optional[Enemy] = None # global text width - self.textwidth = 70 + self.text_width: int = 70 # width of data, so it's not so spaced-out - self.datawidth = 55 + self.data_width: int = 55 # Create all game databases (only needs to run once to make databases) - firsttime = False + first_time: bool = False if 'game.db' not in os.listdir('./db/'): centerprint('This looks like it\'s your first time playing.') centerprint('We must load the database first') centerprint('This will only take a moment...') - firsttime = True + first_time = True # re-creates the database, in case you change values1 - if firsttime: + if first_time: print('Loading Database:') - oursetup = dbsetup.dbsetup() - oursetup.setupdb() + database = Database() + database.setup_db() if self.debugging: printtest() @@ -62,65 +61,62 @@ def __init__(self): self.dbpath = './db/game.db' # import and create our player database - self.gamedb = connect(self.dbpath) - self.conn = self.gamedb.cursor() - - # width of centered data in screencenter - self.datawidth = 55 + self.game_db = connect(self.dbpath) + self.conn = self.game_db.cursor() - # TODO: make self.ourhero.levelup and newhero the same function + # TODO: make self.our_hero.levelup and newhero the same function # makes a new hero object for when starting new game. - def newhero(self): + def new_hero(self) -> Hero: self.conn.execute('SELECT * FROM levelnotes WHERE level = 1;') rows = self.conn.fetchall() marqueeprint('[CHOOSE CLASS]') centerprint('[w]arrior [m]age [h]unter') - ourclass = input() - if ourclass == 'w' or ourclass == '': - ourclass = 'warrior' - elif ourclass == 'm': - ourclass = 'mage' - elif ourclass == 'h': - ourclass = 'hunter' + our_class = input() + if our_class == 'w' or our_class == '': + our_class = HeroClass.WARRIOR + elif our_class == 'm': + our_class = HeroClass.MAGE + elif our_class == 'h': + our_class = HeroClass.HUNTER else: centerprint('Please enter a valid selection') + return self.new_hero() marqueeprint('[CHOOSE DIFFICULTY]') centerprint('[1]easy [2]med [3]hard') diff = input() # the harder the difficulty, the less your attack and defense if diff == '1' or diff == '': - atkcurve = .2 - defcurve = .05 + atk_curve = .2 + def_curve = .05 elif diff == '2': - atkcurve = .1 - defcurve = .1 + atk_curve = .1 + def_curve = .1 elif diff == '3': - atkcurve = .05 - defcurve = .2 + atk_curve = .05 + def_curve = .2 else: centerprint('Please enter a valid selection') diff = 1 - atkcurve = .4 - defcurve = .05 - centerprint('Setting Difficulty to ' + str(diff)) + atk_curve = .4 + def_curve = .05 + centerprint(f'Setting Difficulty to {diff}') new_hero_data = rows[0] - ournewhero = Hero.Hero(ourclass, - new_hero_data[0], new_hero_data[1], - new_hero_data[2], new_hero_data[3], - new_hero_data[4], new_hero_data[5]) - ournewhero.defcurve = defcurve - ournewhero.atkcurve = atkcurve + our_new_hero = Hero(our_class, + new_hero_data[0], new_hero_data[1], + new_hero_data[2], new_hero_data[3], + new_hero_data[4], new_hero_data[5]) + our_new_hero.def_curve = def_curve + our_new_hero.atk_curve = atk_curve marqueeprint('[ENTER NAME]') - centerprint('Your name, ' + str(ournewhero.ourclass) + '?\n') - ournewhero.name = input() - if ournewhero.name == '': - ournewhero.name = 'Sir Lazy' - return ournewhero + centerprint(f'Your name, {our_new_hero.our_class} ?\n') + new_hero_name = input() + our_new_hero.name = new_hero_name if new_hero_name else 'Sir Lazy' + return our_new_hero # brings game back after death. - def gameloop(self): + def game_loop(self) -> None: while True: marqueeprint('') centerprint('MiniRPG') @@ -130,201 +126,199 @@ def gameloop(self): decision = input() if decision == 'n' or decision == '': # Make new global hero and enemy which will change over time - self.ourhero = self.newhero() - self.ourenemy = self.getenemy() - self.ourhero.heroperks() - gridoutput(self.ourhero.datadict()) + self.our_hero = self.new_hero() + self.our_enemy = self.get_enemy() + self.our_hero.hero_perks() + gridoutput(self.our_hero.datadict()) if decision == 'l': - print('lOADING GAME') - self.ourhero = self.loadgame() - self.ourenemy = self.getenemy() - while self.ourhero.isalive(): + print('LOADING GAME') + self.our_hero = self.load_game() + self.our_enemy = self.get_enemy() + while self.our_hero.is_alive(): self.adventure() # where the meat of things happen, this decides what happens when you enter [a]dventure def adventure(self): centerprint('[a]dventure or [c]amp') m = input() - ourrand = random.randint(0, 100) + our_rand = random.randint(0, 100) if m == 'a' or m == '': - if ourrand <= 70: - self.ourhero.isbattling = True + if our_rand <= 70: + self.our_hero.is_battling = True # Make new enemy - self.ourenemy = self.getenemy() + self.our_enemy = self.get_enemy() marqueeprint('[BATTLE]') # battle until one is dead - turnnum = 1 - while self.ourhero.isalive() and self.ourenemy.isalive() and self.ourhero.isbattling: - marqueeprint('[TURN ' + str(turnnum) + ']') + turn_num = 1 + while self.our_hero.is_alive() and self.our_enemy.is_alive() and self.our_hero.is_battling: + marqueeprint(f'[TURN {turn_num}]') self.battle() - turnnum += 1 - elif 70 < ourrand <= 90: + turn_num += 1 + elif 70 < our_rand <= 90: marqueeprint('[FOUND ITEM]') itemrand = random.randrange(0, 6) if itemrand == 0: - self.ourhero.ourarmor = self.ourhero.newarmor() - gridoutput(self.ourhero.ourarmor.datadict()) + self.our_hero.our_armor = self.our_hero.new_armor() + gridoutput(self.our_hero.our_armor.datadict()) elif itemrand == 1: - self.ourhero.ourweapon = self.ourhero.newweapon() - gridoutput(self.ourhero.ourweapon.datadict()) + self.our_hero.our_weapon = self.our_hero.new_weapon() + gridoutput(self.our_hero.our_weapon.datadict()) elif itemrand == 2: - self.ourhero.ourshield = self.ourhero.newshield() - gridoutput(self.ourhero.ourshield.datadict()) + self.our_hero.our_shield = self.our_hero.new_shield() + gridoutput(self.our_hero.our_shield.datadict()) elif 3 <= itemrand <= 6: - self.ourhero.ouritem = self.ourhero.newitem() - gridoutput(self.ourhero.ouritem.datadict()) - self.ourhero.items.append(self.ourhero.ouritem) - self.ourhero.applyequip() - elif 90 < ourrand <= 95: + self.our_hero.our_item = self.our_hero.new_item() + gridoutput(self.our_hero.our_item.datadict()) + self.our_hero.items.append(self.our_hero.our_item) + self.our_hero.apply_equip() + elif 90 < our_rand <= 95: marqueeprint('A LONE TRAVELER') centerprint('You find a lone traveler,') centerprint('He says:') print('\n') with open('./quoteslist.txt', 'rb') as f: - quotelist = f.read().splitlines() - quote = random.choice(quotelist) - quote = quote.decode('utf-8') - wrapstring = textwrap.wrap(quote, width=self.datawidth) - for line in wrapstring: + quote_list = f.read().splitlines() + quote = random.choice(quote_list).decode('utf-8') + for line in textwrap.wrap(quote, width=self.data_width): centerprint(line) print('\n') - threechoicerandom = random.randrange(0, 2) - if threechoicerandom == 0: - xpgain = int(self.ourhero.nextlevel * .10) - self.ourhero.addxp(int(round(xpgain, 1))) - if threechoicerandom == 1: - goldgain = int(self.ourhero.gold * .10) - self.ourhero.addgold(goldgain) - if threechoicerandom == 2: + three_choice_random = random.randrange(0, 2) + if three_choice_random == 0: + xp_gain = int(self.our_hero.next_level * .10) + self.our_hero.add_xp(int(round(xp_gain, 1))) + if three_choice_random == 1: + gold_gain = int(self.our_hero.gold * .10) + self.our_hero.add_gold(gold_gain) + if three_choice_random == 2: pass centerprint('...you venture back to camp') - elif 90 < ourrand <= 95: + elif 90 < our_rand <= 95: # a story event? centerprint('You find nothing and wander back to camp') pass - elif 95 < ourrand <= 100: + elif 95 < our_rand <= 100: self.riddle() elif m == 'c': self.camp() - if not self.ourhero.isalive(): + if not self.our_hero.is_alive(): return # One round of a battle def battle(self): - self.ourhero.battlecount += 1 - self.printadversaries(self.datawidth) + self.our_hero.battle_count += 1 + self.print_adversaries(self.data_width) marqueeprint('[CHOOSE ACTION]') centerprint('[a]tk [d]ef [r]un [i]tem') centerprint('Coinflip to [h]eal (100g)') centerprint('Action?') - nextmove = input() + next_move = input() # conditions to end battle - if self.ourhero.isalive(): - turnnotused = True - while turnnotused: - turnnotused = self.playerturn(nextmove) - #wait = input() - if self.ourenemy.isalive(): - self.enemyturn() - #wait = input() - if not self.ourhero.isalive(): - self.ourhero.death() - #wait = input() + if self.our_hero.is_alive(): + turn_not_used = True + while turn_not_used: + turn_not_used = self.player_turn(next_move) + # wait = input() + if self.our_enemy.isalive(): + self.enemy_turn() + # wait = input() + if not self.our_hero.is_alive(): + self.our_hero.death() + # wait = input() return - if not self.ourenemy.isalive(): - self.ourhero.isbattling = False - self.ourenemy.reset() + if not self.our_enemy.isalive(): + self.our_hero.is_battling = False + self.our_enemy.reset() marqueeprint('[VICTORY]') - self.ourhero.addgold(self.ourenemy.gold + (self.ourenemy.gold * self.ourhero.defcurve)) - self.ourhero.addxp(self.ourenemy.xp + (self.ourenemy.xp * self.ourhero.defcurve)) + self.our_hero.add_gold(self.our_enemy.gold + (self.our_enemy.gold * self.our_hero.def_curve)) + self.our_hero.add_xp(self.our_enemy.xp + (self.our_enemy.xp * self.our_hero.def_curve)) # 15% chance to get some health back. if random.randrange(0, 100) in range(0, 15): - self.ourhero.food() + self.our_hero.food() centerprint('Press [Enter] To continue') - wait = input() - if not self.ourhero.isbattling: + input() # Wait + if not self.our_hero.is_battling: return # One round of a player's turn - def playerturn(self, m): + def player_turn(self, m: str) -> Optional[bool]: # FixMe: This stinks and is a possible soft-lock # for health regen potion - if self.ourhero.regentimer > 0: - regen = int(self.ourhero.maxhp * .2) - self.ourhero.heal(regen) - self.ourhero.regentimer -= 1 + if self.our_hero.regen_timer > 0: + regen = int(self.our_hero.max_hp * .2) + self.our_hero.heal(regen) + self.our_hero.regen_timer -= 1 # for haste potion for 5 turn dodge increases - self.ourhero.dodge = self.ourhero.basedodge - if self.ourhero.hastetimer > 0: + self.our_hero.dodge = self.our_hero.base_dodge + if self.our_hero.haste_timer > 0: centerprint('Your dodge chance is elevated') - self.ourhero.hastetimer -= 1 + self.our_hero.haste_timer -= 1 else: - self.ourhero.dodge = self.ourhero.basedodge - self.ourhero.applyequip() + self.our_hero.dodge = self.our_hero.base_dodge + self.our_hero.apply_equip() marqueeprint('[HERO TURN]') crit = 0 - critrand = random.randrange(0, 100) - if critrand in range(self.ourhero.crit, critrand): - crit = self.ourhero.atk * .4 - effatk = int(self.ourhero.atk + crit) - if effatk < 0: - effatk = 0 + crit_rand = random.randrange(0, 100) + if crit_rand in range(self.our_hero.crit, crit_rand): + crit = self.our_hero.atk * .4 + eff_atk = int(self.our_hero.atk + crit) + if eff_atk < 0: + eff_atk = 0 if m == 'a' or m == '': - if critrand == 0: + if crit_rand == 0: centerprint('CRITICAL HIT!') - self.ourenemy.damage(effatk + crit, self.ourhero.atkcurve) - self.ourhero.ourweapon.damagedur(effatk + crit, self.ourhero.defcurve) - if self.ourenemy.hp < 0: - self.ourenemy.hp = 0 - self.ourhero.isbattling = False + self.our_enemy.damage(eff_atk + crit, self.our_hero.atk_curve) + self.our_hero.our_weapon.damagedur(eff_atk + crit, self.our_hero.def_curve) + if self.our_enemy.hp < 0: + self.our_enemy.hp = 0 + self.our_hero.is_battling = False return False elif m == 'd': marqueeprint('[DEFENSE]') - self.ourhero.defn += self.ourhero.defn * self.ourhero.defcurve + self.our_hero.defn += self.our_hero.defn * self.our_hero.def_curve return False elif m == 'r': marqueeprint('[RUN ATTEMPT]') rand = random.randrange(0, 4) if rand == 0: centerprint('you ran away') - self.ourhero.isbattling = False + self.our_hero.is_battling = False else: centerprint('you can\'t run!') return False elif m == 'i': - itemnotchosen = True - while itemnotchosen: - itemnotchosen = self.item_management() + item_not_chosen = True + while item_not_chosen: + item_not_chosen = self.item_management() return False elif m == 'h': - self.ourhero.healflip() - wait = input() + self.our_hero.heal_flip() + input() # Wait # One round of an enemy turn - def enemyturn(self): + def enemy_turn(self) -> None: overunder = random.randrange(0, 20) - if self.ourenemy.isalive: + if self.our_enemy.isalive: marqueeprint('[ENEMY ATTACK]') if overunder == 0: - self.ourenemy.anger() + self.our_enemy.anger() elif overunder == 1: - self.ourenemy.weaker() + self.our_enemy.weaker() elif overunder == 2: - centerprint(str(self.ourenemy.name) + ' ran away!') - self.ourenemy.hp = 0 - self.ourhero.isbattling = False + centerprint(str(self.our_enemy.name) + ' ran away!') + self.our_enemy.hp = 0 + self.our_hero.is_battling = False return - if overunder in range(3, self.ourhero.dodge): - centerprint(str(self.ourenemy.name) + ' swings and misses!') + if overunder in range(3, self.our_hero.dodge): + centerprint(str(self.our_enemy.name) + ' swings and misses!') return - if self.ourhero.isbattling: - effatk = int(self.ourenemy.atk) - if effatk < 0: - effatk = 0 - self.ourhero.ourarmor.damagedur(effatk, self.ourhero.defcurve) - self.ourhero.ourshield.damagedur(effatk, self.ourhero.defcurve) - self.ourhero.damage(effatk) - - def riddle(self): + if self.our_hero.is_battling: + eff_atk = int(self.our_enemy.atk) + if eff_atk < 0: + eff_atk = 0 + self.our_hero.our_armor.damage_dur(eff_atk, self.our_hero.def_curve) + self.our_hero.our_shield.damage_dur(eff_atk, self.our_hero.def_curve) + self.our_hero.damage(eff_atk) + + def riddle(self) -> None: marqueeprint('[RIDDLE]') centerprint('The area gets quiet. The wind blows.') centerprint('A torn page lands in your grasp. It reads:') @@ -332,61 +326,60 @@ def riddle(self): # query database for a single random riddle self.conn.execute('SELECT * FROM riddles ORDER BY RANDOM() LIMIT 1' + ';') row = self.conn.fetchall()[0] - ourriddle = [row[0], row[1]] - wrapstring = textwrap.wrap(ourriddle[0], width=self.datawidth) - answer = str(ourriddle[1]).lower() - for line in wrapstring: + our_riddle = [row[0], row[1]] + wrap_string = textwrap.wrap(our_riddle[0], width=self.data_width) + answer = str(our_riddle[1]).lower() + for line in wrap_string: centerprint(line) centerprint('Speak the answer to the wind...') - useranswer = input() - if useranswer == '' and self.riddlemode == 1: - while useranswer == '': + user_answer = input() + if user_answer == '' and self.riddle_mode == 1: + while user_answer == '': centerprint('Please answer the riddle.') - useranswer = input() + user_answer = input() if self.debugging: - marqueeprint(answer + ', you cheater!') - if similarstring(useranswer, answer) and useranswer != '': + marqueeprint(f'{answer}, you cheater!') + if similarstring(user_answer, answer) and user_answer != '': centerprint('You have successfully answered the riddle') centerprint('The answer was \"' + answer + '\"') centerprint('I present you with this:') - self.ourhero.addgold(self.ourhero.level * 44) - self.ourhero.addxp(self.ourhero.nextlevel * .17) + self.our_hero.add_gold(self.our_hero.level * 44) + self.our_hero.add_xp(self.our_hero.next_level * .17) else: centerprint('You Fail! Leave this place!') - # fetch a new enemy that is at hero's level (for now...) - def getenemy(self): - self.conn.execute('SELECT * FROM enemies WHERE level = ' + str(self.ourhero.level) + ';') + def get_enemy(self) -> Enemy: + self.conn.execute('SELECT * FROM enemies WHERE level = ' + str(self.our_hero.level) + ';') rows = self.conn.fetchall() new_enemy = random.choice(rows) # create random enemy name - levelname = random.choice((rows[0][1], rows[1][1], - rows[2][1], rows[3][1], - rows[4][1])) + level_name = random.choice((rows[0][1], rows[1][1], + rows[2][1], rows[3][1], + rows[4][1])) # part of random name adjective = random.choice((rows[0][2], rows[1][2], rows[2][2], rows[3][2], rows[4][2])) # part of random name - enemyname = random.choice((rows[0][3], rows[1][3], - rows[2][3], rows[3][3], - rows[4][3])) + enemy_name = random.choice((rows[0][3], rows[1][3], + rows[2][3], rows[3][3], + rows[4][3])) # part of random name - ournewenemy = Enemy.Enemy(new_enemy[0], levelname, adjective, enemyname, new_enemy[4], - new_enemy[5], (new_enemy[6] + (new_enemy[6] * self.ourhero.defcurve)), - new_enemy[7], new_enemy[8], new_enemy[9]) - return ournewenemy + our_new_enemy = Enemy.Enemy(new_enemy[0], level_name, adjective, enemy_name, new_enemy[4], + new_enemy[5], (new_enemy[6] + (new_enemy[6] * self.our_hero.def_curve)), + new_enemy[7], new_enemy[8], new_enemy[9]) + return our_new_enemy # a blacksmith who can repair or sell gear def blacksmith(self): centerprint('An old Blacksmith rests at your camp') centerprint('He shows his wares and services:') centerprint('[f]ix gear [b]uy gear') - nextdecision = input() - centerprint('Gold: ' + str(self.ourhero.gold)) - if nextdecision == 'f': + next_decision = input() + centerprint('Gold: ' + str(self.our_hero.gold)) + if next_decision == 'f': # offer equipment repair for any of the 3 slots, for 1g/durability point centerprint('The Blacksmith can offer repair ') @@ -394,71 +387,71 @@ def blacksmith(self): centerprint('Here is your gear durability:') # print all your gear out - gridoutput(self.ourhero.ourweapon.datadict()) - gridoutput(self.ourhero.ourshield.datadict()) - gridoutput(self.ourhero.ourarmor.datadict()) + gridoutput(self.our_hero.ourweapon.datadict()) + gridoutput(self.our_hero.ourshield.datadict()) + gridoutput(self.our_hero.ourarmor.datadict()) # user input for what to repair, or all of it, for convenience decision = input('What do you want to repair? [a] for all') if decision == '1' or decision == 'a': - repaircost = self.ourhero.ourweapon.maxdur - self.ourhero.ourweapon.dur + repair_cost = self.our_hero.ourweapon.maxdur - self.our_hero.ourweapon.dur centerprint('Repair Your weapon?') - centerprint('Cost: ' + str(repaircost) + ' gold') + centerprint(f'Cost: {repair_cost} gold') centerprint('[y]es [n]o') decision2 = input() - if decision2 == 'y' and self.ourhero.gold >= repaircost: - self.ourhero.gold -= repaircost - self.ourhero.ourweapon.dur = self.ourhero.ourweapon.maxdur + if decision2 == 'y' and self.our_hero.gold >= repair_cost: + self.our_hero.gold -= repair_cost + self.our_hero.ourweapon.dur = self.our_hero.ourweapon.maxdur centerprint('Repair Success.') if decision == '2' or decision == 'a': - repaircost = self.ourhero.ourshield.maxdur - self.ourhero.ourshield.dur + repair_cost = self.our_hero.ourshield.max_dur - self.our_hero.ourshield.dur centerprint('Repair Your shield?') - centerprint('Cost: ' + str(repaircost) + ' gold') + centerprint(f'Cost: {repair_cost} gold') centerprint('[y]es [n]o') decision2 = input() - if decision2 == 'y' and self.ourhero.gold >= repaircost: - self.ourhero.gold -= repaircost - self.ourhero.ourshield.dur = self.ourhero.ourshield.maxdur + if decision2 == 'y' and self.our_hero.gold >= repair_cost: + self.our_hero.gold -= repair_cost + self.our_hero.ourshield.dur = self.our_hero.ourshield.max_dur centerprint('Repair Success.') if decision == '3' or decision == 'a': - repaircost = self.ourhero.ourarmor.maxdur - self.ourhero.ourarmor.dur + repair_cost = self.our_hero.ourarmor.max_dur - self.our_hero.ourarmor.dur centerprint('Repair Your armor?)') - centerprint('Cost: ' + str(repaircost) + ' gold') + centerprint(f'Cost: {repair_cost} gold') centerprint('[y]es [n]o') decision2 = input() - if decision2 == 'y' and self.ourhero.gold >= repaircost: - self.ourhero.gold -= repaircost - self.ourhero.ourarmor.dur = self.ourhero.ourarmor.maxdur + if decision2 == 'y' and self.our_hero.gold >= repair_cost: + self.our_hero.gold -= repair_cost + self.our_hero.ourarmor.dur = self.our_hero.ourarmor.max_dur centerprint('Repair Success') # offer random choice of weapon, armor, or shield at 1.5x value price - elif nextdecision == 'b': - weaponforsale = self.ourhero.newweapon() - armorforsale = self.ourhero.newarmor() - shieldforsale = self.ourhero.newshield() + elif next_decision == 'b': + weapon_for_sale = self.our_hero.new_weapon() + armor_for_sale = self.our_hero.new_armor() + shield_for_sale = self.our_hero.new_shield() marqueeprint('[YOUR GEAR]') - gridoutput(self.ourhero.ourweapon.datadict()) - gridoutput(self.ourhero.ourshield.datadict()) - gridoutput(self.ourhero.ourarmor.datadict()) + gridoutput(self.our_hero.ourweapon.datadict()) + gridoutput(self.our_hero.ourshield.datadict()) + gridoutput(self.our_hero.ourarmor.datadict()) print('') # determine weapon costs - wepcost = weaponforsale.level * 60 * self.ourhero.defcurve - armcost = armorforsale.level * 60 * self.ourhero.defcurve - shcost = shieldforsale.level * 60 * self.ourhero.defcurve + wepcost = weapon_for_sale.level * 60 * self.our_hero.def_curve + armcost = armor_for_sale.level * 60 * self.our_hero.def_curve + shcost = shield_for_sale.level * 60 * self.our_hero.def_curve - data1 = [str(weaponforsale.name), str(weaponforsale.type), - str(weaponforsale.baseatk), + data1 = [str(weapon_for_sale.name), str(weapon_for_sale.type), + str(weapon_for_sale.baseatk), str(wepcost)] - data2 = [str(shieldforsale.name), str(shieldforsale.type), - str(shieldforsale.basedefn), + data2 = [str(shield_for_sale.name), str(shield_for_sale.type), + str(shield_for_sale.base_defn), str(shcost)] - data3 = [str(armorforsale.name), str(armorforsale.type), - str(armorforsale.basedefn), + data3 = [str(armor_for_sale.name), str(armor_for_sale.type), + str(armor_for_sale.base_defn), str(armcost)] - title = ('[GEAR FOR SALE]') + title = '[GEAR FOR SALE]' dataheader = ['Name', 'Type', 'Atk/Def', 'Cost'] alldata = [data1, data2, data3] fiverowprintoptions(dataheader, alldata, title) @@ -468,35 +461,35 @@ def blacksmith(self): if itemindex not in ['1', '2', '3', '']: centerprint('Please enter a valid choice') elif itemindex == '1': - self.ourhero.ourweapon = weaponforsale - if self.ourhero.gold < wepcost: + self.our_hero.ourweapon = weapon_for_sale + if self.our_hero.gold < wepcost: centerprint('You don\'t have enough money!') - self.ourhero.gold -= wepcost - centerprint('You equip your new gear: ' + str(weaponforsale.name) + ' ' + str(weaponforsale.type)) + self.our_hero.gold -= wepcost + centerprint('You equip your new gear: ' + str(weapon_for_sale.name) + ' ' + str(weapon_for_sale.type)) elif itemindex == '2': - self.ourhero.ourshield = shieldforsale - if self.ourhero.gold < wepcost: + self.our_hero.ourshield = shield_for_sale + if self.our_hero.gold < wepcost: centerprint('You don\'t have enough money!') return - self.ourhero.gold -= armcost - centerprint('You equip your new gear: ' + str(shieldforsale.name) + ' ' + str(shieldforsale.type)) + self.our_hero.gold -= armcost + centerprint('You equip your new gear: ' + str(shield_for_sale.name) + ' ' + str(shield_for_sale.type)) elif itemindex == '3': - self.ourhero.ourarmor = armorforsale - if self.ourhero.gold < shcost: + self.our_hero.ourarmor = armor_for_sale + if self.our_hero.gold < shcost: centerprint('You don\'t have enough money!') return - self.ourhero.gold -= shcost - centerprint('You equip your new gear: ' + str(armorforsale.name) + ' ' + str(armorforsale.type)) - self.ourhero.applyequip() + self.our_hero.gold -= shcost + centerprint('You equip your new gear: ' + str(armor_for_sale.name) + ' ' + str(armor_for_sale.type)) + self.our_hero.apply_equip() return # a camp where you regain hp after so many fights. def camp(self): camping = True while camping: - self.ourhero.hp = self.ourhero.maxhp + self.our_hero.hp = self.our_hero.max_hp marqueeprint('[CAMP]') - centerprint('You rest at camp. Hero HP: ' + str(self.ourhero.hp)) + centerprint('You rest at camp. Hero HP: ' + str(self.our_hero.hp)) centerprint('[a]dventure [i]tem [h]ero') centerprint('[p]eddler [b]lacksmith') centerprint('[l]oad [s]ave [q]uit') @@ -507,20 +500,20 @@ def camp(self): iteming = self.item_management() elif m == 'h': marqueeprint('[HERO DETAIL]') - gridoutput(self.ourhero.datadict()) - wait = input() - gridoutput(self.ourhero.ourweapon.datadict()) - wait = input() - gridoutput(self.ourhero.ourshield.datadict()) - wait = input() - gridoutput(self.ourhero.ourarmor.datadict()) - wait = input() + gridoutput(self.our_hero.datadict()) + input() # Wait + gridoutput(self.our_hero.our_weapon.datadict()) + input() # Wait + gridoutput(self.our_hero.our_shield.datadict()) + input() # Wait + gridoutput(self.our_hero.our_armor.datadict()) + input() # Wait elif m == 'a' or m == '': return # adventure() elif m == 'l': marqueeprint('[LOAD GAME]') - self.ourhero = self.loadgame() + self.our_hero = self.load_game() elif m == 's': marqueeprint('[SAVE GAME]') self.savegame() @@ -546,26 +539,26 @@ def peddler(self): nextdecision = input() if nextdecision == 'b': pass - item1 = self.ourhero.newitem() - item2 = self.ourhero.newitem() - item3 = self.ourhero.newitem() - item4 = self.ourhero.newitem() - item5 = self.ourhero.newitem() + item1 = self.our_hero.new_item() + item2 = self.our_hero.new_item() + item3 = self.our_hero.new_item() + item4 = self.our_hero.new_item() + item5 = self.our_hero.new_item() itemarray = [item1, item2, item3, item4, item5] for i, item in enumerate(itemarray): print(str(i + 1) + '\t' + item.name + '\t' + str(item.val * 1.5)) print('Your selection? (ENTER to go back)') selection = input() if selection == '1': - self.ourhero.buyitem(item1) + self.our_hero.buy_item(item1) elif selection == '2': - self.ourhero.buyitem(item2) + self.our_hero.buy_item(item2) elif selection == '3': - self.ourhero.buyitem(item3) + self.our_hero.buy_item(item3) elif selection == '4': - self.ourhero.buyitem(item4) + self.our_hero.buy_item(item4) elif selection == '5': - self.ourhero.buyitem(item5) + self.our_hero.buy_item(item5) elif selection == '': centerprint('\"WHYD YOU COME HERE AND NOT BUY ANYTHING?\"') return @@ -573,12 +566,13 @@ def peddler(self): centerprint('Get out of here you bum!') # offer random choice of items at 1.5x value price if nextdecision == 'r': - if self.ourhero.canafford(100): - self.ourhero.gold -= 100 + if self.our_hero.can_afford(100): + self.our_hero.gold -= 100 self.riddle() # pickle in to hero obj and start gameloop - def loadgame(self): + @staticmethod + def load_game(): # load hero object from pickle file dirlist = os.listdir('./saves/') for i, item in enumerate(dirlist): @@ -599,133 +593,131 @@ def loadgame(self): def savegame(self): # pickle hero object to file # should prompt to overwrite - heroname = input('Name your save file\nOr [c]ancel') - if heroname == 'c': + hero_name = input('Name your save file\nOr [c]ancel') + if hero_name == 'c': return - savefolder = "./saves/" - filepath = savefolder + heroname + '.hero' - gamedata = self.ourhero + save_directory = "./saves/" + filepath = save_directory + hero_name + '.hero' + game_data = self.our_hero if not os.path.isfile(filepath): with open(filepath, 'wb') as f: - pickle.dump(gamedata, f, -1) + pickle.dump(game_data, f, -1) else: answer = input('Overwrite?') if answer.lower() == 'y': os.remove(filepath) print(os.listdir('./saves/')) with open(filepath, 'wb') as f: - pickle.dump(gamedata, f, -1) + pickle.dump(game_data, f, -1) elif answer.lower() == 'n': newname = input('Enter New Save file name') with open(filepath + str(newname), 'wb') as f: - pickle.dump(gamedata, f, -1) + pickle.dump(game_data, f, -1) # TODO: Go back from item menu without enemy turn happening # TODO: Make this into an item selection method, with an argument if [s]elling, [u]sing, or [d]iscarding # lets hero use items def item_management(self): - if not self.ourhero.items: + if not self.our_hero.items: centerprint('Inventory Empty') return False # print all the item's info - for i, item in enumerate(self.ourhero.items): - leftprint('ITEM: ' + str(i+1)) - gridoutput(self.ourhero.items[i].datadict()) + for i, item in enumerate(self.our_hero.items): + leftprint('ITEM: ' + str(i + 1)) + gridoutput(self.our_hero.items[i].datadict()) centerprint('Please enter decision, [ENTER] to go back') try: itemindex = input() itemindex = int(itemindex) itemindex -= 1 - self.ourhero.ouritem = self.ourhero.items[int(itemindex)] - del (self.ourhero.items[int(itemindex)]) + self.our_hero.ouritem = self.our_hero.items[int(itemindex)] + del (self.our_hero.items[int(itemindex)]) except ValueError: centerprint('Please enter a valid choice') return False except IndexError: centerprint('Please enter a valid choice') return False - self.ourhero.activeitem = self.ourhero.ouritem - centerprint('Using ' + str(self.ourhero.ouritem.name)) - if self.ourhero.ouritem.name == 'Healing Potion': - self.healingpotion() - if self.ourhero.ouritem.name == 'Explosive Mana Vial': - if self.ourhero.isbattling: - self.explosivemanavial() + self.our_hero.activeitem = self.our_hero.ouritem + centerprint('Using ' + str(self.our_hero.ouritem.name)) + if self.our_hero.ouritem.name == 'Healing Potion': + self.healing_potion() + if self.our_hero.ouritem.name == 'Explosive Mana Vial': + if self.our_hero.is_battling: + self.explosive_mana_vial() else: centerprint('You\'re not in battle!') return False - if self.ourhero.ouritem.name == 'Health Regen Potion': - self.healthregenpotion() - if self.ourhero.ouritem.name == 'Haste Potion': - self.hastepotion() - if self.ourhero.ouritem.name == 'Weapon Repair Tincture': - self.weaponrepairtincture() + if self.our_hero.ouritem.name == 'Health Regen Potion': + self.health_regen_potion() + if self.our_hero.ouritem.name == 'Haste Potion': + self.haste_potion() + if self.our_hero.ouritem.name == 'Weapon Repair Tincture': + self.weapon_repair_tincture() # hero uses a healing potion - def healingpotion(self): + def healing_potion(self): marqueeprint('[HEALING POTION]') - healed = self.ourhero.activeitem.effect - self.ourhero.heal(healed) - self.ourhero.activeitem = 0 - + healed = self.our_hero.active_item.effect + self.our_hero.heal(healed) + self.our_hero.active_item = 0 # hero uses an item that damages enemy - def explosivemanavial(self): + def explosive_mana_vial(self): marqueeprint('[EXPLOSIVE MANA BOMB]') centerprint('The Mana Vial EXPLODES!') - dmg = self.ourhero.activeitem.effect - self.ourenemy.damage(dmg, self.ourhero.atkcurve) - self.ourhero.activeitem = 0 - + dmg = self.our_hero.active_item.effect + self.our_enemy.damage(dmg, self.our_hero.atk_curve) + self.our_hero.active_item = 0 # adds health per turn - def healthregenpotion(self): + def health_regen_potion(self): marqueeprint('[REGEN POTION]') - self.ourhero.regentimer += 5 - centerprint(str(self.ourhero.regentimer) + ' turns health regen') - self.ourhero.activeitem = 0 + self.our_hero.regen_timer += 5 + centerprint(str(self.our_hero.regen_timer) + ' turns health regen') + self.our_hero.active_item = 0 # dodge buff - def hastepotion(self): + def haste_potion(self): marqueeprint('[HASTE POTION]') - self.ourhero.hastetimer += 5 - centerprint(str(self.ourhero.hastetimer) + ' turns dodge buff') - self.ourhero.activeitem = 0 + self.our_hero.haste_timer += 5 + centerprint(str(self.our_hero.haste_timer) + ' turns dodge buff') + self.our_hero.active_item = 0 # heals 60% of dur points to weapon - def weaponrepairtincture(self): + def weapon_repair_tincture(self): marqueeprint('[WEAPON REPAIR]') - rep = self.ourhero.ourweapon.maxdur * .6 + rep = self.our_hero.our_weapon.maxdur * .6 centerprint('You repaired your weapon for ' + str(rep) + ' durability points') - self.ourhero.ourweapon.dur += rep - if self.ourhero.ourweapon.dur > self.ourhero.ourweapon.maxdur: - self.ourhero.ourweapon.dur = self.ourhero.ourweapon.maxdur - self.ourhero.activeitem = 0 + self.our_hero.our_weapon.dur += rep + if self.our_hero.our_weapon.dur > self.our_hero.our_weapon.maxdur: + self.our_hero.our_weapon.dur = self.our_hero.our_weapon.maxdur + self.our_hero.active_item = 0 # adds a little suspense to offset the monotony of text input - def suspense(self): + def suspense(self) -> None: s = ' ' - if self.suspensemode: + if self.suspense_mode: time.sleep(.5) print(s) # Print hero and enemy justified on left and right - def printadversaries(self, datawidth): - self.textwidth = datawidth - centerprint(lr_justify('[HERO]', '[ENEMY]', self.textwidth)) - centerprint(lr_justify(self.ourhero.name, self.ourenemy.name, self.textwidth)) - centerprint(lr_justify(str('lvl: ' + str(self.ourhero.level)), - str('lvl: ' + str(self.ourenemy.level)),self.textwidth)) - centerprint(lr_justify(str('HP: ' + str(self.ourhero.hp) + '/' + str(self.ourhero.maxhp)), - str('HP: ' + str(self.ourenemy.hp) + '/' + str(self.ourenemy.maxhp)), self.textwidth)) - centerprint(lr_justify(str('XP: ' + str(self.ourhero.xp) + '/' + str(self.ourhero.nextlevel)), - str('XP drop: ' + str(self.ourenemy.xp)),self.textwidth)) + def print_adversaries(self, datawidth): + self.text_width = datawidth + centerprint(lr_justify('[HERO]', '[ENEMY]', self.text_width)) + centerprint(lr_justify(self.our_hero.name, self.our_enemy.name, self.text_width)) + centerprint(lr_justify(str('lvl: ' + str(self.our_hero.level)), + str('lvl: ' + str(self.our_enemy.level)), self.text_width)) + centerprint(lr_justify(str('HP: ' + str(self.our_hero.hp) + '/' + str(self.our_hero.max_hp)), + str('HP: ' + str(self.our_enemy.hp) + '/' + str(self.our_enemy.maxhp)), self.text_width)) + centerprint(lr_justify(str('XP: ' + str(self.our_hero.xp) + '/' + str(self.our_hero.next_level)), + str('XP drop: ' + str(self.our_enemy.xp)), self.text_width)) # To be used on status screens def printmarqueehero(self, sometext): marqueeprint(sometext) - print(lr_justify('[HERO]', '', self.textwidth)) - print(lr_justify(self.ourhero.name, '', self.textwidth)) - print(lr_justify(str('lvl: ' + str(self.ourhero.level)), '', self.textwidth)) - print(lr_justify(str('HP: ' + str(self.ourhero.hp) + '/' + str(self.ourhero.maxhp)), '', self.textwidth)) - print(lr_justify(str('XP: ' + str(self.ourhero.xp) + '/' + str(self.ourhero.nextlevel)), '', self.textwidth)) + print(lr_justify('[HERO]', '', self.text_width)) + print(lr_justify(self.our_hero.name, '', self.text_width)) + print(lr_justify(f'lvl: {self.our_hero.level}', '', self.text_width)) + print(lr_justify(f'HP: {self.our_hero.hp} / {self.our_hero.max_hp}', '', self.text_width)) + print(lr_justify(f'XP: {self.our_hero.xp} / {self.our_hero.next_level}', '', self.text_width)) diff --git a/Hero.py b/Hero.py index 7edf557..c0e85ae 100644 --- a/Hero.py +++ b/Hero.py @@ -1,154 +1,164 @@ import random +from enum import Enum +from typing import Union -import Armor -import Game -import Item -import Shield -import Weapon -import dbsetup +from Item import Item +from Shield import Shield +from Weapon import Weapon +from Database import Database from texttools import * +from Armor import Armor + + +class HeroClass(Enum): + HUNTER = 'hunter' + MAGE = 'mage' + WARRIOR = 'warrior' class Hero: - def __init__(self, heroclass, herolevel, herohp, heroatk, herodefn, heronextlevel, herododge): + def __init__(self, + hero_class: HeroClass, + hero_level: int, + hero_hp: int, + hero_atk: int, + hero_defn: int, + hero_next_level: int, + hero_dodge: int): # name - self.name = '' + self.name: str = '' # instance vars - self.ourclass = heroclass - self.level = herolevel - self.nextlevel = heronextlevel + self.our_class: HeroClass = hero_class + self.level: int = hero_level + self.next_level: int = hero_next_level # HP - self.maxhp = herohp - self.hp = self.maxhp + self.max_hp: int = hero_hp + self.hp: int = self.max_hp # Attack - self.baseatk = heroatk - self.atk = self.baseatk + self.base_atk: int = hero_atk + self.atk: int = self.base_atk # Defense - self.basedef = herodefn - self.defn = self.basedef + self.base_def: int = hero_defn + self.defn: int = self.base_def # Dodge - self.basedodge = herododge - self.dodge = self.basedodge + self.base_dodge: int = hero_dodge + self.dodge: int = self.base_dodge # Luck - self.baseluck = 0 - self.luck = self.baseluck + self.base_luck: int = 0 + self.luck: int = self.base_luck # Crit - self.basecrit = 5 - self.crit = self.basecrit + self.base_crit: int = 5 + self.crit: int = self.base_crit # game-created vars - self.gold = 0 - self.xp = 0 + self.gold: int = 0 + self.xp: Union[int, float] = 0 # Augmentations for hero classes - self.hpaug = 0 - self.dodgeaug = 0 - self.defaug = 0 - self.atkaug = 0 - self.levelupaug = 0 - self.critaug = 0 + self.hp_aug: int = 0 + self.dodge_aug: int = 0 + self.def_aug: int = 0 + self.atk_aug: int = 0 + self.levelup_aug: int = 0 + self.crit_aug: int = 0 # Items container and usage - self.items = [] - self.activeitem = 0 + self.items: list = [] + self.active_item = 0 # Gear container - self.gear = [] + self.gear: list = [] # Keep track of battle count - self.battlecount = 0 + self.battle_count: int = 0 # Used for regen and haste potions - self.regentimer = 0 - self.hastetimer = 0 + self.regen_timer: int = 0 + self.haste_timer: int = 0 # A difficulty curve for determining lots of things - self.atkcurve = 0 - self.defcurve = 0 + self.atk_curve: float = 0 + self.def_curve: float = 0 # equip objects - self.ourweapon = Weapon.Weapon(0, 'training', 'wooden', 'stick', 3, 20, 'none') - self.ourarmor = Armor.Armor(0, 'training', 'broken', 'plate', 2, 10) - self.ourshield = Shield.Shield(0, 'training', 'wooden', 'ward', 3, 20) - self.ouritem = Item.Item(0, 0, 0, 0, 0) - self.isbattling = False + self.our_weapon: Weapon = Weapon(0, 'training', 'wooden', 'stick', 3, 20, 'none') + self.our_armor: Armor = Armor(0, 'training', 'broken', 'plate', 2, 10) + self.our_shield: Shield = Shield(0, 'training', 'wooden', 'ward', 3, 20) + self.our_item: Item = Item(0, 0, 0, 0, 0) + self.is_battling: bool = False - # width of centered data in screencenter - self.datawidth = 40 + # width of centered data in screen center + self.data_width: int = 40 # Heals user up to max health - def heal(self, hpup): - centerprint('You heal for ' + str(int(hpup)) + ' HP') - print('') - self.hp += hpup - if self.hp > self.maxhp: - self.hp = self.maxhp + def heal(self, hp_up: int) -> None: + centerprint(f'You heal for {hp_up} HP\n') + self.hp += hp_up + if self.hp > self.max_hp: + self.hp = self.max_hp # flip a coin, pay 100g, 1/2 chance of regaining health - def healflip(self): + def heal_flip(self) -> None: marqueeprint('[HEAL FLIP]') centerprint('Death appears to flip a coin with you.') if self.gold >= 100: self.gold -= 100 - newrand = random.randrange(0, 1) - if newrand == 0: - self.heal(self.maxhp) + if random.choice([True, False]): + self.heal(self.max_hp) marqueeprint('[HEAL SUCCESS]') - centerprint(str(self.maxhp) + ' healed') - else: - marqueeprint('HEAL FAILED You lost the roll!') - else: - marqueeprint('[HEAL FAILED]') - centerprint('You don\'t have enough money!') + centerprint(str(self.max_hp) + ' healed') + return + marqueeprint('HEAL FAILED You lost the roll!') + return + marqueeprint('[HEAL FAILED]') + centerprint('You don\'t have enough money!') # sometimes you find food after a fight - def food(self): - hpback = int(self.maxhp * .2) - centerprint('You found some food and healed ' + str(hpback) + ' HP.') - self.heal(hpback) + def food(self) -> None: + hp_back = int(self.max_hp * .2) + centerprint(f'You found some food and healed {hp_back} HP.') + self.heal(hp_back) # take damage - def damage(self, hpdown): - effatk = hpdown + (hpdown * self.defcurve) - self.hp -= int(effatk) - centerprint(str(self.name) + ' takes ' + str(int(effatk)) + ' damage!') - if self.hp < 0: - self.hp = 0 + def damage(self, hp_down: int) -> None: + eff_atk = hp_down + (hp_down * self.def_curve) + self.hp -= int(eff_atk) + centerprint(f'{self.name} takes {eff_atk} damage!') + self.hp = 0 if self.hp < 0 else self.hp # kills the character - def death(self): - self.isbattling = False + def death(self) -> None: + self.is_battling = False self.hp = 0 marqueeprint('') marqueeprint('[GAME OVER]') - marqueeprint('') - print('') + marqueeprint('\n') gridoutput(self.datadict()) # adds XP to character, and levels up if it goes over - def addxp(self, gainedxp): - gainedxp = gainedxp + (gainedxp * self.defcurve) - centerprint('You gained ' + str(int(gainedxp)) + ' Exp') - self.xp += int(gainedxp) - if self.xp >= self.nextlevel: - self.levelup() + def add_xp(self, gained_xp: float) -> None: + gained_xp = gained_xp + (gained_xp * self.def_curve) + centerprint(f'You gained {gained_xp} Exp') + self.xp += gained_xp + if self.xp >= self.next_level: + self.level_up() # adds gold to character - def addgold(self, gainedgold): - gainedgold = gainedgold + (gainedgold * self.defcurve) - centerprint('You gained ' + str(int(gainedgold + (gainedgold * self.defcurve))) + ' Gold') - self.gold += int(gainedgold + (gainedgold * self.defcurve)) + def add_gold(self, gained_gold: int) -> None: + gained_gold = gained_gold + (gained_gold * self.def_curve) + centerprint(f'You gained {str(int(gained_gold + (gained_gold * self.def_curve)))} Gold') + self.gold += int(gained_gold + (gained_gold * self.def_curve)) # attempt to buy an item - def buyitem(self, item): - if self.canafford(item.val): + def buy_item(self, item: Item) -> None: + if self.can_afford(item.val): self.gold -= item.val self.items.append(item) print('You bought ' + item.name) @@ -156,172 +166,166 @@ def buyitem(self, item): print('You can\'t afford that!') # see if you can afford an item - def canafford(self, val): - if self.gold >= val: - return True - else: - return False + def can_afford(self, val: int) -> bool: + return self.gold >= val # alive check - def isalive(self): - if self.hp > 0: - return True - else: - return False + def is_alive(self) -> bool: + return self.hp > 0 # applies hero's perks - def heroperks(self): - if self.ourclass == 'warrior': + def hero_perks(self) -> None: + if self.our_class == HeroClass.WARRIOR: # more HP - self.hpaug = 15 + self.hp_aug = 15 # slower - self.dodgeaug = 2 + self.dodge_aug = 2 # more def - self.defaug = 12 + self.def_aug = 12 # low atk - self.atkaug = 2 + self.atk_aug = 2 # doofus is a slow leveler - self.levelupaug = 1 + self.levelup_aug = 1 # mild crit chance boost - self.critaug = 2 - elif self.ourclass == 'mage': + self.crit_aug = 2 + elif self.our_class == HeroClass.MAGE: # glass cannon - self.hpaug = 5 + self.hp_aug = 5 # med dodge - self.dodgeaug = 5 + self.dodge_aug = 5 # low DEF - self.defaug = 6 + self.def_aug = 6 # lower atk - self.atkaug = 12 + self.atk_aug = 12 # smarter, levels up quicker - self.levelupaug = .6 + self.levelup_aug = .6 # mild crit chance boost - self.critaug = 2 - elif self.ourclass == 'hunter': + self.crit_aug = 2 + elif self.our_class == HeroClass.HUNTER: # med health - self.hpaug = 10 + self.hp_aug = 10 # high dodge - self.dodgeaug = 8 + self.dodge_aug = 8 # med DEF - self.defaug = 8 + self.def_aug = 8 # def ATK - self.atkaug = 6 + self.atk_aug = 6 # he gets by - self.levelupaug = .8 + self.levelup_aug = .8 # high crit chance boost - self.critaug = 6 - self.maxhp += self.hpaug - self.hp += self.hpaug - self.dodge += self.dodgeaug - self.basedef += self.defaug - self.defn += self.defaug - self.nextlevel = int(self.nextlevel * self.levelupaug) - self.baseatk += self.atkaug - self.atk += self.atkaug + self.crit_aug = 6 + self.max_hp += self.hp_aug + self.hp += self.hp_aug + self.dodge += self.dodge_aug + self.base_def += self.def_aug + self.defn += self.def_aug + self.next_level = int(self.next_level * self.levelup_aug) + self.base_atk += self.atk_aug + self.atk += self.atk_aug # prints all hero stat info - def printheroinfodetail(self): + def print_hero_info_detail(self) -> None: marqueeprint('[HERO DATA]') - centerprint(Game.lr_justify('Class:', str(self.ourclass), self.datawidth)) - centerprint(Game.lr_justify('Name:', str(self.name), self.datawidth)) - centerprint(Game.lr_justify('Level:', str(self.level), self.datawidth)) - centerprint(Game.lr_justify('XP:', str(self.xp) + '/' + str(self.nextlevel), self.datawidth)) - centerprint(Game.lr_justify('HP:', str(self.hp) + '/' + str(self.maxhp), self.datawidth)) - centerprint(Game.lr_justify('Gold:', str(self.gold), self.datawidth)) - centerprint(Game.lr_justify('Atk:', str(self.atk), self.datawidth)) - centerprint(Game.lr_justify('Defense:', str(self.defn), self.datawidth)) - centerprint(Game.lr_justify('Dodge:', str(self.dodge), self.datawidth)) - centerprint(Game.lr_justify('battles fought', str(self.battlecount), self.datawidth)) + centerprint(lr_justify('Class:', str(self.our_class), self.data_width)) + centerprint(lr_justify('Name:', str(self.name), self.data_width)) + centerprint(lr_justify('Level:', str(self.level), self.data_width)) + centerprint(lr_justify('XP:', str(self.xp) + '/' + str(self.next_level), self.data_width)) + centerprint(lr_justify('HP:', str(self.hp) + '/' + str(self.max_hp), self.data_width)) + centerprint(lr_justify('Gold:', str(self.gold), self.data_width)) + centerprint(lr_justify('Atk:', str(self.atk), self.data_width)) + centerprint(lr_justify('Defense:', str(self.defn), self.data_width)) + centerprint(lr_justify('Dodge:', str(self.dodge), self.data_width)) + centerprint(lr_justify('battles fought', str(self.battle_count), self.data_width)) print('') # returns a dictionary of relevant user data for printing and delivering class information in a package - def datadict(self): + def datadict(self) -> dict: return { - 'Class': str(self.ourclass), + 'Class': str(self.our_class), 'Name': str(self.name), 'Level': str(self.level), - 'XP': str(str(self.xp) + '/' + str(self.nextlevel)), - 'HP': str(str(self.hp) + '/' + str(self.maxhp)), + 'XP': str(str(self.xp) + '/' + str(self.next_level)), + 'HP': str(str(self.hp) + '/' + str(self.max_hp)), 'Gold': str(self.gold), 'Atk': str(self.atk), 'Def': str(self.defn), 'Dodge': str(self.dodge), - 'battles': str(self.battlecount) + 'battles': str(self.battle_count) } # levels up hero - def levelup(self): - newdb = dbsetup.dbsetup() + def level_up(self) -> None: + new_db = Database() marqueeprint('[LEVEL UP]') - self.xp -= self.nextlevel + self.xp -= self.next_level self.level += 1 if self.level > 15: centerprint('MAX LEVEL! YOU WIN!') centerprint('THANKS FOR PLAYING') gridoutput(self.datadict()) quit() - newdb.conn.execute('SELECT * FROM levelnotes WHERE level = ' + str(self.level) + ';') - rows = newdb.conn.fetchall() - newdb.conn.close() + new_db.conn.execute('SELECT * FROM levelnotes WHERE level = ' + str(self.level) + ';') + rows = new_db.conn.fetchall() + new_db.conn.close() new_hero_data = rows[0] - self.maxhp = int(new_hero_data[1] + self.hpaug) - self.hp = self.maxhp - self.baseatk = int(new_hero_data[2] + self.atkaug) - self.atk = self.baseatk - self.basedef = int(new_hero_data[3] + self.defaug) - self.defn = self.basedef - self.nextlevel += int(new_hero_data[4] * self.levelupaug) - self.dodge = int(new_hero_data[5] + self.dodgeaug) - self.basecrit += self.critaug + self.max_hp = int(new_hero_data[1] + self.hp_aug) + self.hp = self.max_hp + self.base_atk = int(new_hero_data[2] + self.atk_aug) + self.atk = self.base_atk + self.base_def = int(new_hero_data[3] + self.def_aug) + self.defn = self.base_def + self.next_level += int(new_hero_data[4] * self.levelup_aug) + self.dodge = int(new_hero_data[5] + self.dodge_aug) + self.base_crit += self.crit_aug gridoutput(self.datadict()) # fetches a new weapon for hero - def newweapon(self): - newdb = dbsetup.dbsetup() - newdb.conn.execute('SELECT * FROM weapons WHERE "level" = ? AND "class" = ? ;', - (str(self.level), str(self.ourclass),)) - rows = newdb.conn.fetchall() - newdb.conn.close() + def new_weapon(self) -> Weapon: + new_db = Database() + new_db.conn.execute('SELECT * FROM weapons WHERE "level" = ? AND "class" = ? ;', + (str(self.level), str(self.our_class),)) + rows = new_db.conn.fetchall() + new_db.conn.close() new_weapon_data = rows[0] - ournewweapon = Weapon.Weapon(new_weapon_data[0], new_weapon_data[1], new_weapon_data[2], new_weapon_data[3], - new_weapon_data[4], new_weapon_data[5], new_weapon_data[6]) - return ournewweapon + our_new_weapon = Weapon(new_weapon_data[0], new_weapon_data[1], new_weapon_data[2], new_weapon_data[3], + new_weapon_data[4], new_weapon_data[5], new_weapon_data[6]) + return our_new_weapon # fetches a new armor for hero - def newarmor(self): - newdb = dbsetup.dbsetup() - newdb.conn.execute('SELECT * FROM armor WHERE "level" = ? AND "class" = ? ;', - (str(self.level), str(self.ourclass),)) - rows = newdb.conn.fetchall() - newdb.conn.close() + def new_armor(self) -> Armor: + new_db = Database() + new_db.conn.execute('SELECT * FROM armor WHERE "level" = ? AND "class" = ? ;', + (str(self.level), str(self.our_class),)) + rows = new_db.conn.fetchall() + new_db.conn.close() new_armor_data = rows[0] - ournewarmor = Armor.Armor(new_armor_data[0], new_armor_data[1], new_armor_data[2], new_armor_data[3], - new_armor_data[4], new_armor_data[5]) - return ournewarmor + our_new_armor = Armor(new_armor_data[0], new_armor_data[1], new_armor_data[2], new_armor_data[3], + new_armor_data[4], new_armor_data[5]) + return our_new_armor # fetches a new shield for hero - def newshield(self): - newdb = dbsetup.dbsetup() - newdb.conn.execute('SELECT * FROM shields WHERE "level" = ? AND "class" = ? ;', - (str(self.level), str(self.ourclass),)) - rows = newdb.conn.fetchall() - newdb.conn.close() + def new_shield(self) -> Shield: + new_db = Database() + new_db.conn.execute('SELECT * FROM shields WHERE "level" = ? AND "class" = ? ;', + (str(self.level), str(self.our_class),)) + rows = new_db.conn.fetchall() + new_db.conn.close() new_shield_data = rows[0] - ournewshield = Shield.Shield(new_shield_data[0], new_shield_data[1], new_shield_data[2], new_shield_data[3], - new_shield_data[4], new_shield_data[5]) - return ournewshield + our_new_shield = Shield(new_shield_data[0], new_shield_data[1], new_shield_data[2], new_shield_data[3], + new_shield_data[4], new_shield_data[5]) + return our_new_shield # fetches a new item for hero - def newitem(self): - newdb = dbsetup.dbsetup() - newdb.conn.execute('SELECT * FROM items WHERE "level" = ? ;', (self.level,)) - rows = newdb.conn.fetchall() - newdb.conn.close() + def new_item(self) -> Item: + new_db = Database() + new_db.conn.execute('SELECT * FROM items WHERE "level" = ? ;', (self.level,)) + rows = new_db.conn.fetchall() + new_db.conn.close() new_item_data = random.choice(rows) - ournewitem = Item.Item(new_item_data[0], new_item_data[1], new_item_data[2], new_item_data[3], new_item_data[4]) - return ournewitem + our_new_item = Item(new_item_data[0], new_item_data[1], new_item_data[2], new_item_data[3], new_item_data[4]) + return our_new_item - # re-equips all gear. Usually called when setting something like self.ourarmor = Armor.Armor(*args) - def applyequip(self): - self.atk = int(self.baseatk + self.ourweapon.baseatk) - self.defn = int(self.basedef + self.ourarmor.defn + self.ourshield.defn) + # re-equips all gear. Usually called when setting something like self.our_armor = Armor.Armor(*args) + def apply_equip(self) -> None: + self.atk = int(self.base_atk + self.our_weapon.baseatk) + self.defn = int(self.base_def + self.our_armor.defn + self.our_shield.defn) diff --git a/Item.py b/Item.py index 7627d8f..f9c58a5 100644 --- a/Item.py +++ b/Item.py @@ -1,26 +1,43 @@ +from enum import Enum + from texttools import * +class ItemGrade(Enum): + WEAK = 'weak' + MINOR = 'minor' + STANDARD = 'standard' + SATISFYING = 'satisfying' + EXCESSIVE = 'excessive' + ABOVE_AVERAGE = 'above average' + PURE = '100% pure' + + class Item: # grade,name,effect,value - def __init__(self, itemlevel, itemgrade, itemname, itemeffect, itemvalue): - self.level = itemlevel - self.grade = itemgrade - self.name = itemname - self.effect = itemeffect - self.val = itemvalue + def __init__(self, + item_level: int, + item_grade: ItemGrade, + item_name: str, + item_effect: int, + item_value: int): + self.level: int = item_level + self.grade: ItemGrade = item_grade + self.name: str = item_name + self.effect: int = item_effect + self.val: int = item_value # prints all item stats - def printiteminfo(self): + def print_item_info(self) -> None: marqueeprint('Item: ') print(lr_justify('Level:', str(self.level), 60)) print(lr_justify('Grade:', str(self.grade), 60)) - print(lr_justify('Name:', str(self.name), 60)) + print(lr_justify('Name:', self.name, 60)) print(lr_justify('Effect Val:', str(self.effect), 60)) print(lr_justify('Gold Val:', str(self.val), 60)) # ['Level', 'Quality', 'Name', 'Effect'] - def datadict(self): + def datadict(self) -> dict: return {'Level': str(self.level), 'Name': str(self.grade) + ' ' + str(self.name), 'Effect': str(self.effect), diff --git a/Shield.py b/Shield.py index 13bf337..5a23c4f 100644 --- a/Shield.py +++ b/Shield.py @@ -1,115 +1,130 @@ -import Game +from enum import Enum import random +from texttools import * + + +class ShieldType(Enum): + WARD = 'ward' + SHIELD = 'shield' + BUCKLER = 'buckler' + + +class ShieldQuality(Enum): + RUSTY = 'rusty' + COMMON = 'common' + GREAT = 'great' + MAGICAL = 'magical' + LEGENDARY = 'legendary' # TODO: Make shield, armor, weapon all have similar repair methods. +# TIP (from @DavidRodenkirchen): Make abstract base class for all of these and implement those methods there class Shield: - # level,class,name,type,basedef,durability - def __init__(self, shieldlevel, shieldclass, shieldname, shieldtype, shieldbasedefn, shielddur): + # level,class,name,type,base_def,durability + def __init__(self, + shield_level: int, + shield_class: str, + shield_name: str, + shield_type: ShieldType, + shield_base_defn: int, + shield_dur: int): # shield level - self.level = shieldlevel + self.level: int = shield_level # shield hero class type - self.ourshieldclass = shieldclass + self.our_shield_class: str = shield_class # shield name - self.name = shieldname + self.name: str = shield_name # shield type - self.type = shieldtype + self.type: ShieldType = shield_type + + self.base_defn = shield_base_defn # Shield Quality (rusty, common, great, magical, legendary) chance = random.randint(1, 100) if chance < 20: - self.quality = 'Rusty' + self.quality = ShieldQuality.RUSTY + self.base_defn = int(self.base_defn * 0.9) elif chance >= 21 or chance < 65: - self.quality = 'Common' + self.quality = ShieldQuality.COMMON + self.base_defn = int(self.base_defn * 1) elif chance >= 66 or chance < 86: - self.quality = 'Great' + self.quality = ShieldQuality.GREAT + self.base_defn = int(self.base_defn * 1.25) elif chance >= 85 or chance < 96: - self.quality = 'Magical' + self.quality = ShieldQuality.MAGICAL + self.base_defn = int(self.base_defn * 1.6) elif chance >= 96 or chance < 100: - self.quality = 'Legendary' - - # Defense Values - self.basedefn = shieldbasedefn - if self.quality == 'Rusty': - self.basedefn = int(self.basedefn * 0.9) - elif self.quality == 'Common': - self.basedefn = int(self.basedefn * 1) - elif self.quality == 'Great': - self.basedefn = int(self.basedefn * 1.25) - elif self.quality == 'Magical': - self.basedefn = int(self.basedefn * 1.6) - elif self.quality == 'Legendary': - self.basedefn = int(self.basedefn * 2) - - self.defn = self.basedefn + self.quality = ShieldQuality.LEGENDARY + self.base_defn = int(self.base_defn * 2) + + self.defn = self.base_defn # shield durability value - self.maxdur = shielddur - if self.quality == 'Rusty': - self.maxdur = int(self.maxdur * 0.9) - elif self.quality == 'Common': - self.maxdur = int(self.maxdur * 1) - elif self.quality == 'Great': - self.maxdur = int(self.maxdur * 1.25) - elif self.quality == 'Magical': - self.maxdur = int(self.maxdur * 1.6) - elif self.quality == 'Legendary': - self.maxdur = int(self.maxdur * 2) - self.dur = self.maxdur + self.max_dur = shield_dur + if self.quality == ShieldQuality.RUSTY: + self.max_dur = int(self.max_dur * 0.9) + elif self.quality == ShieldQuality.COMMON: + self.max_dur = int(self.max_dur * 1) + elif self.quality == ShieldQuality.GREAT: + self.max_dur = int(self.max_dur * 1.25) + elif self.quality == ShieldQuality.MAGICAL: + self.max_dur = int(self.max_dur * 1.6) + elif self.quality == ShieldQuality.LEGENDARY: + self.max_dur = int(self.max_dur * 2) + self.dur = self.max_dur # damage durability, and check to see if broken - def damagedur(self, aug, curve): + def damage_dur(self, aug: int, curve: float) -> None: self.dur -= int(aug * curve) - self.isbroken() - pass + self.is_broken() # restore dur and check to see if fixed - def restoredur(self, aug): + def restore_dur(self, aug: int) -> None: self.dur += aug - if self.dur > self.maxdur: - self.dur = self.maxdur - if not self.isbroken(): - self.defn = self.basedefn + if self.dur > self.max_dur: + self.dur = self.max_dur + if not self.is_broken(): + self.defn = self.base_defn # repair entirely - def repair(self): - self.defn = self.basedefn - self.dur = self.maxdur + def repair(self) -> None: + self.defn = self.base_defn + self.dur = self.max_dur # 15% durability = stat reduction - def isbroken(self): + def is_broken(self) -> bool: if self.dur <= 0: - self.gearbreak() + self.gear_break() return True - elif self.dur > 0: - return False + return False # this breaks the gear - def gearbreak(self): - self.atk = int(self.basedefn * .3) + def gear_break(self) -> None: + # Possible FixMe: self.atk seems to serve no purpose + self.atk = int(self.base_defn * .3) # prints all info about the shield - def printshieldinfo(self): - Game.marqueeprint('SHIELD') - print(Game.lr_justify('Level:', str(self.level), 60)) - print(Game.lr_justify('Name:', str(self.name), 60)) - print(Game.lr_justify('Type:', str(self.type), 60)) - print(Game.lr_justify('Defense:', str(self.defn) + '/' + str(self.basedefn), 60)) - print(Game.lr_justify('Dur:', str(self.dur) + '/' + str(self.maxdur), 60)) - print(Game.lr_justify('Broken?:', str(self.isbroken()), 60)) - print(Game.lr_justify('Quality:', str(self.quality), 60)) + def print_shield_info(self) -> None: + marqueeprint('SHIELD') + print(lr_justify('Level:', str(self.level), 60)) + print(lr_justify('Name:', self.name, 60)) + print(lr_justify('Type:', str(self.type), 60)) + print(lr_justify('Defense:', f'{self.defn} / {self.base_defn}', 60)) + print(lr_justify('Dur:', f'{self.dur} / {self.max_dur}', 60)) + print(lr_justify('Broken?:', 'Yes' if self.is_broken() else 'No', 60)) + print(lr_justify('Quality:', str(self.quality), 60)) # ['Level', 'Name', 'Defense', 'Dur', 'Broken?', 'Power'] - def datadict(self): + def datadict(self) -> dict: return {'Level': str(self.level), 'Name': str(self.name) + ' ' + str(self.type), 'Def': str(self.defn), - 'Dur': str(self.dur) + '/' + str(self.maxdur), - 'Broken?': str(self.isbroken()), - 'Repair Cost': str(self.maxdur - self.dur) + ' gold', + 'Dur': str(self.dur) + '/' + str(self.max_dur), + 'Broken?': str(self.is_broken()), + 'Repair Cost': f'{str(self.max_dur - self.dur)} + gold', 'Quality': str(self.quality) } diff --git a/__init__.py b/__init__.py index 4cdf482..be63bd8 100644 --- a/__init__.py +++ b/__init__.py @@ -2,4 +2,4 @@ if __name__ == '__main__': ourgame = Game.Game() - ourgame.gameloop() + ourgame.game_loop() From 46526acc27e9f99adbb62e087fea1dd355b52590 Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Tue, 24 May 2022 12:45:05 +0200 Subject: [PATCH 3/3] remove enum dependency --- Armor.py | 5 ++--- Game.py | 8 ++++---- Hero.py | 3 +-- Item.py | 4 +--- Shield.py | 5 ++--- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Armor.py b/Armor.py index 261e0a5..3a79c1c 100644 --- a/Armor.py +++ b/Armor.py @@ -1,15 +1,14 @@ import random -from enum import Enum from texttools import * -class ArmorType(Enum): +class ArmorType: OUTFIT = 'outfit' PLATE = 'plate' ROBE = 'robe' -class ArmorQuality(Enum): +class ArmorQuality: RUSTY = 'rusty' COMMON = 'common' GREAT = 'great' diff --git a/Game.py b/Game.py index 7e29b34..ff65414 100644 --- a/Game.py +++ b/Game.py @@ -218,14 +218,14 @@ def battle(self): while turn_not_used: turn_not_used = self.player_turn(next_move) # wait = input() - if self.our_enemy.isalive(): + if self.our_enemy.is_alive(): self.enemy_turn() # wait = input() if not self.our_hero.is_alive(): self.our_hero.death() # wait = input() return - if not self.our_enemy.isalive(): + if not self.our_enemy.is_alive(): self.our_hero.is_battling = False self.our_enemy.reset() marqueeprint('[VICTORY]') @@ -296,7 +296,7 @@ def player_turn(self, m: str) -> Optional[bool]: # FixMe: This stinks and is a # One round of an enemy turn def enemy_turn(self) -> None: overunder = random.randrange(0, 20) - if self.our_enemy.isalive: + if self.our_enemy.is_alive: marqueeprint('[ENEMY ATTACK]') if overunder == 0: self.our_enemy.anger() @@ -709,7 +709,7 @@ def print_adversaries(self, datawidth): centerprint(lr_justify(str('lvl: ' + str(self.our_hero.level)), str('lvl: ' + str(self.our_enemy.level)), self.text_width)) centerprint(lr_justify(str('HP: ' + str(self.our_hero.hp) + '/' + str(self.our_hero.max_hp)), - str('HP: ' + str(self.our_enemy.hp) + '/' + str(self.our_enemy.maxhp)), self.text_width)) + str('HP: ' + str(self.our_enemy.hp) + '/' + str(self.our_enemy.max_hp)), self.text_width)) centerprint(lr_justify(str('XP: ' + str(self.our_hero.xp) + '/' + str(self.our_hero.next_level)), str('XP drop: ' + str(self.our_enemy.xp)), self.text_width)) diff --git a/Hero.py b/Hero.py index c0e85ae..18ceada 100644 --- a/Hero.py +++ b/Hero.py @@ -1,5 +1,4 @@ import random -from enum import Enum from typing import Union from Item import Item @@ -10,7 +9,7 @@ from Armor import Armor -class HeroClass(Enum): +class HeroClass: HUNTER = 'hunter' MAGE = 'mage' WARRIOR = 'warrior' diff --git a/Item.py b/Item.py index f9c58a5..b803389 100644 --- a/Item.py +++ b/Item.py @@ -1,9 +1,7 @@ -from enum import Enum - from texttools import * -class ItemGrade(Enum): +class ItemGrade: WEAK = 'weak' MINOR = 'minor' STANDARD = 'standard' diff --git a/Shield.py b/Shield.py index 5a23c4f..988e45b 100644 --- a/Shield.py +++ b/Shield.py @@ -1,15 +1,14 @@ -from enum import Enum import random from texttools import * -class ShieldType(Enum): +class ShieldType: WARD = 'ward' SHIELD = 'shield' BUCKLER = 'buckler' -class ShieldQuality(Enum): +class ShieldQuality: RUSTY = 'rusty' COMMON = 'common' GREAT = 'great'