doors_chest1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""minigames for temple of doors: | |
opening a chest, guessing a number with hint system | |
using PySimpleGUI as GUI | |
""" | |
import PySimpleGUI as sg | |
import random | |
# graph window | |
WIDTH = 600 | |
HEIGHT = 50 | |
class Riddle: | |
storage = {} | |
number = 1 | |
def __init__(self, solution_list, hint_list, full_bonus=60, bounty=100): | |
self.number = Riddle.number | |
Riddle.storage[self.number] = self | |
Riddle.number += 1 | |
self.solutions = solution_list | |
self.solved = False | |
self.hints = hint_list # ( [[func_string, description_text, price in gold ],]) | |
self.full_bonus = full_bonus # max. time in seconds to solve this riddle, bonus gold is the remaining time left | |
self.bonus = full_bonus # current time left | |
self.bounty = bounty # how much gold you get for solving this riddle, independent of time spent | |
#self.visible_hints = [True if price == 0 else False for (func, text, price) in self.hints] # how many hints are already visible | |
self.wrong_answers = set() | |
self.wrong_answers.add("--type your guess here--") | |
# ----------- self-test ---------- | |
results = [] | |
# check all hints for all provided solutions | |
for solution in self.solutions: | |
results = self.test(solution) | |
if not all(results): # all: only True's in the iterable | |
print(f"self-test: riddle {self.number}: found error for solution {solution}!", results) | |
def history(self): | |
"""get big text of wrong answers""" | |
wrongs = list(self.wrong_answers) | |
wrongs.sort() | |
return "\n".join(wrongs) | |
def test(self, solution): | |
"""check if all hints are True for one provided solutions | |
returns a list of boolean values""" | |
all_results = [] | |
for (func_string, func_txt, price) in self.hints: | |
try: | |
result = eval(func_string)(str(solution)) | |
except: | |
result = False | |
all_results.append(result) | |
return all_results | |
def calculate_hint_list(self, solution): | |
results = self.test(solution) | |
t = [] | |
for i, (func_string, func_txt, price) in enumerate(self.hints): | |
if price == 0: | |
t.append([price, func_txt, results[i]]) | |
else: | |
t.append([price, "--you can buy this hint--", results[i]]) | |
return t | |
def get_riddle(riddle_number): | |
riddle = Riddle.storage[riddle_number] | |
window2["bonus"].update(f"{riddle.bonus:.1f}") | |
window2["riddle_number"].update(f"Bounty for riddle #{riddle_number}:") | |
window2["bounty"].update(f"{riddle.bounty}") | |
# TODO: actual bonus, hints etc. | |
if riddle_number > 1: | |
window2["previous riddle"].update(disabled=False) | |
if riddle_number < len(Riddle.storage): | |
window2["next riddle"].update(disabled=False) | |
return riddle | |
# ------------------ riddles ---------------- | |
# --------- create riddle number 1 ---------- | |
# hints: function-string, description, price in gold | |
# price of 0 means this hint is instantly visible | |
hints = [["""lambda x: len(x) == 3""", "the code has 3 chars", 0], | |
["""lambda x: x.isnumeric()""", "the code has only (decimalsystem) digits", 0], | |
["""lambda x: "4" in x""" , "there is at least one '4' in the code", 10], | |
["""lambda x: x[0]=='7'""", "the first char is x, where 5x -14 = 3x", 20], | |
["""lambda x: int(x[0])+int(x[1])+int(x[2])==16""", "the sum of all digits in the code is 16", 40], | |
] | |
solutions = [745,754] | |
Riddle(solution_list=solutions, hint_list = hints ) | |
# --------- create riddle number 2 ---------- | |
hints = [["""lambda x: len(x)>0""" , "it sails on the sea", 0], | |
["""lambda x: x.isalpha()""", "the code has only letters", 0], | |
["""lambda x: len(x) == 4""", "the code has 4 chars", 5], | |
["""lambda x: 'i' in x""", "the code conains an 'i'", 20], | |
] | |
solutions = ["ship"] | |
Riddle(solution_list=solutions, hint_list = hints ) | |
# -------- first gui: theme cooser -------------------------- | |
sg.theme(random.choice(sg.theme_list())) | |
# ---------------------- theme selector layout ------------- | |
layout1 = [ | |
[ | |
sg.Text("Select theme:"), | |
sg.Combo( | |
values=sg.theme_list(), | |
default_value=sg.theme(), | |
enable_events=True, | |
key="selector", | |
), | |
], | |
[sg.Button("play the game")], | |
] | |
window1 = sg.Window("theme selector", layout1) | |
# ---------------- main loop for first layout --------------- | |
while True: | |
event1, values1 = window1.read() | |
if event1 == "play the game" or event1 == sg.WIN_CLOSED: | |
# sg.theme("DarkBlue3") | |
break | |
if event1 == "selector": | |
old = sg.theme() | |
sg.theme(values1["selector"]) | |
if sg.PopupYesNo("do you like this Theme?") == "Yes": | |
break | |
else: | |
sg.theme(old) | |
window1.close() | |
# sg.PopupOK("and now to the main program...") | |
# 745 | |
layout2 = [ | |
[sg.Text("Bonus:"),sg.Text("10", key="bonus", font=("Arial", 20, "bold")), | |
sg.Graph((WIDTH,HEIGHT), graph_bottom_left=(0,HEIGHT), graph_top_right=(WIDTH,0), | |
key="g", background_color=sg.theme_background_color())], | |
[sg.Text("Your gold:"), sg.Text(100,key="gold"), | |
sg.Text("Bounty for riddle #1:", key="riddle_number"), | |
sg.Text("100", key="bounty"), | |
sg.Text("riddles solved:"),sg.Text(f"0/{len(Riddle.storage)}", key="solved") ], | |
[ sg.Column([ | |
[sg.Text("Enter Code:")], | |
[sg.Input(default_text="???", key="code", enable_events=True, | |
font=("Courier New",20), size=(20,1))], | |
[sg.Text("wrong codes:")], | |
[sg.Multiline("???\n", disabled=True, size=(40,5), key="history", autoscroll=True )], | |
]), | |
sg.Column([ | |
[sg.Image(filename="chest.png", key="img")], | |
]), | |
], | |
[ sg.Text(f"hints: 2 / 4", key="hints"), | |
sg.Button(f"buy this hint for 10 gold", key="buy_hint")], | |
[ sg.Table([[]], | |
alternating_row_color=sg.theme_input_background_color(), # "light grey", | |
headings=["price","condition","status"], | |
font=("System", 12), | |
auto_size_columns=False, | |
justification="left", | |
num_rows = 10, | |
col_widths = [10,40,10], | |
enable_events = True, | |
select_mode = sg.TABLE_SELECT_MODE_BROWSE, | |
key="table"),], | |
[sg.Button("previous riddle", disabled=True), sg.Button("next riddle", disabled=True), sg.Button("Exit")], | |
] | |
window2 = sg.Window("code guesser game", layout2) | |
window2.Finalize() | |
g = window2["g"] | |
fig1 = g.draw_rectangle(top_left=(0,0), bottom_right=(150,20), | |
line_color=sg.theme_input_text_color(), | |
fill_color=sg.theme_text_color(), | |
line_width=3) | |
riddle = Riddle.storage[1] | |
#print(riddle.solutions) | |
window2["table"].update(riddle.calculate_hint_list("???")) | |
window2["table"].update(select_rows=[0]) | |
# left align for first column in table, see pysimplegui issue # | |
window2["table"].Widget.column('#1', anchor='e') # east for right | |
# TODO: replace with the brand_new cols_justification , as soon as all my students have upgraded to newest pysimplegui | |
gold = 100 | |
anim = False | |
while True: | |
event2, values2 = window2.read(timeout=10) | |
#print(event2, values2) | |
if event2 in ("Exit", sg.WIN_CLOSED): | |
break | |
elif event2 == sg.TIMEOUT_EVENT: | |
if anim: | |
window2["img"].update_animation("chest_animation.gif", time_between_frames = 200) | |
else: | |
if riddle.bonus > 0: | |
riddle.bonus -= 0.01 # 10 ms | |
#window2["bonus"].update(f"{bonus:.2f}") | |
g.delete_figure(fig1) | |
w = (WIDTH / riddle.full_bonus) * riddle.bonus | |
fig1 = g.draw_rectangle(top_left=(0,0), bottom_right=(w,HEIGHT), | |
line_color=sg.theme_input_text_color(), | |
fill_color=sg.theme_text_color(), | |
line_width=3) | |
else: | |
riddle.bonus = 0 | |
g.delete_figure(fig1) | |
window2["bonus"].update(f"{riddle.bonus:.1f}") | |
elif event2 == "table": | |
# a hint line was clicked | |
# or code was changed and for unknow reason this triggered the table event... | |
try: | |
line_number = values2["table"][0] | |
except IndexError: | |
continue | |
# using named tuples would be fine, but I need named list (??) because the price will be changed after buying a hint | |
price = riddle.hints[line_number][2] | |
if price == 0: | |
window2["buy_hint"].update(disabled=True) | |
window2["buy_hint"].update(text="This hint is already bought") | |
else: | |
window2["buy_hint"].update(text=f"Buy this hint for {price} gold") | |
window2["buy_hint"].update(disabled=False) | |
elif event2 == "buy_hint": | |
line_number = values2["table"][0] | |
price = riddle.hints[line_number][2] # TODO: use named tuples | |
if gold < price: | |
sg.PopupOK("You have not enough gold") | |
continue | |
gold -= price | |
window2["gold"].update(f"{gold}") | |
window2["buy_hint"].update(disabled=True) | |
window2["buy_hint"].update(text="This hint is already bought") | |
riddle.hints[line_number][2] = 0 # set price to 0 | |
window2["hints"].update(f"hints: {[price for (f,d,price) in riddle.hints].count(0)} / {len(riddle.hints)}") | |
window2["table"].update(riddle.calculate_hint_list(values2["code"])) | |
window2["table"].update(select_rows=[line_number]) | |
elif event2 == "next riddle": | |
i = riddle.number + 1 | |
if i <= len(Riddle.storage): | |
riddle = get_riddle(i) | |
elif event2 == "code": | |
#print("something happened in code") | |
guess = values2["code"] | |
# ----- check how many hints are true ------- | |
window2["table"].update(riddle.calculate_hint_list(guess)) | |
#print("guess/solution", guess, solutions) | |
# ------ check if guess is one of the correct answers --- | |
if guess.lower() in [str(x).lower() for x in riddle.solutions]: | |
window2["img"].update(filename="chest_animation.gif") | |
window2["img"].update_animation_no_buffering("chest_animation.gif", time_between_frames = 200) | |
anim =True | |
riddle.solved = True | |
window2["solved"].update(f"{len([r for r in Riddle.storage.values() if r.solved])}/{len(Riddle.storage)}") | |
wintext = "Your guess is correct!\n" | |
wintext += "You win gold:\n" | |
wintext += f"bounty: {riddle.bounty:8.2f}\n" | |
wintext += f"+bonus: {riddle.bonus:8.2f}\n" | |
wintext += "======================\n" | |
wintext += f"=total: {riddle.bounty+riddle.bonus:8.2f}" | |
sg.PopupOK(wintext, title="You win!", font=("Courier New",12)) | |
gold += (riddle.bounty + riddle.bonus) | |
window2["gold"].update(str(round(gold,2))) | |
window2["code"].update(disabled=True) | |
window2["buy_hint"].update(disabled=True) | |
# next / prev riddle? | |
if riddle.number < len(Riddle.storage): | |
window2["next riddle"].update(disabled=False) | |
else: | |
# wrong answer | |
if anim: | |
window2["img"].update(filename="chest.png") | |
anim = False | |
if len(guess) > 0: | |
# adding to a set will never create duplicate values | |
riddle.wrong_answers.add(guess) | |
window2["history"].update(riddle.history()) | |
window2.close() | |
print("bye") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""minigames for temple of doors: | |
opening a chest, guessing a number with hint system | |
using PySimpleGUI as GUI | |
""" | |
import PySimpleGUI as sg | |
import random | |
# graph window | |
WIDTH = 800 | |
HEIGHT = 500 | |
# -------- first gui: theme cooser -------------------------- | |
sg.theme(random.choice(sg.theme_list())) | |
# ---------------------- theme selector layout ------------- | |
layout1 = [ | |
[ | |
sg.Text("Select theme:"), | |
sg.Combo( | |
values=sg.theme_list(), | |
default_value=sg.theme(), | |
enable_events=True, | |
key="selector", | |
), | |
], | |
[sg.Button("play the game")], | |
] | |
window1 = sg.Window("theme selector", layout1) | |
# ---------------- main loop for first layout --------------- | |
while True: | |
event1, values1 = window1.read() | |
if event1 == "play the game" or event1 == sg.WIN_CLOSED: | |
# sg.theme("DarkBlue3") | |
break | |
if event1 == "selector": | |
old = sg.theme() | |
sg.theme(values1["selector"]) | |
if sg.PopupYesNo("do you like this Theme?") == "Yes": | |
break | |
else: | |
sg.theme(old) | |
window1.close() | |
# sg.PopupOK("and now to the main program...") | |
layout2 = [ | |
[sg.Text("Enter the Code:"), | |
sg.Input(default_text="???", key="code", enable_events=True)], | |
[sg.Text("hints:"),], | |
[sg.Table([["condition1:","fullfilled"], | |
["condition2:","not fullfilled"], | |
],alternating_row_color="grey", | |
headings=["condition","status"], | |
key="table")], | |
[sg.Button("Exit")], | |
] | |
window2 = sg.Window("code guesser game", layout2) | |
while True: | |
event2, values2 = window2.read(timeout=10) | |
if event2 in ("Exit", sg.WIN_CLOSED): | |
break | |
elif event2 == "code": | |
print("something happened in code") | |
window2.close() | |
print("bye") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment