File size: 6,990 Bytes
f7cd020
 
7c7984f
a135531
55b0da0
e19f381
a659a92
b707618
b0e72b5
 
a135531
f7cd020
b0e72b5
 
 
 
 
a135531
b0e72b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55b0da0
 
a659a92
41f349c
a659a92
 
 
 
b707618
a659a92
 
b707618
a659a92
 
 
 
498d5e9
b707618
 
a135531
b707618
 
a659a92
 
 
a135531
b707618
 
 
 
a135531
b707618
 
 
 
a135531
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a659a92
a135531
 
41f349c
 
a135531
 
 
 
a659a92
 
 
 
d192eda
 
a135531
 
 
f7cd020
d192eda
 
 
e19f381
7c7984f
 
 
a659a92
f7cd020
 
8679a4b
f7cd020
41f349c
f7cd020
783f89a
b0e72b5
41f349c
a659a92
 
a135531
 
 
 
d192eda
f7cd020
 
 
 
d192eda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# formatted with python black, line length 200

import os, random
import openai
import gradio as gr
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 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:
    game_intro = random.choice(GAME_INTRO_CHOICES)

    s_narr_transcript = game_intro + NOTES_TO_THE_NARRATOR_AT_START + AWAITING_INPUT
    s_user_transcript = game_intro + AWAITING_INPUT

    gr_top_of_scr_padding = gr.HTML(TOP_OF_SCREEN_PADDING_DIV)

    gr_narr_transcript = gr.Textbox(label="", value=s_narr_transcript, interactive=False, max_lines=9999, visible=False)
    gr_user_transcript = gr.Textbox(label="", value=s_user_transcript, 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()