from fast_P_nim import P def safe_int_parse(s): try: return int(s) except ValueError: return -1 n = int(input("Path size to play on> ")) nimb = P(n) human_turn = -1 # placeholder if nimb > 0: human_turn = False print("I'll play first!") else: human_turn = True print("You can play first!") game_state = [True for _ in range(n)] def display_game(): for i in range(n): if game_state[i]: print(f'{i+1:02d}', end="") else: print(f' ', end="") if i + 1 != n: print('-', end="") print() def valid_move(i): if i >= n or i < 0: return False if game_state[i]: if i > 0: if i < n-1: return game_state[i-1] or game_state[i+1] else: return game_state[i-1] else: if i < n-1: return game_state[i+1] else: return True def make_move(i): gs = game_state.copy() gs[i] = False if i > 0: gs[i-1] = not gs[i-1] if i < n-1: gs[i+1] = not gs[i+1] return gs def get_nimber(gs): nimber_so_far = 0 path_size = 0 for i in range(n): if gs[i]: path_size += 1 else: if path_size == 1 and n != 1: path_size = 0 nimber_so_far = nimber_so_far ^ P(path_size) path_size = 0 if path_size == 1 and n != 1: path_size = 0 nimber_so_far = nimber_so_far ^ P(path_size) return nimber_so_far def i_have_won(): for i in range(n): if valid_move(i): return False return True def find_move(): game_state_orig = game_state.copy() for i in range(n): if valid_move(i): gs = make_move(i) if get_nimber(gs) == 0: return i raise Exception("I have been beat!") # game_state = make_move(2-1) # game_state = make_move(6-1) # game_state = make_move(6-1) # display_game() # print(get_nimber(game_state)) # raise Exception() while True: display_game() if human_turn: if i_have_won(): print("You're out of moves. I win!") break human_turn = False i = -1 # placeholder while True: i = safe_int_parse(input("Make your move> ")) - 1 if valid_move(i): break print("Hey! That's not allowed!") display_game() game_state = make_move(i) else: human_turn = True i = find_move() print(f"Hmm... I'll toggle {i + 1}") game_state = make_move(i)