def play(self): self.gameState = State() while not self.gameState.game_over(): player1Action = self.player1.choose_action(self.gameState) self.gameState.execute(player1Action) util.pprint(self.gameState) if self.gameState.game_over(): break player2Action = self.player2.choose_action(self.gameState) self.gameState.execute(player2Action) util.pprint(self.gameState) return self.gameState.winner()
def __init__(self, state: State = State(), p1: Player = None, p2: Player = None): self.state = state self.p1 = p1 self.p2 = p2
def choose_action(self, state: State = None) -> Action: struct = self.minimax(state) action = struct[0] #print("Chosen action =", action) if struct[1] == -1 * float("inf"): #print("CONCESSION") return random.choice(state.actions(self.character)) return action
def heuristic(state: State = None, playerchar: str = None): # -> a number boi if state.game_over(): if state.winner() == playerchar: return float("inf") elif state.winner() != None: # Opponent wins return -1 * float("inf") else: return 0 score = 0 # number of player's pieces adjacent to open spaces # - number of opponent's pieces adjacent to open spaces for col in range(4): for row in range(3): if (piece := state.get(col, row)) and piece == " ": deltas = [-1, 0, +1] for dx in deltas: for dy in deltas: if None == (adjacent_piece := state.get(col+dx, row+dy)): continue if adjacent_piece == playerchar: # player's piece score += 1 elif adjacent_piece != " ": # opponent's piece score -= 1 else: # empty score += 0
class Game: gameState = None player1 = None player2 = None def __init__(self, player1, player2): self.player1 = player1 self.player2 = player2 def play(self): self.gameState = State() while not self.gameState.game_over(): player1Action = self.player1.choose_action(self.gameState) self.gameState.execute(player1Action) util.pprint(self.gameState) if self.gameState.game_over(): break player2Action = self.player2.choose_action(self.gameState) self.gameState.execute(player2Action) util.pprint(self.gameState) return self.gameState.winner()
def choose_action(self, state: State = None) -> Action: if state: print("Choose your action") actions = state.actions(self.character) for a in enumerate(actions): print(str(a[0]) + ":", a[1]) choice = input("Please choose an action (0-" + str(len(actions) - 1) + "): ") while choice == "" or not (0 <= int(choice) < len(actions)): choice = input("Please choose an action (0-" + str(len(actions) - 1) + "): ") choice = int(choice) return actions[choice]
def minimax(self, state: State, depth = MINIMAX_LOOKAHEAD, func = heuristic): def _max(): return ((MINIMAX_LOOKAHEAD - depth) % 2) == 0 #tabs = " "*(MINIMAX_LOOKAHEAD - depth) state = state.clone() # Don't modify the game state! if depth == 0: score = heuristic(state=state, playerchar=self.character) try: action = random.choice(state.actions(self.character)) except: action = None #print(tabs+"score =", score) else: if _max(): #print(tabs+"Looking for MAX") score = -1 * float("inf") action = None for a in state.actions(self.character): #print(tabs+"- considering action", a) nextState = state.clone().execute(a) s = self.minimax(nextState, depth=depth-1)[1] if s > score: action = a score = s #print(tabs+"MAX score =", score) else: # _min() #print(tabs+"Looking for MIN") score = float("inf") action = None opponent_character = "O" if self.character == "X" else "X" for a in state.actions(opponent_character): #print(tabs+"- considering action", a) nextState = state.clone().execute(a) s = self.minimax(nextState, depth=depth-1)[1] if s < score: action = a score = s #print(tabs+"MIN score =", score) score = score - depth return (action, score)
def choose_action(self, state: State = None) -> Action: return random.choice(state.actions(self.character))
from connect3 import State, util from game import Game from human import HumanPlayer from agent import RandomPlayer, MinimaxPlayer def make_player(p: str = "", c: str = ""): if p[0] == "h": return HumanPlayer(c) if p[0] == "r": return RandomPlayer(c) if p[0] == "m": return MinimaxPlayer(c) print("Please enter a valid player string: [human, random, minimax]") exit() p1 = util.get_arg(1) p2 = util.get_arg(2) print(p1, "vs.", p2) if p1 and p2: p1 = make_player(p1, 'X') p2 = make_player(p2, 'O') print(p1, "vs.", p2) game = Game(state=State(), p1=p1, p2=p2) hist = game.play() print("Game over!", hist.pop(0), "wins!") util.pprint(hist) else: print("Usage: python3 main.py PlayerType PlayerType")