最強の三目並べAI

def cell_click(position): game.play_turn(position) if game.game_running: ai_turn() def ai_turn(): game.stop() score, pos = min_max(game, 1) game.resume() game.play_turn(pos) def reset(): game.start() def update_cells(values): for i, value in enumerate(values, start=1): Element(f"pos-{i}-x").add_class("hidden") Element(f"pos-{i}-o").add_class("hidden") Element(f"pos-{i}-none").add_class("hidden") if value == 0: Element(f"pos-{i}-x").remove_class("hidden") elif value == 1: Element(f"pos-{i}-o").remove_class("hidden") else: Element(f"pos-{i}-none").remove_class("hidden") def display_message(value): Element("message").write(value) def min_max(game, player): opp = 1 if player == 0 else 0 if game.is_winner(1): # COMP win return 10, None elif game.is_winner(0): return -10, None elif game.is_draw(): return 0, None opp = (1 + player) % 2 if player == 1: max_t = -9999 max_c = None for c in game.candidates(): game.move(c, player) t, cc = min_max(game, opp) if max_t < t: max_t = t max_c = c game.back(c) return max_t, max_c else: min_t = 9999 min_c = None for c in game.candidates(): game.move(c, player) t, cc = min_max(game, opp) if min_t > t: min_t = t min_c = c game.back(c) return min_t, min_c class TicTacToe: def start(self): self.player = 0 self.cells = [None] * 9 self.game_running = True display_message('あなたの番') update_cells(self.cells) Element("reset-button").add_class("hidden") def stop(self): self.game_running = False def resume(self): self.game_running = True def play_turn(self, position): if not self.game_running: return if self.cells[position] != None: display_message("Invalid Position") return self.cells[position] = self.player update_cells(self.cells) if not self.is_game_over(): self.next_palyer() else: self.game_running = False Element("reset-button").remove_class("hidden") def next_palyer(self): player_messages = ["あなたの番", "AIの番(考え中...)"] self.player = (self.player + 1) % 2 display_message(player_messages[self.player]) def is_game_over(self): if self.is_winner(self.player): win_messages = ["あなたの勝ち🎉", "あなたの負け😞"] display_message(win_messages[self.player]) self.game_running = False return True if self.is_draw(): display_message("引き分け") self.game_running = False return True return False def is_winner(self, player): win_patterns = [(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)] for a1, a2, a3 in win_patterns: if self.cells[a1] == self.cells[a2] == self.cells[a3] == player: return True return False def is_draw(self): return all(val != None for val in self.cells) def candidates(self): return [i for i,x in enumerate(self.cells) if x == None] def move(self, pos, player): self.cells[pos] = player def back(self, pos): self.cells[pos] = None game = TicTacToe() game.start() import sys sys.setrecursionlimit(3000) # 1000(default)