def solve_simon_says(self, bomb_contains_vowel, num_strikes, curr_round): # Translates the user's flashing colors into the correct colors to press original_flash_colors = input("Enter the flash of each color, seperated by a space: ").strip().split() translated_colors = [] # Stores the correct colors to press in a list # Ensure the correct number of colors are entered if len(original_flash_colors) != curr_round: print_and_wait(f"There should be {curr_round} color(s). Please re-enter the numbers or restart.") return self.solve_simon_says(bomb_contains_vowel, num_strikes, curr_round) # Go through each color, translating them all for color in original_flash_colors: try: # Check which table should be used to translate the colors if bomb_contains_vowel: translated_colors.append(self.translate_with_vowels[color.lower()][num_strikes]) else: translated_colors.append(self.translate_without_vowels[color.lower()][num_strikes]) except KeyError: print_and_wait("Invalid color detected. Please try again.") return self.solve_simon_says(bomb_contains_vowel, num_strikes, curr_round) # Create a string to return to the user containing the correct colors colors_to_press = ", ".join(str(color) for color in translated_colors) return f"Press the following buttons in this order: {colors_to_press}"
def solve_whos_on_first(self, display_word, user_buttons): # Does most of the heavy lifting for solving this module # Check that the display is correct (exists) if self.display_label_instructions[display_word]: # Get the correct button text correct_word = self.display_label_instructions[display_word] button_text = user_buttons[correct_word[0]][correct_word[1]] # Check that the button text is correct (exists) if self.corresponding_label[button_text]: correct_list = self.corresponding_label[ button_text] # Contains the answer that the user would search for return self.get_first_word( correct_list, user_buttons) # Return the correct word else: # Button text that the user entered doesn't exist, try again print_and_wait( "An error occurred. Make sure you type the button text correctly." ) self.start_whos_on_first() else: # Display text that the user entered doesn't exist, try again print_and_wait( "An error occurred. Make sure you type the display correctly.") self.start_whos_on_first()
def get_num_wires(self): # Asks the user how many wires they see try: number_of_wires = int(input("How many wires are there? ")) return number_of_wires except ValueError: # If they don't enter just a number, ask them again print_and_wait("Invalid number of wires. Please try again.") return self.get_num_wires()
def start_simon_says(self, bomb): # Solves and prints the solution to the module bomb_contains_vowel = bomb.vowel_in_serial() # Perform all 4 rounds for curr_round in range(1, 5): num_strikes = bomb.ask_strikes() # Number of strikes changes what color to press, ask each time print_and_wait(self.solve_simon_says(bomb_contains_vowel, num_strikes, curr_round)) return
def enter_batteries(self): # Asks user how many batteries there are on the bomb try: num_batteries = int( input("How many batteries are there on the bomb? ")) return num_batteries except ValueError: print_and_wait("Invalid number of batteries. Please try again.") return self.enter_batteries()
def ask_button_label(self, curr_stage): # Asks for the button position that the user pressed valid_button_labels = ["1", "2", "3", "4"] label = input("What was the value of the button you pressed? ") if label in valid_button_labels: return int(label) else: print_and_wait("That's an invalid label.") return self.ask_button_label(curr_stage)
def ask_led(self): # Asks the user if the wire has a lit LED has_led = input("Does the wire have a lit LED? ") if has_led in self.truthy: return True elif has_led in self.falsy: return False else: print_and_wait("Invalid answer. Please try again.") return self.ask_led()
def ask_position(self, curr_stage): # Asks for the button position that the user pressed valid_positions = ["1", "2", "3", "4"] position = input("What was the position of the button you pressed? ") if position in valid_positions: return int(position) else: print_and_wait("That's an invalid position.") return self.ask_position(curr_stage)
def ask_blue_coloring(self): # Asks the user if the wire has blue coloring has_blue_coloring = input("Does the wire have blue coloring? ") if has_blue_coloring in self.truthy: return True elif has_blue_coloring in self.falsy: return False else: print_and_wait("Invalid answer. Please try again.") return self.ask_blue_coloring()
def get_button_color(self): # Asks for and returns the color of the button button_color = input("What color is the button? ") # Check that the button color is valid if button_color.lower() in self.valid_button_colors: return button_color else: print_and_wait("Invalid button color. Please try again.") return self.get_button_color()
def ask_star(self): # Asks the user if the wire has a star has_star = input("Does the wire have a star? ") if has_star in self.truthy: return True elif has_star in self.falsy: return False else: print_and_wait("Invalid answer. Please try again.") return self.ask_star()
def get_display(self): # Asks for the current number on the display valid_response = ["1", "2", "3", "4"] display = input("What is the number on the display? ") if display in valid_response: return int(display) else: print_and_wait("An error occurred, please check your input.") return self.get_display()
def get_display_word(self): display_word = input( "What word appears on the display? If it's empty, enter `empty`: " ).lower() # Ensure the display word is valid if display_word in self.display_label_instructions: return display_word else: print_and_wait("Invalid display word, please try again.") return self.get_display_word()
def start_passwords(self, bomb): user_characters = self.get_user_letters() # Split the characters up into their seperate columns (each column has 5 characters) split_chars = [ user_characters[i:i + 6] for i in range(0, len(user_characters), 6) ] # Find the word based on the columns of letters word = self.solve(split_chars) print_and_wait(f"The word is `{word}`.") return
def get_user_letters(self): user_input = input( "Enter all letters with no seperation (30 letters total): ") # There are 30 total characters (6 characters x 5 columns) if len(user_input) != 30: print_and_wait( "There was an error with your input. Please try again.") return self.get_user_letters() else: return user_input
def enter_serial(self): # Asks user for serial number of the bomb serial_length = 6 serial_no = input("What's the serial number on the bomb? ").strip() if len(serial_no) != serial_length: print_and_wait( "Invalid serial number. Please re-enter the serial number.") return self.enter_serial() else: return serial_no
def start_wire_sequences(self): # Begins the process of starting a new wire sequence module wire_instance = WireSet() # Get a new module to start fresh print_and_wait( "Ready to start. Please always enter wires from top to bottom!") # Go through each of the 4 rounds of wires for number in range(1, 5): print(f"Round {number}") self.input_wire_level(wire_instance)
def get_symbol_input(self): # Accepts input for a symbol, ensuring it's in the list of all symbols lower_list = [x.lower() for x in self.all_symbols] symbol = input("Enter one of the four symbols: ") # If the symbol is not valid, ask them to re-enter that symbol if symbol.lower() not in lower_list: print_and_wait("That is an invalid symbol. Please refer to the symbols above.") return self.get_symbol_input() else: return symbol
def translate_morse_code(self, morse_code): # Takes the user's morse code and translates it into a word based on the table try: word_list = [ self.morse_code_lookup[x] for x in morse_code.split(' ') ] return ''.join(word_list) except KeyError: # The user interpreted the morse code incorrectly print_and_wait("An error occurred! Please try again.") self.start_morse_code()
def start_button(self, bomb): # Begin the solving! batteries = bomb.num_batteries indicators = bomb.lit_indicators button_color = self.get_button_color() button_text = self.get_button_text() # Print the directions print_and_wait( self.button_sequence(batteries, indicators, button_color, button_text)) return
def start_whos_on_first(self): round_number = 1 while round_number < 4: print(f"Round {round_number}") display_word = self.get_display_word() # Get the display text user_buttons = self.get_all_buttons() # Get the button texts # Solved! print_and_wait( self.solve_whos_on_first(display_word, user_buttons), "Press the following button:") round_number += 1
def get_wire_color(self, number): # Asks for the color of the wire valid_colors = ["red", "blue", "black"] color = input( f"What is the color of the {ordinalize(number)} wire? ").lower() if color not in valid_colors: print_and_wait( "Invalid wire color. Wires are `red`, `blue`, or `black`. Try again." ) return self.get_wire_color(number) else: return color
def get_wire_connection(self, number): # Asks for the letter that the wire is connected to valid_connections = ["a", "b", "c"] connection = input( f"What is the {ordinalize(number)} wire connected to? ").lower() if connection not in valid_connections: print_and_wait( "Invalid wire connection. Connections are `a`, `b`, or `c`. Try again." ) return self.get_wire_connection(number) else: return connection
def ask_wire_count(self): # Asks the user how many wires are in the module try: wire_count = int(input("How many wires are there? ")) # There can only be 1,2,3,4,5, or 6 wires if wire_count in range(1, 7): return wire_count else: raise ValueError( "The wire count must be between 1 and 6 inclusive.") except ValueError: print_and_wait("Invalid wire count. Please try again") return self.ask_wire_count()
def get_led_rows(self): led_row_1 = input("Enter the first row of LED's: ").strip().split() led_row_2 = input("Enter the second row of LED's: ").strip().split() # Validate that the lists are the correct length if self.validate_led_list(led_row_1, led_row_2): led_2d_list = [led_row_1, led_row_2] # Safe because validate_led_list checks for int elems return [[int(element) for element in lst] for lst in led_2d_list] else: print_and_wait( "There was an error with your LED lists. Please try again.") return self.get_led_rows()
def ask_strikes(self): # Gets the number of strikes from the user, which affects the solution try: num_strikes = input( "How many strikes does the bomb have right now? ") if int(num_strikes) not in range(0, 3): raise ValueError( "The bomb can only have 0, 1, or 2 strikes before exploding." ) else: return int(num_strikes) except ValueError: print_and_wait("Invalid number of strikes. Please try again") return self.ask_strikes()
def get_user_pos(self): # Get the starting position of the user try: user_posx = int(input("What is your X position? ")) user_posy = int(input("What is your Y position? ")) if user_posx in range(0, 6) and user_posy in range(0, 6): return (user_posx, user_posy) else: print_and_wait("Invalid coordinates. Please try again.") return self.get_user_pos() except ValueError: print_and_wait("Invalid coordinates. Please try again.") return self.get_user_pos()
def get_goal_pos(self): # Get the position of the goal (red triangle) try: goal_posx = int(input("What is the goal's X position? ")) goal_posy = int(input("What is the goal's Y position? ")) if goal_posx in range(0, 6) and goal_posy in range(0, 6): return (goal_posx, goal_posy) else: print_and_wait("Invalid coordinates. Please try again.") return self.get_goal_pos() except ValueError: print_and_wait("Invalid coordinates. Please try again.") return self.get_goal_pos()
def start_maze(self): # Start solving the module print("The top left corner is `0, 0`. The top right corner is `5, 0") # Collect information indicator_pos = self.get_indicator_pos() user_pos = self.get_user_pos() goal_pos = self.get_goal_pos() maze = self.determine_maze(indicator_pos) # Solve the maze moves = self.solve_maze(indicator_pos, user_pos, goal_pos, maze) print("Solution:") for move in moves: print(move, end=", ") print_and_wait("Done.")
def start_morse_code(self): # Input the actual dots and dashes morse_code = self.get_morse_code() # Convert the morse characters into letters by looking each character up word = self.translate_morse_code(morse_code) try: # Print the resulting frequency if it exists print_and_wait( f"Respond at frequency `3.{self.frequencies[word]}`.") return except KeyError: # The user interpreted the morse code incorrectly print_and_wait("An error occurred! Please try again.") self.start_morse_code()