View difference between Paste ID: zpW3zsLU and pWyruJ6S
SHOW: | | - or go back to the newest paste.
1
modify in py.play part:
2
 elif action == "save":
3
                if upload_story:
4
                    id = story_manager.story.save_to_local()
5
                    console_print("Game saved.")
6
                    console_print("To load the game, type 'load' and enter the following ID: " + id)
7
                else:
8
                    console_print("Saving has been turned off. Cannot save.")
9
10
            elif action =="load":
11
                load_ID = input("What is the ID of the saved game?")
12
                result = story_manager.story.load_from_local(load_ID)
13
                console_print("\nLoading Game...\n")
14
                console_print(result)
15
=========================================================================================================================
16
17
modify in the story.maneger part
18
19
from story.utils import *
20
import json
21
import uuid
22
from subprocess import Popen
23
import subprocess
24
import os
25
26
class Story():
27
28
    def __init__(self, story_start, context ="", seed=None, game_state=None, upload_story=False):
29
        self.story_start = story_start
30
        self.context = context
31
        self.rating = -1
32
        self.upload_story = upload_story
33
34
        # list of actions. First action is the prompt length should always equal that of story blocks
35
        self.actions = []
36
37
        # list of story blocks first story block follows prompt and is intro story
38
        self.results = []
39
40
        # Only needed in constrained/cached version
41
        self.seed = seed
42
        self.choices = []
43
        self.possible_action_results = None
44
        self.uuid = None
45
46
        if game_state is None:
47
            game_state = dict()
48
        self.game_state = game_state
49
        self.memory = 20
50
51
    def __del__(self):
52
        if self.upload_story:
53
            self.save_to_local()
54
            console_print("Game saved.")
55
            console_print("To load the game, type 'load' and enter the following ID: " + self.uuid)
56
57
58
    def init_from_dict(self, story_dict):
59
        self.story_start = story_dict["story_start"]
60
        self.seed = story_dict["seed"]
61
        self.actions = story_dict["actions"]
62
        self.results = story_dict["results"]
63
        self.choices = story_dict["choices"]
64
        self.possible_action_results = story_dict["possible_action_results"]
65
        self.game_state = story_dict["game_state"]
66
        self.context = story_dict["context"]
67
        self.uuid = story_dict["uuid"]
68
69
        if "rating" in story_dict.keys():
70
            self.rating = story_dict["rating"]
71
        else:
72
            self.rating = -1
73
74
75
    def initialize_from_json(self, json_string):
76
        story_dict = json.loads(json_string)
77
        self.init_from_dict(story_dict)
78
79
    def add_to_story(self, action, story_block):
80
        self.actions.append(action)
81
        self.results.append(story_block)
82
83
    def latest_result(self):
84
85
        mem_ind = self.memory
86
        if len(self.results) < 2:
87
            latest_result = self.story_start
88
        else:
89
            latest_result = self.context
90
        while mem_ind > 0:
91
92
            if len(self.results) >= mem_ind:
93
                latest_result += (self.actions[-mem_ind] + self.results[-mem_ind])
94
95
            mem_ind -= 1
96
97
        return latest_result
98
99
    def __str__(self):
100
        story_list = [self.story_start]
101
        for i in range(len(self.results)):
102
            story_list.append("\n" + self.actions[i] + "\n")
103
            story_list.append("\n" + self.results[i])
104
105
        return "".join(story_list)
106
107
    def to_json(self):
108
        story_dict = {}
109
        story_dict["story_start"] = self.story_start
110
        story_dict["seed"] = self.seed
111
        story_dict["actions"] = self.actions
112
        story_dict["results"] = self.results
113
        story_dict["choices"] = self.choices
114
        story_dict["possible_action_results"] = self.possible_action_results
115
        story_dict["game_state"] = self.game_state
116
        story_dict["context"] = self.context
117
        story_dict["uuid"] = self.uuid
118
        story_dict["rating"] = self.rating
119
120
        return json.dumps(story_dict)
121
122
    def save_to_local(self):
123
        self.uuid = str(uuid.uuid1())
124
        story_json = self.to_json()
125
        file_name = "AIDungeonSave_" + str(self.uuid) + ".json"
126
        f = open(file_name, "w")
127
        f.write(story_json)
128
        f.close()
129
        return self.uuid
130
131
    def load_from_local(self, save_name):
132
        file_name = "AIDungeonSave_" + save_name + ".json"
133
        exists = os.path.isfile(file_name)
134
        
135
        if exists:
136
            with open(file_name, 'r') as fp:
137
                game = json.load(fp)
138
            self.init_from_dict(game)
139
            return str(self)
140
        else:
141
            return "Error save not found."
142
        
143
144
    def save_to_storage(self):
145
        self.uuid = str(uuid.uuid1())
146
147
148
        story_json = self.to_json()
149
        file_name = "story" + str(self.uuid) + ".json"
150
        f = open(file_name, "w")
151
        f.write(story_json)
152
        f.close()
153
154
        FNULL = open(os.devnull, 'w')
155
        p = Popen(['gsutil.cmd', 'cp', file_name, 'gs://aidungeonstories'], stdout=FNULL, stderr=subprocess.STDOUT)
156
        return self.uuid
157
158
    def load_from_storage(self, story_id):
159
160
        file_name = "story" + story_id + ".json"
161
        cmd = "gsutil.cmd cp gs://aidungeonstories/" + file_name + " ."
162
        os.system(cmd)
163
        exists = os.path.isfile(file_name)
164
165
        if exists:
166
            with open(file_name, 'r') as fp:
167
                game = json.load(fp)
168
            self.init_from_dict(game)
169
            return str(self)
170
        else:
171
            return "Error save not found."
172
173
174
class StoryManager():
175
176
    def __init__(self, generator):
177
        self.generator = generator
178
        self.story = None
179
        
180
    def start_new_story(self, story_prompt, context="", game_state=None, upload_story=False):
181
        block = self.generator.generate(context + story_prompt)
182
        block = cut_trailing_sentence(block)
183
        self.story = Story(context + story_prompt + block, context=context, game_state=game_state, upload_story=upload_story)
184
        return self.story
185
    
186
    def load_story(self, story, from_json=False):
187
        if from_json:
188
            self.story = Story("")
189
            self.story.initialize_from_json(story)
190
        else:
191
            self.story = story
192
        return str(story)
193
194
    def json_story(self):
195
        return self.story.to_json()
196
197
    def story_context(self):
198
        return self.story.latest_result()
199
200
201
class UnconstrainedStoryManager(StoryManager):
202
203
    def act(self, action_choice):
204
205
        result = self.generate_result(action_choice)
206
        self.story.add_to_story(action_choice, result)
207
        return result
208
209
    def generate_result(self, action):
210
        block = self.generator.generate(self.story_context() + action)
211
        return block
212
213
214
class ConstrainedStoryManager(StoryManager):
215
216
    def __init__(self, generator, action_verbs_key="classic"):
217
        super().__init__(generator)
218
        self.action_phrases = get_action_verbs(action_verbs_key)
219
        self.cache = False
220
        self.cacher = None
221
        self.seed = None
222
223
    def enable_caching(self, credentials_file=None, seed=0, bucket_name="dungeon-cache"):
224
        self.cache = True
225
        self.cacher = Cacher(credentials_file, bucket_name)
226
        self.seed = seed
227
228
    def start_new_story(self, story_prompt, context="", game_state=None):
229
        if self.cache:
230
            return self.start_new_story_cache(story_prompt, game_state=game_state)
231
        else:
232
            return super().start_new_story(story_prompt, context=context, game_state=game_state)
233
234
    def start_new_story_generate(self, story_prompt, game_state=None):
235
        super().start_new_story(story_prompt, game_state=game_state)
236
        self.story.possible_action_results = self.get_action_results()
237
        return self.story.story_start
238
239
    def start_new_story_cache(self, story_prompt, game_state=None):
240
241
        response = self.cacher.retrieve_from_cache(self.seed, [], "story")
242
        if response is not None:
243
            story_start = story_prompt + response
244
            self.story = Story(story_start, seed=self.seed)
245
            self.story.possible_action_results = self.get_action_results()
246
        else:
247
            story_start = self.start_new_story_generate(story_prompt, game_state=game_state)
248
            self.story.seed = self.seed
249
            self.cacher.cache_file(self.seed, [], story_start, "story")
250
251
        return story_start
252
253
    def load_story(self, story, from_json=False):
254
        story_string = super().load_story(story, from_json=from_json)
255
        return story_string
256
257
    def get_possible_actions(self):
258
        if self.story.possible_action_results is None:
259
            self.story.possible_action_results = self.get_action_results()
260
261
        return [action_result[0] for action_result in self.story.possible_action_results]
262
263
    def act(self, action_choice_str):
264
265
        try:
266
            action_choice = int(action_choice_str)
267
        except:
268
            print("Error invalid choice.")
269
            return None, None
270
271
        if action_choice < 0 or action_choice >= len(self.action_phrases):
272
            print("Error invalid choice.")
273
            return None, None
274
275
        self.story.choices.append(action_choice)
276
        action, result = self.story.possible_action_results[action_choice]
277
        self.story.add_to_story(action, result)
278
        self.story.possible_action_results = self.get_action_results()
279
        return result, self.get_possible_actions()
280
281
    def get_action_results(self):
282
        if self.cache:
283
            return self.get_action_results_cache()
284
        else:
285
            return self.get_action_results_generate()
286
287
    def get_action_results_generate(self):
288
        action_results = [self.generate_action_result(self.story_context(), phrase) for phrase in self.action_phrases]
289
        return action_results
290
291
    def get_action_results_cache(self):
292
        response = self.cacher.retrieve_from_cache(self.story.seed, self.story.choices, "choices")
293
294
        if response is not None:
295
            print("Retrieved from cache")
296
            return json.loads(response)
297
        else:
298
            print("Didn't receive from cache")
299
            action_results = self.get_action_results_generate()
300
            response = json.dumps(action_results)
301
            self.cacher.cache_file(self.story.seed, self.story.choices, response, "choices")
302
            return action_results
303
304
    def generate_action_result(self, prompt, phrase, options=None):
305
306
        action_result = phrase + " " + self.generator.generate(prompt + " " + phrase, options)
307
        action, result = split_first_sentence(action_result)
308
        return action, result