cleaning templates, getting levels are party counts cached properly
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,9 +10,9 @@ def roll_dice(count, sides):
|
|||||||
|
|
||||||
# Player Character Classes
|
# Player Character Classes
|
||||||
class Adventurer:
|
class Adventurer:
|
||||||
def __init__(self, c_id: int, level=1, attributes={}) -> None:
|
def __init__(self, c_id: str, level=1, attributes={}) -> None:
|
||||||
# using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get
|
# using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get
|
||||||
self.id = c_id
|
self.identifier = c_id
|
||||||
self.player_class = None
|
self.player_class = None
|
||||||
self.level = level
|
self.level = level
|
||||||
self.strength = attributes.get('strength', roll_dice(3,6))
|
self.strength = attributes.get('strength', roll_dice(3,6))
|
||||||
@@ -117,6 +117,10 @@ class Adventurer:
|
|||||||
spell_book.append(random_spell)
|
spell_book.append(random_spell)
|
||||||
return spell_book
|
return spell_book
|
||||||
|
|
||||||
|
def set_level(self, new_level):
|
||||||
|
self.level = new_level
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Fighter(Adventurer):
|
class Fighter(Adventurer):
|
||||||
adv_class = "fighter"
|
adv_class = "fighter"
|
||||||
|
|||||||
72
app.py
72
app.py
@@ -19,39 +19,73 @@ def index():
|
|||||||
|
|
||||||
@app.route('/party', methods = ["GET","POST"])
|
@app.route('/party', methods = ["GET","POST"])
|
||||||
def party():
|
def party():
|
||||||
|
stored_adv_party = []
|
||||||
|
stored_count = None
|
||||||
|
stored_level = None
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
count = request.args.get("count", default=4, type=int)
|
count = request.args.get("count", default=4, type=int)
|
||||||
level = request.args.get("level", default=1, type=int)
|
level = request.args.get("level", default=1, type=int)
|
||||||
|
cache = request.args.get("cache", default='true', type=str)
|
||||||
adv_party = returnParty(count, level)
|
adv_party = returnParty(count, level)
|
||||||
resp = make_response(render_template("party_sheet.html", adv_party=adv_party, count=count, level=level))
|
# check for cookies present
|
||||||
|
if request.cookies:
|
||||||
|
print('there are cookies')
|
||||||
|
stored_count = len(request.cookies)
|
||||||
|
#print(request.cookies)
|
||||||
|
for c in request.cookies:
|
||||||
|
if c.startswith('adv'):
|
||||||
|
cookie_encoded = request.cookies[c]
|
||||||
|
cookie_compressed = base64.urlsafe_b64decode(cookie_encoded)
|
||||||
|
character_dict = json.loads(zlib.decompress(cookie_compressed).decode())
|
||||||
|
new_char = createCharacterWithDict(character_dict)
|
||||||
|
stored_level = new_char.level
|
||||||
|
stored_adv_party.append(new_char)
|
||||||
|
# if request arguments match the adventure party count & level stored in the cookies, just use the cookies
|
||||||
|
if cache == 'true':
|
||||||
|
print('caching is true')
|
||||||
|
if level != stored_level:
|
||||||
|
print(f'change party level to {level}')
|
||||||
|
for adv in stored_adv_party:
|
||||||
|
print('...editing')
|
||||||
|
adv.set_level(level)
|
||||||
|
print(adv.level)
|
||||||
|
if count == stored_count:
|
||||||
|
print('counts and levels are the same')
|
||||||
|
adv_party.set_party(stored_adv_party, count, level)
|
||||||
|
if count > stored_count:
|
||||||
|
print('extend the party!')
|
||||||
|
extension = count - stored_count
|
||||||
|
more_party_members = returnParty(extension,level).adventurers
|
||||||
|
extended_party = stored_adv_party + more_party_members
|
||||||
|
adv_party.set_party(extended_party, count, level)
|
||||||
|
if count < stored_count:
|
||||||
|
print('reduce the party!')
|
||||||
|
reduction = count - stored_count
|
||||||
|
reduced_party = stored_adv_party[:reduction]
|
||||||
|
adv_party.set_party(reduced_party, count, level)
|
||||||
|
|
||||||
|
|
||||||
|
# generate page
|
||||||
|
response = make_response(render_template("party_sheet.html", adv_party=adv_party, count=count, level=level, cache=cache))
|
||||||
# make a cookie for each character
|
# make a cookie for each character
|
||||||
# this took a while to figure out, json alone was too large, b64 encoded json was too large, but it turns out you can compress json as a cookie
|
# this took a while to figure out, json was too large, b64 encoded json was too large, but it turns out you can compress json as a cookie
|
||||||
for character in adv_party.adventurers:
|
for character in adv_party.adventurers:
|
||||||
cookie_string = str(character.id)
|
cookie_string = character.identifier
|
||||||
char_json = json.dumps(character.get_json())
|
char_json = json.dumps(character.get_json())
|
||||||
compressed = zlib.compress(char_json.encode())
|
compressed = zlib.compress(char_json.encode())
|
||||||
cookie_data = base64.urlsafe_b64encode(compressed).decode()
|
cookie_data = base64.urlsafe_b64encode(compressed).decode()
|
||||||
resp.set_cookie(cookie_string, cookie_data)
|
response.set_cookie(cookie_string, cookie_data)
|
||||||
return resp
|
return response
|
||||||
# return render_template("party_sheet.html", adv_party=adv_party, count=count, level=level)
|
|
||||||
|
|
||||||
@app.route('/character', methods = ["GET","POST"])
|
@app.route('/character', methods = ["GET","POST"])
|
||||||
def characters():
|
def characters():
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
c_id = str(request.args.get("id", default=0, type=int))
|
c_id = str(request.args.get("id", default=0, type=str))
|
||||||
|
if request.cookies and c_id:
|
||||||
cookie_encoded = request.cookies[c_id]
|
cookie_encoded = request.cookies[c_id]
|
||||||
cookie_compressed = base64.urlsafe_b64decode(cookie_encoded)
|
cookie_compressed = base64.urlsafe_b64decode(cookie_encoded)
|
||||||
character_dict = json.loads(zlib.decompress(cookie_compressed).decode())
|
character_dict = json.loads(zlib.decompress(cookie_compressed).decode())
|
||||||
chosen_class = character_dict['player_class']
|
new_char = createCharacterWithDict(character_dict)
|
||||||
c_id = character_dict['id']
|
else:
|
||||||
level = character_dict['level']
|
new_char = Adventurer(1,1)
|
||||||
adv_dict = Adventurer.get_subclass_dict()
|
|
||||||
chosen_class = adv_dict[chosen_class]
|
|
||||||
# note, i wonder if i can find a way to use the dict in a one liner, like from hw1
|
|
||||||
# makes a new character of the correct player class
|
|
||||||
new_char = chosen_class(c_id=c_id, level=level)
|
|
||||||
# loads in all the values from the dict
|
|
||||||
for k, v in character_dict.items():
|
|
||||||
# https://realpython.com/ref/builtin-functions/setattr/
|
|
||||||
setattr(new_char,k, v)
|
|
||||||
return render_template("character.html", character=new_char)
|
return render_template("character.html", character=new_char)
|
||||||
|
|||||||
37
main.py
37
main.py
@@ -43,27 +43,33 @@ class ClassSelector():
|
|||||||
|
|
||||||
class PartyGenerator():
|
class PartyGenerator():
|
||||||
def __init__(self, party_size: int, party_level: int) -> None:
|
def __init__(self, party_size: int, party_level: int) -> None:
|
||||||
self.size = party_size
|
|
||||||
self.size = party_size
|
self.size = party_size
|
||||||
self.level = party_level
|
self.level = party_level
|
||||||
self.adventurers = []
|
self.adventurers = []
|
||||||
self.adventurer_types = []
|
self.adventurer_types = []
|
||||||
|
|
||||||
def gen_party(self):
|
def gen_party(self):
|
||||||
c_id = 0
|
c_id = 1
|
||||||
while len(self.adventurers) < self.size:
|
while len(self.adventurers) < self.size:
|
||||||
c_id += 1
|
identifier = "adv-" + str(c_id)
|
||||||
new_player = Adventurer(c_id, self.level)
|
new_player = Adventurer(identifier, self.level)
|
||||||
attempts = 0
|
attempts = 0
|
||||||
while new_player.player_class not in self.adventurer_types:
|
while new_player.player_class not in self.adventurer_types:
|
||||||
attempts += 1
|
attempts += 1
|
||||||
selected_class = ClassSelector(new_player).selection()
|
selected_class = ClassSelector(new_player).selection()
|
||||||
new_player = selected_class(new_player.id, new_player.level, new_player.get_attributes())
|
new_player = selected_class(new_player.identifier, new_player.level, new_player.get_attributes())
|
||||||
# i couldnt randomly generate a scenario where a character couldn't be added, but it seems possible, so this is the hard cut off
|
# i couldnt randomly generate a scenario where a character couldn't be added, but it seems possible, so this is the hard cut off
|
||||||
if (new_player.player_class not in self.adventurer_types) or (attempts > 10):
|
if (new_player.player_class not in self.adventurer_types) or (attempts > 10):
|
||||||
|
c_id += 1
|
||||||
self.adventurers.append(new_player)
|
self.adventurers.append(new_player)
|
||||||
self.adventurer_types.append(new_player.player_class)
|
self.adventurer_types.append(new_player.player_class)
|
||||||
|
|
||||||
|
def set_party(self, adventurers, count, level):
|
||||||
|
self.size = count
|
||||||
|
self.level = level
|
||||||
|
self.adventurers = adventurers
|
||||||
|
self.adventurer_types = []
|
||||||
|
|
||||||
def get_character_sheets(self):
|
def get_character_sheets(self):
|
||||||
sheet_string = ""
|
sheet_string = ""
|
||||||
character_sheets = []
|
character_sheets = []
|
||||||
@@ -94,22 +100,31 @@ def returnParty(party_size, party_level):
|
|||||||
# return the created adventurer party
|
# return the created adventurer party
|
||||||
return new_party
|
return new_party
|
||||||
|
|
||||||
def returnCharacter(c_id):
|
def returnCharacter(identifer):
|
||||||
for adv in new_party.adventurers:
|
for adv in new_party.adventurers:
|
||||||
if adv.id == c_id:
|
if adv.identifier == identifier:
|
||||||
return adv
|
return adv
|
||||||
|
|
||||||
|
def createCharacterWithDict(character_dict):
|
||||||
|
chosen_class = character_dict['player_class']
|
||||||
|
c_id = character_dict['identifier']
|
||||||
|
level = character_dict['level']
|
||||||
|
adv_dict = Adventurer.get_subclass_dict()
|
||||||
|
chosen_class = adv_dict[chosen_class]
|
||||||
|
new_char = chosen_class(c_id=c_id, level=level)
|
||||||
|
for k, v in character_dict.items():
|
||||||
|
setattr(new_char,k, v)
|
||||||
|
return new_char
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
adventurer_party = returnParty(party_size=2, party_level=2)
|
adventurer_party = returnParty(party_size=2, party_level=2)
|
||||||
for adv in adventurer_party.adventurers:
|
for adv in adventurer_party.adventurers:
|
||||||
print(adv.adv_class)
|
print(adv.adv_class)
|
||||||
adv_dict = Adventurer.get_subclass_dict()
|
adv_dict = Adventurer.get_subclass_dict()
|
||||||
test_class = adv_dict['fighter']
|
test_class = adv_dict['fighter']
|
||||||
new_char = test_class(c_id=1,level=1)
|
new_char = test_class(c_id="adv-1",level=1)
|
||||||
print(new_char.adv_class)
|
print(new_char.adv_class)
|
||||||
# for line in adv.vertical_sheet:
|
|
||||||
# print(f"{line}")
|
|
||||||
# print()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
|
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
|
||||||
@@ -23,18 +22,14 @@
|
|||||||
|
|
||||||
<div id="navbarBasicExample" class="navbar-menu">
|
<div id="navbarBasicExample" class="navbar-menu">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
<a class="navbar-item">
|
<a class="navbar-item" href="party?cache=true">
|
||||||
Characters
|
Generate Adventurer Party
|
||||||
</a>
|
</a>
|
||||||
|
<a class="navbar-item" href="character">
|
||||||
<a class="navbar-item">
|
Generate Single Adventurer
|
||||||
VTT
|
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<div id="navbarBasicExample" class="navbar-menu">
|
<div id="navbarBasicExample" class="navbar-menu">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
<a class="navbar-item" href="party">
|
<a class="navbar-item" href="party?cache=true">
|
||||||
Generate Adventurer Party
|
Generate Adventurer Party
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
@@ -23,18 +23,14 @@
|
|||||||
|
|
||||||
<div id="navbarBasicExample" class="navbar-menu">
|
<div id="navbarBasicExample" class="navbar-menu">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
<a class="navbar-item">
|
<a class="navbar-item" href="party?cache=true">
|
||||||
Characters
|
Generate Adventurer Party
|
||||||
</a>
|
</a>
|
||||||
|
<a class="navbar-item" href="character">
|
||||||
<a class="navbar-item">
|
Generate Single Adventurer
|
||||||
VTT
|
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -46,39 +42,51 @@
|
|||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column" >
|
<div class="column" >
|
||||||
<p>How many party members? {{count}}</p>
|
<p>How many party members?</p>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
{%for i in range(2,6)%}
|
{%for i in range(2,6)%}
|
||||||
{% if count|int() == i|int() %}
|
{% if count|int() == i|int() %}
|
||||||
<a class="button is-primary" href="{{ '/party?count={}&level={}'.format(i,level) }}">{{i}}</a>
|
<a class="button is-primary" href="{{ '/party?count={}&level={}&cache={}'.format(i,level,cache) }}">{{i}}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="button" href="{{ '/party?count={}&level={}'.format(i,level) }}">{{i}}</a>
|
<a class="button" href="{{ '/party?count={}&level={}&cache={}'.format(i,level,cache) }}">{{i}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column" >
|
<div class="column" >
|
||||||
<p>What level for the party? {{level}} </p>
|
<p>What level for the party?</p>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
{%for j in range(1,6)%}
|
{%for j in range(1,6)%}
|
||||||
{% if level|int() == j|int() %}
|
{% if level|int() == j|int() %}
|
||||||
<a class="button is-primary" href="{{ '/party?count={}&level={}'.format(count,j) }}">{{j}}</a>
|
<a class="button is-primary" href="{{ '/party?count={}&level={}&cache={}'.format(count,j,cache) }}">{{j}}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="button" href="{{ '/party?count={}&level={}'.format(count,j) }}">{{j}}</a>
|
<a class="button" href="{{ '/party?count={}&level={}&cache={}'.format(count,j,cache) }}">{{j}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="column" >
|
||||||
|
<p>Change character preservation? {{cache}}</p>
|
||||||
|
<div class="buttons">
|
||||||
|
{% if cache == 'true' %}
|
||||||
|
<a class="button is-primary">are cached</a>
|
||||||
|
<a class="button is-danger is-outlined" href="{{ '/party?count={}&level={}&cache=false'.format(count,level) }}">not cached</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="button is-primary is-outlined" href="{{ '/party?count={}&level={}&cache=true'.format(count,level) }}">are cached</a>
|
||||||
|
<a class="button is-danger">not cached</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="block has-text-centered">
|
<div class="block has-text-centered">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
{%for character in adv_party.adventurers%}
|
{%for character in adv_party.adventurers%}
|
||||||
<div class="column" >
|
<div class="column" >
|
||||||
<div class="block has-text-centered">
|
|
||||||
<a class="button is-focused" href="{{ '/character?id={}'.format(character.id)}}">Select this {{character.player_class.title()}}</a>
|
|
||||||
</div>
|
|
||||||
<pre>{{character.vertical_sheet() | join("\n")}}</pre>
|
<pre>{{character.vertical_sheet() | join("\n")}}</pre>
|
||||||
|
<div class="block has-text-centered">
|
||||||
|
<a class="button is-focused" href="{{ '/character?id={}'.format(character.identifier)}}">Select this {{character.player_class.title()}}</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user