def get_all_possible_board_states(turn_num, primary_state, secondary_state): """ Loops through all possible states of the board starting from the turn_num provided and ending on the last turn. Finally, collates them in a list :param turn_num: type: int The number of moves on the board :param primary_state: type: int The state of the player that had the first move, HUMAN_STATE or BOT_STATE :param secondary_state: type: int The state of the player that had the second move, HUMAN_STATE or BOT_STATE :return: type: list Containing all the possible board states given a turn number """ # Check for valid turn number if turn_num < 0 or turn_num > 9: raise ValueError("Turn number must be between 0 and 9") # Return blank board for turn 0 if not turn_num: return create_board() boards = [] temp_boards = [] board = create_board() # Player for that turn number for move in combinations(get_possible_moves(board), ceil(turn_num / 2)): temp_boards.append(deepcopy(board)) for row, box in move: temp_boards[-1][row][ box] = secondary_state if turn_num % 2 == 0 else primary_state # Other player for board in temp_boards: for move in combinations(get_possible_moves(board), floor(turn_num / 2)): boards.append(deepcopy(board)) for row, box in move: boards[-1][row][ box] = primary_state if turn_num % 2 == 0 else secondary_state # Remove all won/terminal board states if win_check(boards[-1]): del boards[-1] return boards
def test_blank_board(): """ Testing for result consistency between the 3 approaches to minimax algorithm Testing algorithm result from evaluating a blank board """ board = create_board() minimax_result = minimax(board, get_depth(board), True) minimax_soft_alpha_beta_result = minimax_soft_alpha_beta( board, get_depth(board), True, -inf, +inf) minimax_alpha_beta_result = minimax_alpha_beta(board, get_depth(board), True, -inf, +inf) assert minimax_result == minimax_soft_alpha_beta_result assert minimax_alpha_beta_result[0] == minimax_result[0] assert minimax_alpha_beta_result[1][0] in minimax_result[1]
def __init__(self, name): Player.__init__(self, name) self.city_edges, self.edges = board.create_board() self.path = None self.path_costs = {} self.edge_costs = {} self.all_paths = [] self.info = None self.edge_claims = None self.action_history = [] self.cards_needed = Counter() self.remaining_edge = [] self.path_clear = False # self.gui = None self.opponent_name = [] self.player_cars_count = {} self.possible_cards = [] self.bug_showed = False
def main(): """ The main function of the application. Creates the board, players and loop their turns infinitely until a winner is found. """ # Introduction print( "Welcome to the game of Tic Tac Toe, your opponent is a bot running the Minimax algorithm" ) # Create Tic Tac Toe board board = create_board() # Create players human_mark, bot_mark = choose_mark() bot = Player(bot=True, state=BOT_STATE, mark=bot_mark) human = Player(bot=False, state=HUMAN_STATE, mark=human_mark) # Random starting player players = [human, bot] random.shuffle(players) # Loop turns while True: for player in players: print("\n{}'s turn".format( player_name := "Bot" if player.bot else "Human")) move = player.make_move(board) update_board(board, move, player) display_board(board, players) # Break infinite loop under conditions if win_check(board): return print("Game over. {} wins!".format(player_name)) elif is_board_full(board): return print("Game over. Draw!")
def main(): """ The main function of the game. Responsible for the setup of game window properties, creating players, scheduling scenes in the game, recording player statistics and looping the game. """ # Setup game screen, clock = setup_game() # Create list of players players = [] # Define whose turn player = None # Define stats recording records = { # Record turn number 'turn_num': 0, # Record bot wins 'bot_win': 0, # Record human wins 'human_win': 0, # Record draws 'draw': 0 } # Define screen states intro = True game = True # Create a blank Tic Tac Toe board board = create_board() # Game loop while True: # tick rate clock.tick(30) mouse_position = pygame.mouse.get_pos() mouse_clicked = False for event in pygame.event.get(): # Break loop if window is closed if event.type == pygame.QUIT: pygame.quit() sys.exit() # Break loop if ESC key is pressed elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_clicked = True # White background/clear previous objects screen.fill(color_to_rgb("white")) if intro: # Draw selection screen interface_items = selection_screen(screen, mouse_position) render_items_to_screen(screen, interface_items) # Handle user input if mouse_clicked: human_input_selection_screen_handler(interface_items, players, mouse_position) # Proceed to next screen if user selected a choice & assign players if players: # Unpack players bot, human = players[0], players[1] # Random starting player player = random.choice(players) # Move on to game screen intro = False elif game: # Game scene # Draw board information interface_items = board_information(screen, records) render_items_to_screen(screen, interface_items) # Draw tic tac toe board interface_items = game_board(screen, board, players) render_items_to_screen(screen, interface_items) # Check if game is finished if win_check(board): # Game is finished # Highlight the winning row interface_items = highlight_win(interface_items, board) render_items_to_screen(screen, interface_items) # Add delay post_game_delay() # Record stats record_win(player, records) # Reset board board = create_board() # Next game, random starting turn again player = random.choice(players) elif is_board_full(board): # Game is finished # Add delay post_game_delay() # Record stats record_draw(records) # Reset board board = create_board() # Next game, random starting turn again player = random.choice(players) else: # Game not finished # Make a move (bot/human) if player.bot: # Bot turn bot_move_input_handler(board, bot) else: if mouse_clicked: # Human turn human_move_input_handler(board, interface_items, mouse_position, human) # Cycle turns if get_turn_number(board) != records["turn_num"]: if not win_check(board) and not is_board_full(board): # Subsequent turns player = human if player.bot else bot records["turn_num"] = get_turn_number(board) # Update screen pygame.display.update()
def __init__(self, x_size=20, y_size=10): print('initializing gui') img = mpimg.imread('../gui/world2.png') plt.ion() # uncomment to let go of string self.fig = plt.figure( figsize=(x_size, y_size)) # uncomment to let go of string imgplot = plt.imshow(img) plt.xlim([0, 1080]) plt.ylim([700, 0]) imgplot.axes.get_xaxis().set_visible(False) imgplot.axes.get_yaxis().set_visible(False) self.needs_reset = False # imgplot = plt.imdraw(img) self.place_cities() self.plot_board() self.set_colors() [city_edges, edges] = create_board() x_offset = 5 y_offset = 5 # Plot the edges for connecting cities for index1, edge in enumerate(edges): offset = 0 for index2, edge2 in enumerate(edges): # Check if this is a double edge if edge.city1 is edge2.city1 and edge.city2 is edge2.city2 and edge is not edge2: if (index1 > index2): offset = -1 else: offset = 1 x_1 = [] y_1 = [] x_1.append(self.cities[edge.city1][0] + offset * x_offset) y_1.append(self.cities[edge.city1][1] + offset * y_offset) x_1.append(self.cities[edge.city2][0] + offset * x_offset) y_1.append(self.cities[edge.city2][1] + offset * y_offset) self.edge_colors[edge] = plt.plot(x_1, y_1, self.colors[edge.color]) plt.setp(self.edge_colors[edge], linewidth=4) x_mean = (x_1[0] + x_1[1]) / 2 y_mean = (y_1[0] + y_1[1]) / 2 self.edge_means[edge] = [x_mean, y_mean] self.edge_weights[edge] = plt.plot(x_mean, y_mean, 'go') plt.setp(self.edge_weights[edge], 'ms', 15.0) self.edge_numbers[edge] = plt.text(x_mean - 5, y_mean + 5, str(edge.cost), fontdict=None) for city in self.cities: self.city_points[city] = plt.plot(self.cities[city][0], self.cities[city][1], 'ro') self.city_texts[city] = plt.text(self.cities[city][0] - 5, self.cities[city][1] + 5, '', fontdict=None) # Plot the numbers of cards player 1 and 2 have # First for player 1 x = 705 y = 33 i = 0 for i in range(9): self.player_1_cards[str(i)] = plt.text(x, y, '0', fontdict=None) x = x + 22 self.p1_score = plt.text(x + 77, y, '0', fontdict=None) self.p1_cars = plt.text(x + 22, y, '0', fontdict=None) # Next for player 2 x = 705 y = 103 i = 0 for i in range(9): self.player_2_cards[str(i)] = plt.text(x, y, '0', fontdict=None) x = x + 22 self.p2_score = plt.text(x + 77, y, '0', fontdict=None) self.p2_cars = plt.text(x + 22, y, '0', fontdict=None) self.cards['0'] = mpimg.imread('../gui/red.png') self.cards['1'] = mpimg.imread('../gui/orange.png') self.cards['2'] = mpimg.imread('../gui/blue.png') self.cards['3'] = mpimg.imread('../gui/yellow.png') self.cards['4'] = mpimg.imread('../gui/green.png') self.cards['5'] = mpimg.imread('../gui/pink.png') self.cards['6'] = mpimg.imread('../gui/black.png') self.cards['7'] = mpimg.imread('../gui/white.png') self.cards['8'] = mpimg.imread('../gui/wild.png') i = 0 x = 0.858 y = 0.78 for i in range(5): self.table_card_slots.append( self.fig.add_axes([x, y - 0.020 * i, 0.034, 0.016], 'auto_scale_on')) self.table_card_slots[i].get_xaxis().set_visible(False) self.table_card_slots[i].get_yaxis().set_visible(False) plt.draw()