def settings_menu(): all_settings = list(setting_info.keys()) while True: list_items([ pad_text(k, 19) + v[0] + (" " if v[0] else "") + "Default: " + str(v[1]) + " | " "Current: " + settings.get(k) for k, v in setting_info.items() ] + ["(Finish)"]) i = input_number(len(all_settings), default=-1) if i == len(all_settings): output("Done editing settings. ", "menu") return else: key = all_settings[i] output(key + ": " + setting_info[key][0], "menu") output("Default: " + str(setting_info[key][1]), "menu", beg='') output("Current: " + str(settings[key]), "menu", beg='') new_value = input_line("Enter the new value: ", "query") if len(new_value.strip()) == 0: output("Invalid value; cancelling. ", "error") continue output(key + ": " + setting_info[key][0], "menu") output("Current: " + str(settings[key]), "menu", beg='') output("New: " + str(new_value), "menu", beg='') output("Saving an invalid option will corrupt file! ", "message") if input_bool("Change setting? (y/N): ", "selection-prompt"): settings[key] = new_value try: with open("config.ini", "w", encoding="utf-8") as file: config.write(file) except IOError: output( "Permission error! Changes will not be saved for next session.", "error")
def process_command(self, cmd_regex) -> bool: """ Processes an in-game command. :param cmd_regex: The regular expression for the command. :return: True if the command causes the game to exit, false otherwise. """ command = cmd_regex.group(1).strip().lower() args = cmd_regex.group(2).strip().split() if command == "set": if len(args) < 2: output("Invalid number of arguments for set command. ", "error") instructions() return False if args[0] in settings: curr_setting_val = settings[args[0]] output("Current Value of {}: {} Changing to: {}".format( args[0], curr_setting_val, args[1])) output("Saving an invalid option will corrupt file! ", "error") if input_bool("Save setting? (y/N): ", "selection-prompt"): settings[args[0]] = args[1] try: with open("config.ini", "w", encoding="utf-8") as f: config.write(f) except IOError: output( "Permission error! Changes will not be saved for next session.", "error") else: output("Invalid setting", "error") instructions() elif command == "settings": settings_menu() self.story.print_last() elif command == "menu": if input_bool("Do you want to save? (y/N): ", "query"): save_story(self.story) # self.story, self.context, self.prompt = None, None, None return True elif command == "restart": output("Restarting story...", "loading-message") if len((self.context + self.prompt).strip()) == 0: output( "Story has no prompt or context. Please enter a valid prompt. ", "error") return False self.story = new_story(self.generator, self.story.context, self.prompt) elif command == "quit": if input_bool("Do you want to save? (y/N): ", "query"): save_story(self.story) exit() elif command == "help": instructions() elif command == "print": use_wrap = input_bool("Print with wrapping? (y/N): ", "query") use_color = input_bool("Print with colors? (y/N): ", "query") output("Printing story...", "message") self.story.print_story(wrap=use_wrap, color=use_color) elif command == "retry": if len(self.story.actions) < 2: output("Restarting story...", "loading-message") if len((self.context + self.prompt).strip()) == 0: output( "Story has no prompt or context. Please enter a valid prompt. ", "error") return False self.story = new_story(self.generator, self.story.context, self.prompt) return False else: output("Retrying...", "loading-message") new_action = self.story.actions[-1] self.story.revert() result = self.story.act(new_action) if self.story.is_looping(): self.story.revert() output( "That action caused the model to start looping. Try something else instead. ", "error") return False self.story.print_last() elif command == "revert": if len(self.story.actions) < 2: output("You can't go back any farther. ", "error") return False self.story.revert() output("Last action reverted. ", "message") self.story.print_last() elif command == "alter": self.story.results[-1] = alter_text(self.story.results[-1]) self.story.print_last() elif command == "context": self.story.context = alter_text(self.story.context) self.story.print_last() elif command == "remember": memory = cmd_regex.group(2).strip() if len(memory) > 0: memory = re.sub("^[Tt]hat +(.*)", "\\1", memory) memory = memory.strip('.') memory = memory.strip('!') memory = memory.strip('?') self.story.memory.append(memory[0].upper() + memory[1:] + ".") output("You remember " + memory + ". ", "message") else: output("Please enter something valid to remember. ", "error") elif command == "forget": while True: output("Select a memory to forget: ", "menu") list_items(self.story.memory + ["(Finish)"], "menu") i = input_number(len(self.story.memory), default=-1) if i == len(self.story.memory): break else: del self.story.memory[i] elif command == "save": save_story(self.story) elif command == "load": story_file = select_file(Path("saves"), ".json") if story_file: tstory, tcontext, tprompt = load_story(story_file, self.generator) if tstory: output("Loading story...", "message") self.story = tstory self.context = tcontext self.prompt = tprompt self.story.print_story() else: self.story.print_last() else: self.story.print_last() elif command == "summarize": first_result = self.story.results[-1] output(self.story.context, "user-text", "(YOUR SUMMARY HERE)", "message") output(self.story.results[-1], "ai-text") new_prompt = input_line("Enter the summary for the new story: ", "query") new_prompt = new_prompt.strip() if len(new_prompt) == 0: output("Invalid new prompt; cancelling. ", "error") self.story.print_last() return False if input_bool("Do you want to save your previous story? (y/N): ", "query"): save_story(self.story) self.prompt = new_prompt self.story = new_story(self.generator, self.context, self.prompt, memory=self.story.memory, first_result=first_result) self.story.savefile = "" elif command == "altergen": result = alter_text(self.story.results[-1]) self.story.results[-1] = "" output("Regenerating result...", "message") result += ' ' + self.story.act(result, record=False) self.story.results[-1] = result self.story.print_last() else: output("Invalid command: " + command, "error") return False
def play(generator): print("\n") with open(Path("interface", "mainTitle.txt"), "r", encoding="utf-8") as file: colPrint(file.read(), colors["title"], wrap=False) with open(Path("interface", "subTitle.txt"), "r", encoding="utf-8") as file: cols = termWidth for line in file: line = re.sub(r'\n', '', line) line = line[:cols] #fills in the graphic using reverse video mode substituted into the areas between |'s colPrint( re.sub(r'\|[ _]*(\||$)', lambda x: '\x1B[7m' + x.group(0) + '\x1B[27m', line), colors['subtitle'], False) print() colPrint( "Go to https://github.com/cloveranon/Clover-Edition/ or email [email protected] for bug reports, help, and feature requests.", colors['subsubtitle']) while True: # May be needed to avoid out of mem gc.collect() torch.cuda.empty_cache() print("\n\n") colPrint( "0: Pick Prompt From File (Default if you type nothing)\n1: Write Custom Prompt", colors['menu']) if getNumberInput(1) == 1: with open(Path("interface", "prompt-instructions.txt"), "r", encoding="utf-8") as file: colPrint(file.read(), colors["instructions"], False) prompt = colInput("Prompt>", colors["main-prompt"], colors["user-text"]) context = colInput("Context>", colors["main-prompt"], colors["user-text"]) filename = colInput( "Name to save prompt as? (Leave blank for no save): ", colors["query"], colors["user-text"], ) filename = re.sub( "-$", "", re.sub("^-", "", re.sub("[^a-zA-Z0-9_-]+", "-", filename))) if filename != "": with open(Path("prompts", filename + ".txt"), "w", encoding="utf-8") as f: f.write(context + "\n" + prompt) else: prompt, context = selectFile() assert (prompt + context) instructions() print() colPrint("Generating story...", colors["loading-message"]) story = newStory(generator, prompt, context) while True: # Generate suggested actions act_alts = settings.getint("action-sugg") if act_alts > 0: # TODO change this to two messages for different colors suggested_actions = [] colPrint("\nSuggested actions:", colors["selection-value"]) action_suggestion_lines = 2 for i in range(act_alts): suggested_action = story.getSuggestion() if len(suggested_action.strip()) > 0: j = len(suggested_actions) suggested_actions.append(suggested_action) suggestion = "{}> {}".format(j, suggested_action) action_suggestion_lines += colPrint( suggestion, colors["selection-value"]) print() bell() action = colInput("> You ", colors["main-prompt"], colors["user-text"]) # Clear suggestions and user input if act_alts > 0: action_suggestion_lines += 2 if not IN_COLAB: clear_lines(action_suggestion_lines) # Show user input again # colPrint("\n> " + action.rstrip(), colors["user-text"], end="") setRegex = re.search("^/set ([^ ]+) ([^ ]+)$", action) if setRegex: if setRegex.group(1) in settings: currentSettingValue = settings[setRegex.group(1)] colPrint( "Current Value of {}: {} Changing to: {}".format( setRegex.group(1), currentSettingValue, setRegex.group(2))) settings[setRegex.group(1)] = setRegex.group(2) colPrint("Save config file?", colors["query"]) colPrint("Saving an invalid option will corrupt file!", colors["error"]) if (colInput( "y/n? >", colors["selection-prompt"], colors["selection-value"], ) == "y"): with open("config.ini", "w", encoding="utf-8") as file: config.write(file) else: colPrint("Invalid Setting", colors["error"]) instructions() elif action == "/menu": break elif action == "/restart": print() colPrint("Restarting story...", colors["loading-message"]) story = newStory(generator, story.prompt, context) continue elif action == "/quit": exit() elif action == "/help": instructions() elif action == "/print": print("\nPRINTING\n") #TODO colorize printed story colPrint(str(story), colors["print-story"]) elif action == '/retry': if len(story.story) == 1: print() colPrint("Restarting story...", colors["loading-message"]) story = newStory(generator, story.prompt, context) continue else: newaction = story.story[-1][0] colPrint(newaction, colors['user-text'], end='') story.story = story.story[:-1] result = "\n" + story.act(newaction)[0] if len(story.story) >= 2: similarity = get_similarity(result, story.story[-2][1][0]) if similarity > 0.9: story.story = story.story[:-1] colPrint( "Woops that action caused the model to start looping. Try a different action to prevent that.", colors["error"], ) continue colPrint(result, colors["ai-text"]) continue elif action == '/revert': if len(story.story) == 1: colPrint("You can't go back any farther. ", colors["error"]) continue story.story = story.story[:-1] colPrint("Last action reverted. ", colors["message"]) if len(story.story) < 2: colPrint(story.prompt, colors["ai-text"]) colPrint(story.story[-1][1][0], colors["ai-text"]) continue elif action == "/alter": story.story[-1][1][0] = alterText(story.story[-1][1][0]) if len(story.story) < 2: colPrint(story.prompt, colors["ai-text"]) else: colPrint("\n" + story.story[-1][0] + "\n", colors["transformed-user-text"]) colPrint("\n" + story.story[-1][1][0] + "\n\n", colors["ai-text"]) elif action == "/prompt": story.prompt = alterText(story.prompt) if len(story.story) < 2: colPrint(story.prompt, colors["ai-text"]) else: colPrint("\n" + story.story[-1][0] + "\n", colors["transformed-user-text"]) colPrint("\n" + story.story[-1][1][0] + "\n\n", colors["ai-text"]) else: if act_alts > 0: # Options to select a suggestion action if action in [ str(i) for i in range(len(suggested_actions)) ]: action = suggested_actions[int(action)] original_action = action action = action.strip() #TODO debug stuff to delete if action != original_action: logger.debug("STRIPPED WHITE SPACE OFF ACTION %r vs %r", original_action, action) # Crop actions to a max length #action = action[:4096] if action != "": # Roll a 20 sided dice to make things interesting d = random.randint(1, 20) logger.debug("roll d20=%s", d) # If it says 'You say "' then it's still dialouge. Normalise it by removing `You say `, we will add again soon action = re.sub("^ ?[Yy]ou say [\"']", '"', action) if any(action.lstrip().startswith(t) for t in ['"', "'"]): if settings.getboolean("action-d20"): action = d20ify_speech(action, d) else: action = "You say " + action logger.info( "%r. %r, %r", action, any(action.lstrip().startswith(t) for t in ['"', "'"]), settings.getboolean("action-d20")) else: action = first_to_second_person(action) if not action.lower().startswith( "you ") and not action.lower().startswith( "i "): action = action[0].lower() + action[1:] # roll a d20 if settings.getboolean("action-d20"): action = d20ify_action(action, d) else: action = "You " + action if action[-1] not in [".", "?", "!"]: action = action + "." action = "\n> " + action + "\n" colPrint( "\n>" + action.lstrip().lstrip("> \n"), colors["transformed-user-text"], ) #TODO check if leading white space makes sense result = "\n" + story.act(action)[0] #TODO: Replace all this nonsense if len(story.story) >= 2: similarity = get_similarity(result, story.story[-2][1][0]) if similarity > 0.9: story.story = story.story[:-1] colPrint( "Woops that action caused the model to start looping. Try a different action to prevent that.", colors["error"], ) continue if player_won(result): colPrint(result + "\n CONGRATS YOU WIN", colors["message"]) break elif player_died(result): colPrint(result, colors["ai-text"]) colPrint("YOU DIED. GAME OVER", colors["error"]) colPrint( "\nOptions:\n0)Start a new game\n1)\"I'm not dead yet!\" (If you didn't actually die)", colors["menu"], ) choice = getNumberInput(1) if choice == 0: break else: colPrint("Sorry about that...where were we?", colors["query"]) colPrint(result, colors["ai-text"])