Spaces:
Runtime error
Runtime error
# formatted with python black, line length 200 | |
import os, random | |
import openai | |
import gradio as gr | |
from game_content import INITIAL_WELCOME_TEXT | |
from game_content import GAME_INTRO_CHOICES, NOTES_TO_THE_NARRATOR_AT_START, AWAITING_INPUT, NOTES_TO_THE_NARRATOR_EVERY_TIME | |
from game_content import game_over_victory_txt, game_over_fail_txt, S_GAME_OVER | |
from game_content import N_TURNS_REQUIRED_TO_PASS_FIRST_BANDIT_ENCOUNTER, N_TURNS_REQUIRED_TO_REACH_HOME | |
import decider_utils | |
from decider_utils import YES, NO | |
from decider_questions import * # QUESTION_IS_USER_HOME, QUESTION_IS_USER_ENGAGED_WITH_BANDITS, etc. | |
from webpage import PAGE_STYLING_JS, PLEASE_BE_PATIENT_DIV, TOP_OF_SCREEN_PADDING_DIV | |
N_COMPLETIONS_WHEN_ELABORATING = 1 # I previously had this set to 3, but that made the program very slow. | |
MINIMUM_COMPLETION_LENGTH_CHARS_WHEN_ELABORATING = 7 | |
def elaborate( | |
str_beginning, | |
prevent_user_from_reaching_home=True, | |
require_user_to_be_still_engaged_with_bandits=False, | |
): | |
longest_completion = "" | |
while len(longest_completion) < MINIMUM_COMPLETION_LENGTH_CHARS_WHEN_ELABORATING: | |
completions = openai.Completion.create( | |
engine="text-davinci-003", | |
prompt=str_beginning, | |
temperature=0.5, | |
max_tokens=4000 - int(len(str_beginning) / 4), | |
frequency_penalty=0.5, | |
presence_penalty=0.5, | |
n=N_COMPLETIONS_WHEN_ELABORATING, | |
)["choices"] | |
for i in range(0, N_COMPLETIONS_WHEN_ELABORATING): | |
completion = completions[i]["text"] | |
# debug_print(completion) | |
allowed = True | |
if prevent_user_from_reaching_home: | |
does_the_user_reach_home = decider_utils.yesno(QUESTION_IS_USER_HOME, str_beginning + completion, default=YES) | |
allowed = not does_the_user_reach_home | |
if require_user_to_be_still_engaged_with_bandits: | |
is_user_engaged_with_bandits = decider_utils.yesno( | |
QUESTION_IS_USER_ENGAGED_WITH_BANDITS, | |
str_beginning + completion, | |
default=YES, | |
) | |
allowed = allowed and is_user_engaged_with_bandits | |
if allowed and len(completion) > len(longest_completion): | |
longest_completion = completion | |
return str_beginning + longest_completion | |
def run_1_game_turn(s_narr_transcript, s_n_turns_elapsed, s_user_transcript, s_user_input): | |
n_turns_elapsed = int(s_n_turns_elapsed) | |
finally_add2_both_tscripts = "" | |
if n_turns_elapsed == 0 and s_narr_transcript == "": | |
# New game. | |
# I learned the hard way that we have to do the random choice thing from within the game code; | |
# because if we just put it inside the "with demo:" block, | |
# then the gradio server only runs the random choice once per reboot. | |
game_intro = random.choice(GAME_INTRO_CHOICES) | |
s_narr_transcript = game_intro + NOTES_TO_THE_NARRATOR_AT_START | |
s_user_transcript = game_intro | |
elif s_user_input == "": | |
s_user_transcript += "You must choose an action.\n" | |
elif S_GAME_OVER in s_narr_transcript: | |
s_user_transcript += "Sorry, the game is already over. To play again, please refresh the page.\n" | |
elif decider_utils.yesno(QUESTION_IS_ACTION_LIKELY_LETHAL, s_user_input, default=NO): | |
finally_add2_both_tscripts += game_over_fail_txt("You have taken an action that is likely to result in killing someone.") | |
elif decider_utils.yesno(QUESTION_IS_USER_ENGAGED_WITH_BANDITS, s_narr_transcript, default=NO) and decider_utils.yesno(QUESTION_IS_ACTION_RUNNING_AWAY, s_user_input, default=NO): | |
finally_add2_both_tscripts += "Invalid entry. You cannot outrun these bandits.\n" | |
elif decider_utils.yesno(QUESTION_IS_ACTION_MAGIC, s_user_input, default=NO): | |
finally_add2_both_tscripts += "Invalid entry. You are not a spellcaster and have no magic items except your revolver.\n" | |
else: | |
# User input accepted. | |
n_turns_elapsed += 1 | |
s_user_transcript += s_user_input + "\n" | |
s_narr_transcript += s_user_input + "\n" | |
s_narr_transcript += NOTES_TO_THE_NARRATOR_EVERY_TIME | |
s_new_narr_transcript = elaborate( | |
s_narr_transcript, | |
prevent_user_from_reaching_home=n_turns_elapsed < N_TURNS_REQUIRED_TO_REACH_HOME, | |
require_user_to_be_still_engaged_with_bandits=n_turns_elapsed < N_TURNS_REQUIRED_TO_PASS_FIRST_BANDIT_ENCOUNTER, | |
) | |
s_new_part = s_new_narr_transcript.replace(s_narr_transcript, "") | |
s_narr_transcript += s_new_part + "\n" | |
s_user_transcript += s_new_part + "\n" | |
did_user_kill = decider_utils.yesno(QUESTION_DID_PROTAGONIST_KILL, s_new_part, default=NO) | |
did_user_kill = did_user_kill or decider_utils.yesno(QUESTION_DID_PROTAGONIST_KILL, s_narr_transcript, default=NO) | |
if did_user_kill: | |
finally_add2_both_tscripts += game_over_fail_txt("You have taken a life.") | |
else: | |
is_user_home = decider_utils.yesno(QUESTION_IS_USER_HOME, s_narr_transcript, default=NO) | |
if is_user_home: | |
has_at_least_30_gold = decider_utils.yesno(QUESTION_DOES_USER_STILL_HAVE_AT_LEAST_30_GOLD, s_narr_transcript, default=NO) | |
if has_at_least_30_gold: | |
finally_add2_both_tscripts += game_over_victory_txt("You made it home with 30+ gold! Your family is grateful and you all hug in celebration.") | |
else: | |
finally_add2_both_tscripts += game_over_fail_txt("You reached home with less than 30 gold - too little for your family to live on.") | |
# End of code block User input accepted. | |
s_n_turns_elapsed = str(n_turns_elapsed) | |
s_user_input = "" | |
if S_GAME_OVER not in finally_add2_both_tscripts and S_GAME_OVER not in s_narr_transcript: | |
finally_add2_both_tscripts += AWAITING_INPUT | |
s_narr_transcript += finally_add2_both_tscripts | |
s_user_transcript += finally_add2_both_tscripts | |
return [s_narr_transcript, s_n_turns_elapsed, s_user_transcript, s_user_input] | |
openai.organization = os.environ.get("OPENAI_ORGANIZATION") | |
openai.api_key = os.environ.get("OPENAI_KEY") | |
demo = gr.Blocks() | |
with demo: | |
gr_top_of_scr_padding = gr.HTML(TOP_OF_SCREEN_PADDING_DIV) | |
gr_narr_transcript = gr.Textbox(label="", value="", interactive=False, max_lines=9999, visible=False) | |
gr_user_transcript = gr.Textbox(label="", value=INITIAL_WELCOME_TEXT, interactive=False, max_lines=9999, elem_classes="parleygame") | |
gr_pls_be_patient = gr.HTML(PLEASE_BE_PATIENT_DIV) | |
gr_user_input = gr.Textbox(label="", value="", placeholder="Describe your next action here...", interactive=True) | |
gr_button1 = gr.Button(value="Run Next Turn") | |
gr_n_turns_elapsed = gr.Textbox(label="N Turns Elapsed", value="0", interactive=False) | |
gr_button1.click( | |
fn=run_1_game_turn, inputs=[gr_narr_transcript, gr_n_turns_elapsed, gr_user_transcript, gr_user_input], outputs=[gr_narr_transcript, gr_n_turns_elapsed, gr_user_transcript, gr_user_input] | |
) | |
# See https://discuss.huggingface.co/t/gradio-html-component-with-javascript-code-dont-work/37316/2 | |
demo.load(None, None, None, _js=PAGE_STYLING_JS) | |
demo.launch() | |