def test_select_dud_entry_game_over(): """Ensure select action on dud entry with game over.""" tester = Backend(DEFAULT_ADVANCED, ewlaps, 4, True) location = find_entry(0, tester) line = tester._interactive._active_col[location[0]][location[1]] location = find_entry(0, tester) for count in range(1, 5): if count != 4: assert tester.select(bool(location[0]), location[1], line.start) == "d" assert tester.game_state == 0 else: assert tester.select(bool(location[0]), location[1], line.end) == "l" assert tester.game_state == -1 assert tester.tries == 4 - count
def test_select_secret_entry_secret(_): """Ensure select action on secret when selected correctly.""" tester = Backend(DEFAULT_ADVANCED, ewlaps, 4, True) location = find_entry("s", tester) line = tester._interactive._active_col[location[0]][location[1]] pre_select_grid = [] post_select_grid = [] for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): pre_select_grid.append(tester.full_row_str(index)[:40]) action = tester.select(bool(location[0]), location[1], line.start) assert action == "s" assert tester._interactive._active_col[location[0]][location[1]].similarity == "e" # Assert feedback responce = ">" + line.word assert responce in tester.full_row_str(13)[-14:] action_a = ">Dud Removed " in tester.full_row_str(14)[-14:] action_b = ">Tries Reset " in tester.full_row_str(14)[-14:] assert action_a ^ action_b assert "> " in tester.full_row_str(15)[-14:] assert tester.game_state == 0 # limited Changes for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): post_select_grid.append(tester.full_row_str(index)[:40]) if action_a: assert pre_select_grid != post_select_grid # Grid did change elif action_b: assert pre_select_grid == post_select_grid # Grid did not change else: raise RuntimeError("Action not taken") assert tester.tries == 4 # Tries does not change on error.
def test_select_exception(): """Ensure select throws exception when intended.""" tester = Backend(DEFAULT_EXPERT, ewlaps, 4, True) tester._state = 1 # win with pytest.raises(RuntimeError): tester.select(0, 0, 0) tester._state = -1 # loss with pytest.raises(RuntimeError): tester.select(0, 0, 0)
def test__init__(): """Ensure that the backend init without issue and correct tries.""" for setting in [DEFAULT_EASY, DEFAULT_ADVANCED, DEFAULT_EXPERT, DEFAULT_MASTER]: tester = Backend(setting, ewlaps, 4, True) assert tester.tries == tester._tries assert tester.tries == 4 assert tester._tries_original == 4 assert tester.game_state == 0 assert tester.settings == setting
def commands() -> Backend: """Parse command line arguments and returns grid.""" parser = argparse.ArgumentParser( description="Python Game to Emulate Fallout 4 hacking Module", epilog="Disclaimer: Not made or endorsed by Bethesda (fan-made Game)", ) help_action = """ Set Game Difficulty easy - word size between 3 and 5 advance - word size between 6 and 8 expert - word size between 9 and 10 master - word size between 11 and 12 """ parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("action", choices=("easy", "advanced", "expert", "master"), help=help_action) parser.add_argument( "-t", "--tries", help="Number of tries", type=int, default="4", choices=range(3, 11), ) parser.add_argument( "-s", "--secret", help="increases difficulty by disabling secret chars.", action="store_false", ) args = parser.parse_args() if args.action == "easy": difficulty: SettingGrid = DEFAULT_EASY elif args.action == "advanced": difficulty = DEFAULT_ADVANCED elif args.action == "expert": difficulty = DEFAULT_EXPERT elif args.action == "master": difficulty = DEFAULT_MASTER else: parser.error(f"Unknown action ({args.action})") return Backend(difficulty, ewlaps, args.tries, args.secret)
def test_hover(): """Ensure hover is working only printing to feedback, hover line.""" tester = Backend(DEFAULT_ADVANCED, ewlaps, 4, True) # password location = find_entry("p", tester) line = tester._interactive._active_col[location[0]][location[1]] tester.hover(bool(location[0]), location[1], line.start) assert tester._non_interactive.feedback_col[-1].strip() == ">" + line.word assert tester.game_state == 0 # Invalid Secret (not front) location = find_entry("s", tester) line = tester._interactive._active_col[location[0]][location[1]] if line.start == 0: tester.hover(bool(location[0]), location[1], line.end + 1) char = line.line[line.end + 1] else: tester.hover(bool(location[0]), location[1], line.start - 1) char = line.line[line.start - 1] assert tester._non_interactive.feedback_col[-1] == ">" + char + " " assert tester.game_state == 0
def test_select_dud_entry_not_lost(): """Ensure select action on dud entry without game over.""" tester = Backend(DEFAULT_ADVANCED, ewlaps, 4, True) location = find_entry(0, tester) line = tester._interactive._active_col[location[0]][location[1]] pre_select_grid = [] post_select_grid = [] for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): pre_select_grid.append(tester.full_row_str(index)[:40]) action = tester.select(bool(location[0]), location[1], line.start) assert action == "d" # Assert feedback assert ">Entry Denied." in tester.full_row_str(13)[-14:] assert ">Likeness = 0 " in tester.full_row_str(14)[-14:] assert "> " in tester.full_row_str(15)[-14:] assert ">" + line.word in tester.full_row_str(12)[-14:] assert tester.game_state == 0 # limited Changes for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): post_select_grid.append(tester.full_row_str(index)[:40]) assert pre_select_grid == post_select_grid # Grid did Not change assert tester.tries == 3 # Tries change on Dud.
def test_select_error_entry(): """Ensure select action on error entry.""" tester = Backend(DEFAULT_ADVANCED, ewlaps, 4, True) location = find_entry("e", tester) pre_select_grid = [] post_select_grid = [] for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): pre_select_grid.append(tester.full_row_str(index)[:40]) action = tester.select(bool(location[0]), location[1], 0) assert action == "e" # Assert feedback assert "> " in tester.full_row_str(15)[-14:] assert ">error" in tester.full_row_str(14)[-14:] assert tester.game_state == 0 # No Changes for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): post_select_grid.append(tester.full_row_str(index)[:40]) assert pre_select_grid == post_select_grid # Grid did Not change assert tester.tries == 4 # Tries does not change on error.
def test_select_password_entry(): """Ensure select action on password entry.""" tester = Backend(DEFAULT_ADVANCED, ewlaps, 4, True) location = find_entry("p", tester) line = tester._interactive._active_col[location[0]][location[1]] pre_select_grid = [] post_select_grid = [] for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): pre_select_grid.append(tester.full_row_str(index)[:40]) action = tester.select(bool(location[0]), location[1], line.start) assert action == "p" # Assert feedback assert ">Entry Allowed" in tester.full_row_str(14)[-14:] assert "> " in tester.full_row_str(15)[-14:] assert tester.game_state == 1 # No Changes for index in range(DEFAULT_ADVANCED.NUM_OF_ROWS): post_select_grid.append(tester.full_row_str(index)[:40]) assert pre_select_grid == post_select_grid # Grid did Not change assert tester.tries == 4 # Tries does not change on error.
def test_full_row_str(): """Ensure the correct row is printed.""" tester = Backend(DEFAULT_EASY, ewlaps, 4, False) line_length = ( DEFAULT_EASY.HEX_LINE_SIZE * 2 + DEFAULT_EASY.ACTIVE_LINE_SIZE * 2 + DEFAULT_EASY.FEEDBACK_LINE_SIZE + 4 ) assert len(tester.full_row_str(0)) == line_length assert isinstance(tester.full_row_str(9), str) assert len(tester.full_row_str(15)) == line_length assert tester.full_row_str(0)[:6] == tester._non_interactive.left_hex[0] assert tester.full_row_str(5)[-14:] == tester._non_interactive.feedback_col[5] with pytest.raises(IndexError): tester.full_row_str(99) with pytest.raises(IndexError): tester.full_row_str(-1)
def main(stdscr: Any, grid: Backend) -> Tuple[str, int]: """ Set up Main loop and run main game loop. Call this function 'curses.wrapper'. :param stdscr: Curses screen :param grid: game grid :return: Game message and exit code """ line_start: int = 4 action: str = "" player = Interface(line_start, grid.settings) if curses.has_colors(): curses.start_color() curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) else: return "Terminal does not support Color", 4 terminal_x: int = 1 # Must be a min of 54 terminal_y: int = 1 # Must be a min of 21 selected: bool = False while True: if curses.is_term_resized(terminal_y, terminal_x): terminal_y, terminal_x = stdscr.getmaxyx() if terminal_x <= 54 or terminal_y <= 21: return "The terminal is too narrow (min 54) or short (min 21)", 3 stdscr.clear() stdscr.addstr(0, 0, "Welcome to ROBCO Industries (TM) TermLink", curses.color_pair(2)) stdscr.addstr(1, 0, "Password Required", curses.color_pair(2)) if grid.tries == 1: color: int = 1 else: color = 2 # chr(9608) is black bar stdscr.addstr( 2, 0, "Attempts Remaining: " + f"{chr(9608)} " * grid.tries, curses.color_pair(color), ) for i in range(line_start, grid.settings.NUM_OF_ROWS + line_start, 1): stdscr.addstr(i, 0, grid.full_row_str(i - line_start), curses.color_pair(2)) # Move cursor back to position stdscr.move(player.line, player.place) key: str = stdscr.getkey() action = player.keyboard_input(key) if action == "Q": return "Game Quit", 0 if action == "S": selected = True # Update cursor location stdscr.move(player.line, player.place) offset_local = player.exact_grid_location() if selected: result: str = grid.select(not offset_local[0], offset_local[1], offset_local[2]) selected = False if result == "p": return "Game Won: Password Found", 0 if result == "l": return "Game Over: Attempts Exhausted", 0 continue # Ensure update after pressing enter else: grid.hover(not offset_local[0], offset_local[1], offset_local[2]) stdscr.refresh() curses.doupdate()