Visualize
main.py
import random RED = "\033[31m" RESET = "\033[0m" MODES = ("human", "dumb-bot", "smart-bot", "genius-bot") def new_board(): return [[None, None, None], [None, None, None], [None, None, None]] def render(init_board): print(" 0 1 2") print(" ---------") for i in range(3): print(f"{i} | ", end="") for j in range(3): if init_board[i][j] is None: print(" ", end="") else: print(init_board[i][j], end="") print(" ", end="") print("|") print(" ---------") def human_player(init_board, symbol): x = None y = None while True: try: x = int(input("What is your move's X co-ordinate?: ")) if x > 2 or x < 0: print(f"{RED} Number has to be between 0-2 {RESET}") continue y = int(input("What is your move's Y co-ordinate?: ")) if y > 2 or y < 0: print(f"{RED} Number has to between 0-2 {RESET}") continue break except ValueError: print(f"{RED} Enter a NUMBER {RESET}") continue return x, y def make_move(init_board, cords, symbol): temp_board = init_board x = cords[0] y = cords[1] # x, y = cords temp_board[y][x] = symbol return temp_board def is_valid_move(init_board, cords): return init_board[cords[1]][cords[0]] is None def get_winner(init_board): # Rows for row in init_board: if len(set(row)) == 1 and row[0] is not None: return row[0] # Columns if len({init_board[0][0], init_board[1][0], init_board[2][0]}) == 1 and init_board[0][0] is not None: return init_board[0][0] if len({init_board[0][1], init_board[1][1], init_board[2][1]}) == 1 and init_board[0][1] is not None: return init_board[0][1] if len({init_board[0][2], init_board[1][2], init_board[2][2]}) == 1 and init_board[0][2] is not None: return init_board[0][2] # Diagonals if len({init_board[0][0], init_board[1][1], init_board[2][2]}) == 1 and init_board[0][0] is not None: return init_board[0][0] if len({init_board[0][2], init_board[1][1], init_board[2][0]}) == 1 and init_board[0][2] is not None: return init_board[0][2] return None def check_draw(init_board): for row in init_board: for space in row: if space is None: return False return True def get_legal_moves(init_board): legal_moves = [] for r_indx, row in enumerate(init_board): for c_indx, space in enumerate(row): if space is None: legal_moves.append((c_indx, r_indx)) return legal_moves def random_ai(init_board, symbol): return random.choice(get_legal_moves(init_board)) def find_winning_move(init_board, symbol): legal_moves = get_legal_moves(init_board) for x, y in legal_moves: init_board = make_move(init_board, (x, y), symbol) if get_winner(init_board) == symbol: init_board[y][x] = None return x, y init_board[y][x] = None return None def find_losing_move(init_board, symbol): symbol = player1 if symbol == player2 else player2 legal_moves = get_legal_moves(init_board) for x, y in legal_moves: init_board = make_move(init_board, (x, y), symbol) if get_winner(init_board) == symbol: init_board[y][x] = None return x, y init_board[y][x] = None return None def finds_winning_moves_ai(init_board, symbol): winning_move = find_winning_move(init_board, symbol) if winning_move: return winning_move return random_ai(init_board, symbol) def finds_winning_and_losing_moves_ai(init_board, symbol): winning_move = find_winning_move(init_board, symbol) if winning_move: return winning_move losing_move = find_losing_move(init_board, symbol) if losing_move: return losing_move return random_ai(init_board, symbol) def use_mode(mode, init_board, symbol): if mode == "human": return human_player(init_board, symbol) if mode == "dumb-bot": return random_ai(init_board, symbol) if mode == "smart-bot": return finds_winning_moves_ai(init_board, symbol) if mode == "genius-bot": return finds_winning_and_losing_moves_ai(init_board, symbol) return None if __name__ == '__main__': player1 = "X" player2 = "O" current_player = player1 print(MODES) player1_mode = None player2_mode = None while True: player1_mode = input(f"What will player '{player1}' be: ") if player1_mode not in MODES: print(f"{RED} Mode has to be {MODES} {RESET}") continue player2_mode = input(f"What will player '{player2}' be: ") if player2_mode not in MODES: print(f"{RED} Mode has to be {MODES} {RESET}") continue break board = new_board() while True: print("***************") print(f"Player '{current_player}' turn") print("---------------") render(board) move_coords = None while True: if current_player == player1: move_coords = use_mode(player1_mode, board, current_player) elif current_player == player2: move_coords = use_mode(player2_mode, board, current_player) if is_valid_move(board, move_coords): break else: print(f"{RED} Invalid move, try again {RESET}") board = make_move(board, move_coords, current_player) winner = get_winner(board) if winner is not None: print("***************") print(f" Player {winner} Wins") print("---------------") render(board) break if check_draw(board): print("***************") print(" DRAW ") print("---------------") render(board) break current_player = player2 if current_player == player1 else player1
Output