井字棋中的艾

问题描述 投票:0回答:1

我已经尝试了很多将极小极大算法添加到我的程序中,但它似乎不起作用。我尝试了很多方法,似乎都没有反应,或者报错。有人可以编写一个工作代码,并解释它以帮助我更好地理解这个概念吗?

我尝试遵循多个教程,并做了很多研究。我使用了其他代码并尝试添加我自己的变量。我还尝试为人工智能创建自己的代码。这是代码:

import sys
initstate = [[],[],[]],[[],[],[]],[[],[],[]]

class Gameboard():
    def __init__(self,state):
        self.state = state
    def turn(self,state):
        self.xcount = 0
        self.ocount = 0
        for row in range(3):
            for col in range(3):
                if self.state[row][col] ==["X"]:
                    self.xcount+=1
                elif self.state[row][col] ==["O"]:
                    self.ocount+=1
        
        if self.xcount > self.ocount:
            return "O"
        if self.xcount == self.ocount:
            return "X"
        if self.xcount <self.ocount:
            raise Exception("Position is imposible and therefor is false")
    def action(self,state):
        self.possible = []
        for row in range(0,3):
            for col in range(0,3):
                if state[row][col] == []:
                    
                    self.possible.append([row,col])
        return self.possible
           
    def result(self,state,actionc,actionr):
        state2 = state
        if [actionr, actionc] not in self.action(state):
            raise Exception("you can not place a piece there")
        
        if self.turn(state) == "X":
            state2[actionr][actionc] = ["X"]
        elif self.turn(state) == "O":
             state2[actionr][actionc] = ["O"]
        return state2
    def gamedone(self,state):
        
        for i in range(3):
            if state[i][0] == ["X"]and state[i][1]  == ["X"]and state[i][2] == ["X"] or  state[0][i] == ["X"]and state[1][i]  == ["X"]and state[2][i] == ["X"] or state[0][0] == ["X"] and state[1][1] == ["X"] and state[2][2] == ["X"] or state[0][2] == ["X"] and state[1][1] == ["X"] and state[2][0] ==["X"] :
                return 1
            elif state[i][0] == ["O"]and state[i][1]  == ["O"]and state[i][2] == ["O"] or  state[0][i] == ["O"]and state[1][i]  == ["O"]and state[2][i] == ["O"] or state[0][0] == ["O"] and state[1][1] == ["O"] and state[2][2] == ["O"] or state[0][2] == ["O"] and state[1][1] == ["O"] and state[2][0] ==["O"] :
                return -1
            elif self.action(state) == []:
                return 0
            else:
                return None
    def print(self,state):
        
        for row in state:
            print()
            print("---------")
            for col in row:
                print("|",end="")
                if col == []:
                    print(" ",end="")
                else:
                    print(*col,end="")
                print("|",end="")
        
        print()
    
       
        



        
        
        
    

            
a = Gameboard(initstate)


while a.gamedone(initstate) == None:
    a.print(initstate)
    initstate = a.result(initstate,int(input("row: ")),int(input("col: ")))
print(initstate)        
python minimax
1个回答
0
投票

我不久前编写了这段代码。我不知道它是否完美,但你可以测试一下:

class TicTacToe:
    def __init__(self, size):
        self.size = size
        self.board = [' '] * (size**2)
        self.current_player = 'X'
    
    def copy(self):
        copy = TicTacToe(self.size)
        copy.board = self.board.copy()
        copy.current_player = self.current_player
        return copy
    
    def print_board(self):
        horizontal_line = "----" * self.size + "-"
    
        print(horizontal_line)
        for row in range(self.size):
            for col in range(self.size):
                print("|", self.board[row * self.size + col], end=" ")
            print("|")
            print(horizontal_line)
    
    def make_move(self, position):
        if self.board[position] == ' ':
            self.board[position] = self.current_player
            self.current_player = 'O' if self.current_player == 'X' else 'X'
            return True
        else:
            return False
    
    def _generate_winning_combinations(self):
        winning_combinations = []
    
        # Horizontal combinations
        for row in range(self.size):
            winning_combinations.append([row * self.size + col for col in range(self.size)])
    
        # Vertical combinations
        for col in range(self.size):
            winning_combinations.append([col + row * self.size for row in range(self.size)])
    
        # Diagonal combinations
        diagonal1 = [i * (self.size + 1) for i in range(self.size)]
        diagonal2 = [i * (self.size - 1) for i in range(1, self.size + 1)]
        winning_combinations.append(diagonal1)
        winning_combinations.append(diagonal2)
    
        return winning_combinations
    
    def is_winner(self, player):
        winning_combinations = self._generate_winning_combinations()
        for combination in winning_combinations:
            if all(self.board[i] == player for i in combination):
                return True
        return False
    
    def is_board_full(self):
        return ' ' not in self.board
    
    def game_over(self):
        return self.is_winner('X') or self.is_winner('O') or             self.is_board_full()
    
    def get_valid_moves(self):
        return [i for i in range(self.size ** 2) if self.board[i] == ' ']
    
    
    def minimax(board, maximizing_player, depth, player):
        if board.game_over() or depth == 0:
            if board.is_winner(player):
                return 1
            elif board.is_winner('X' if player == "O" else "O"):
                return -1
            else:
                return 0
    
        if maximizing_player:
            max_score = float('-inf')
            for move in board.get_valid_moves():
                board_copy = board.copy()
                board_copy.make_move(move)
                score = minimax(board_copy, False, depth-1, player)
                max_score = max(score, max_score)
            return max_score
        else:
            min_score = float('inf')
            for move in board.get_valid_moves():
                board_copy = board.copy()
                board_copy.make_move(move)
                score = minimax(board_copy, True, depth-1, player)
                min_score = min(score, min_score)
            return min_score
    
    def best_move(board, max_depth, player="O"):
        best_score = float('-inf')
        best_move = None
    
        for move in board.get_valid_moves():
            board_copy = board.copy()
            board_copy.make_move(move)
            score = minimax(board_copy, False, max_depth-1, player)
    
            if score > best_score:
                best_score = score
                best_move = move
    
        return best_move
© www.soinside.com 2019 - 2024. All rights reserved.