Skip to content

Commit

Permalink
Develop (latitudegames#9)
Browse files Browse the repository at this point in the history
Adds saving and loading. Changes cmd line interface and adds new commands.
  • Loading branch information
nickwalton authored Dec 2, 2019
1 parent a2e41ef commit 923376d
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 48 deletions.
104 changes: 70 additions & 34 deletions play.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def select_game():
else:
print_str += " (experimental)"
console_print(print_str)
console_print(str(len(settings)) + ") custom (for advanced players)")
console_print(str(len(settings)) + ") custom expiermental")
choice = get_num_options(len(settings)+1)

if choice == len(settings):
Expand Down Expand Up @@ -52,19 +52,25 @@ def select_game():

def instructions():
text = "\nAI Dungeon 2 Instructions:"
text += '\n* Enter actions starting with a verb ex. "go to the tavern" or "attack the orc."'
text += '\n* To speak enter \'say "(thing you want to say)"\' or just "(thing you want to say)" '
text += '\n* Enter "revert" for any action if you want to undo the last action and result.'
text += '\n* Finally if you want to end your game and start a new one just enter "restart" for any action. '
text += '\n Enter actions starting with a verb ex. "go to the tavern" or "attack the orc."'
text += '\n To speak enter \'say "(thing you want to say)"\' or just "(thing you want to say)" '
text += '\n\nThe following commands can be entered for any action: '
text += '\n "revert" Reverts the last action allowing you to pick a different action.'
text += '\n "quit" Quits the game and saves'
text += '\n "restart" Starts a new game and saves your current one'
text += '\n "save" Makes a new save of your game and gives you the save ID'
text += '\n "load" Asks for a save ID and loads the game if the ID is valid'
text += '\n "print" Prints a transcript of your adventure (without extra newline formatting)'
text += '\n "help" Prints these instructions again'
return text

def play_aidungeon_2():

save_story = input("Help AIDungeon by letting us store your adventure to improve the model? (Y/n) ")
if save_story.lower() in ["no", "No", "n"]:
upload_story = False
else:
upload_story = True
console_print("AI Dungeon 2 will save and use your actions and game to continually improve AI Dungeon."
+ " If you would like to disable this enter 'nosaving' for any action. This will also turn off the "
+ "ability to save games.")

upload_story = True

print("\nInitializing AI Dungeon! (This might take a few minutes)\n")
generator = GPT2Generator()
Expand Down Expand Up @@ -93,8 +99,36 @@ def play_aidungeon_2():
action = input("> ")
if action == "restart":
break

elif action == "quit":
exit()

elif action == "nosaving":
upload_story = False
story_manager.story.upload_story = False
console_print("Saving turned off.")

elif action == "help":
console_print(instructions())

elif action == "save":
if upload_story:
id = story_manager.story.save_to_storage()
console_print("Game saved.")
console_print("To load the game, type 'load' and enter the following ID: " + id)
else:
console_print("Saving has been turned off. Cannot save.")

elif action =="load":
load_ID = input("What is the ID of the saved game?")
result = story_manager.story.load_from_storage(load_ID)
console_print("\nLoading Game...\n")
console_print(result)

elif action == "print":
print("\nPRINTING\n")
print(str(story_manager.story))

elif action == "revert":

if len(story_manager.story.actions) is 0:
Expand All @@ -109,40 +143,42 @@ def play_aidungeon_2():
else:
console_print(story_manager.story.story_start)
continue
elif action == "":
action = ""

elif action[0] == '"':
action = "You say " + action

else:
action = action.strip()
action = action[0].lower() + action[1:]
if action == "":
action = ""
result = story_manager.act(action)
console_print(result)

action = first_to_second_person(action)
elif action[0] == '"':
action = "You say " + action

if "You" not in action:
action = "You " + action
else:
action = action.strip()
action = action[0].lower() + action[1:]

if action[-1] not in [".", "?", "!"]:
action = action + "."
if "You" not in action[:6] and "I" not in action[:6]:
action = "You " + action

action = "\n> " + action + "\n"
if action[-1] not in [".", "?", "!"]:
action = action + "."

result = "\n" + story_manager.act(action)
action = first_to_second_person(action)

if player_won(result):
console_print(result + "\n CONGRATS YOU WIN")
break
elif player_died(result):
console_print(result)
died = input("Did you die? (y/N)")
if died.lower() in ["yes", "y"]:
action = "\n> " + action + "\n"

result = "\n" + story_manager.act(action)

if player_won(result):
console_print(result + "\n CONGRATS YOU WIN")
break
elif player_died(result):
console_print(result)
console_print("YOU DIED. GAME OVER")
break
else:
console_print(result)

else:
console_print(result)


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion story/story_data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ settings:
item2: "small dagger"

knight:
prompts: ["You enter the forest where you believe the ogre that has been terrorizing your home has been hiding. You step inside and"]
prompts: ["You are on a quest to defeat the evil dragon of Larion. You've heard he lives up at the north of the kingdom. You set on the path to defeat him and walk into a dark forest. As you enter the forest you see"]

item1: "steel longsword"
item2: "wooden shield"
Expand Down
52 changes: 47 additions & 5 deletions story/story_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, story_start, context ="", seed=None, game_state=None, upload_
self.seed = seed
self.choices = []
self.possible_action_results = None
self.uuid = str(uuid.uuid1())
self.uuid = None

if game_state is None:
game_state = dict()
Expand All @@ -40,8 +40,7 @@ def __del__(self):
except:
pass

def initialize_from_json(self, json_string):
story_dict = json.loads(json_string)
def init_from_dict(self, story_dict):
self.story_start = story_dict["story_start"]
self.seed = story_dict["seed"]
self.actions = story_dict["actions"]
Expand All @@ -57,6 +56,11 @@ def initialize_from_json(self, json_string):
else:
self.rating = -1


def initialize_from_json(self, json_string):
story_dict = json.loads(json_string)
self.init_from_dict(story_dict)

def add_to_story(self, action, story_block):
self.actions.append(action)
self.results.append(story_block)
Expand All @@ -81,8 +85,8 @@ def latest_result(self):
def __str__(self):
story_list = [self.story_start]
for i in range(len(self.results)):
story_list.append(self.actions[i])
story_list.append(self.results[i])
story_list.append("\n> " + self.actions[i] + "\n")
story_list.append("\n" + self.results[i])

return "".join(story_list)

Expand All @@ -101,7 +105,26 @@ def to_json(self):

return json.dumps(story_dict)

def save_to_local(self, save_name):
self.uuid = str(uuid.uuid1())
story_json = self.to_json()
file_name = "AIDungeonSave_" + save_name + ".json"
f = open(file_name, "w")
f.write(story_json)
f.close()

def load_from_local(self, save_name):
file_name = "AIDungeonSave_" + save_name + ".json"
print("Save ID that can be used to load game is: ", self.uuid)

with open(file_name, 'r') as fp:
game = json.load(fp)
self.init_from_dict(game)

def save_to_storage(self):
self.uuid = str(uuid.uuid1())


story_json = self.to_json()
file_name = "story" + str(self.uuid) + ".json"
f = open(file_name, "w")
Expand All @@ -110,6 +133,25 @@ def save_to_storage(self):

FNULL = open(os.devnull, 'w')
p = Popen(['gsutil', 'cp', file_name, 'gs://aidungeonstories'], stdout=FNULL, stderr=subprocess.STDOUT)
return self.uuid

def load_from_storage(self, story_id):

file_name = "story" + story_id + ".json"
cmd = "gsutil cp gs://aidungeonstories/" + file_name + " . >/dev/null 2>&1"
os.system(cmd)
exists = os.path.isfile(file_name)

with open(file_name, 'r') as fp:
game = json.load(fp)
self.init_from_dict(game)

if exists:
return str(self)
else:
return "Error save not found."




class StoryManager():
Expand Down
16 changes: 8 additions & 8 deletions story/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ def get_num_options(num):

def player_died(text):

reg_phrases = ["You[a-zA-Z ]* die.", "you[a-zA-Z ]* die.", "You[a-zA-Z ]* die ", "you[a-zA-Z ]* die ",]

for phrase in reg_phrases:
reg_expr = re.compile(phrase)
matches = re.findall(reg_expr, text)
if len(matches) > 0:
return True
# reg_phrases = ["You[a-zA-Z ]* die.", "you[a-zA-Z ]* die.", "You[a-zA-Z ]* die ", "you[a-zA-Z ]* die ",]
#
# for phrase in reg_phrases:
# reg_expr = re.compile(phrase)
# matches = re.findall(reg_expr, text)
# if len(matches) > 0:
# return True

dead_phrases = ["you die", "You die", "you died", "you are dead", "You died", "You are dead", "You're dead",
"you're dead", "you have died", "You have died", "finish you off", "Your death", "your death"]
"you're dead", "you have died", "You have died", "you bleed out"]
for phrase in dead_phrases:
if phrase in text:
return True
Expand Down

0 comments on commit 923376d

Please sign in to comment.