井字游戏最小最大算法 Python。计算机算法并不稳健

Posted

技术标签:

【中文标题】井字游戏最小最大算法 Python。计算机算法并不稳健【英文标题】:Tic Tac Toe Min Max Algorithm Python. Computer Algorithm is not Robust 【发布时间】:2019-06-19 15:48:37 【问题描述】:

请随意询问清楚,因为这是一个相当长的问题

我有一个井字游戏(X 和 O),由 2 个人类玩家玩时效果很好。

我目前的问题是在尝试对其实施最小最大算法时。我有 4 个构成计算机大脑的功能,它们上面都有一个简短的描述。前两个函数主要用于上下文。

我认为主要的问题要么是如何计算分数,要么是在选择游戏时,许多游戏的分数相同,它会选择第一个得分最高的游戏,这不一定是最佳选择

这里是代码。

# Find All Open Positions On the Current Board
def posis(self):
    return [x for x, coordinate  in enumerate(self.gameBoard) if ((coordinate != 'X') and (coordinate != 'O'))]
# Return All Possible Combinations Given The Current Board State           
def pos_moves(self):
    return [arr for arr in permutations(self.posis())]
# The Computer Plays Every Possible Game Based on self.pos_moves()
# At The End It Returns Each Game and Its Score

def min_max(self,player):
    moves = self.pos_moves()
    pos_boards, scores = [],[]
    for move in moves:
        board = self.gameBoard[:] # This is just the current game board
        depth = 0
        function_player = player

        while True: # This is the loop that each possible game (from pos_moves) goes through for evaluation. at the end giving it a score. 
            board[move[depth]] = function_player
            if ((self.win_checker(board)==True) or (self.board_full(board) != False)):
                if self.win_checker(board) == True:
                    if function_player == player: # Meaning the winner of that game is the computer
                        score = 6-(depth + 1)
                    elif function_player != player: # maening the winner of that game is the human player
                        score = -6+(depth + 1)
                else: # If the game is a draw
                    score = 0
                pos_boards.append(move) # Adding the board to pos_boards
                scores.append(score) # Adding the score to scores with the same index as it's corresponding board from above
                break
            function_player = self.change_player(function_player)
            depth+=1       
    return (pos_boards,scores)
#I Think This Is Where The Problem Is
def comp_think(self,player):
    pos_boards = self.min_max(player)[0]
    scores = self.min_max(player)[1]
    play = pos_boards[scores.index(max(scores))] # this is a supposed to be the best path for the computer to choose. But it's not.
    print(play)
    return str(play[0]) # returning the first move in the best path for the computer to play

这是一个示例游戏:

0 | 1 | 2 
 --------- 
 3 | 4 | 5 
 --------- 
 6 | 7 | 8 


X, Chose a slot: 0 # I play top left

 X | 1 | 2 
 --------- 
 3 | 4 | 5 
 --------- 
 6 | 7 | 8 

(1, 2, 4, 3, 7, 5, 6, 8) #Computer plays top middle but I would like it to play middle middle

 X | O | 2 
 --------- 
 3 | 4 | 5 
 --------- 
 6 | 7 | 8 


X, Chose a slot: 4

 X | O | 2 
 --------- 
 3 | X | 5 
 --------- 
 6 | 7 | 8 

(2, 3, 5, 7, 8, 6)

 X | O | O 
 --------- 
 3 | X | 5 
 --------- 
 6 | 7 | 8 


X, Chose a slot: 8

 X | O | O 
 --------- 
 3 | X | 5 
 --------- 
 6 | 7 | X 

X Wins!!!

在这种情况下,X 是人类玩家

每个元组都是来自 comp_think() 的变量 play。第一步是计算机播放的,第二步是人类玩家。整个元组代表了计算机对自身最佳结果的想法。

【问题讨论】:

【参考方案1】:

我在这里看到的一个潜在错误是计算机选择了可能导致最佳结果的动作。例如,如果它有可能只在 3 步中获胜,它就会做出这样的选择。但是,这假设玩家会做出某些让计算机获胜的动作,这可能不太可能。或许,您不是找到可能获得最高分的单步棋,而是将每个棋步可能出现的所有分数加起来,而最高的总分就是它选择的选项?毕竟,请注意它给出的元组不太可能发生 - 玩家只是忽略了它应该采取的逻辑路径。

此外,您可以在决定得分时降低游戏的深度,即使这很重要 - 为什么让机器人更早获胜有好处?胜利就是胜利。

【讨论】:

我添加深度的原因是计算机可以在 1 步中失败但在 2 步中获胜的情况,它会忽略损失,因此深度是此操作的惩罚。来自深度的一个问题不是 7 步中的损失比 3 步中的获胜更吸引计算机等等。我只需要解决这一切的数学和条件。因为每种方法都适用于非常具体的情况 我见过类似算法的各种实现,但它们是用 C 或 Java 实现的,我还没有开始学习。

以上是关于井字游戏最小最大算法 Python。计算机算法并不稳健的主要内容,如果未能解决你的问题,请参考以下文章

python井字棋算法及代码

蒙特卡洛树搜索:井字游戏的实现

我正在尝试实现一个极小极大算法来创建一个井字游戏机器人,但我遇到了递归错误

python 井字棋 ALPHA-BETA剪枝算法和暴力算法 具体代码

JavaScript写的一个带AI的井字棋

算法训练 最大值与最小值的计算