【问题标题】:minimax function not generating all game statesminimax 函数不生成所有游戏状态
【发布时间】:2016-12-04 02:15:50
【问题描述】:

谁能告诉我为什么我的代码打印的是1 而不是8?它似乎没有经历非常单一的状态。这是为什么?

使用 minimax 算法,根据游戏状态(可能的井字棋盘)找到可能做出的最佳移动。通常,它会分支成一个大的游戏状态树,当游戏没有以结束状态结束时调用每个新分支,重复,然后通过递归地沿着树找到最佳可能的移动,为每个分支找到最佳移动播放器。

我正在关注http://giocc.com/concise-implementation-of-minimax-through-higher-order-functions.html 的“教程”。

我的代码:

#!/usr/bin/env python3
'''Minimax finds the best possible moves by applying a set of rules.
A win = 1, tie = 0, loss = -1 (for us). Assuming that each player chooses the best move
(we choose 1 if possible, opponent chooses -1). Starting at the top of a 'game tree',
generate the possible moves we can make. If It reaches a terminal state, stop. Otherwise keep searching in depth.
We find max.
'''
#[0,1,2,3,4,5,6,7,8]
class GameState: #a game state is a certain state of the board
    #http://stackoverflow.com/questions/1537202/variables-inside-and-outside-of-a-class-init-function
    x_went_first = True
    def __init__(self,board):
        self.board = board
        self.winning_combos = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,8]]
    def is_gameover(self):
        if self.board.count('X') + self.board.count('O') == 9:
            return True
        for combo in self.winning_combos:
            if (self.board[combo[0]] == 'X' and self.board[combo[1]] == 'X' and self.board[combo[2]] == 'X') or (self.board[combo[0]] == 'O' and self.board[combo[1]] == 'O' and self.board[combo[2]] == 'O'):
                return True
        return False
    def get_possible_moves(self):
        squares = []
        for square in self.board:
            if square != 'X' and square != 'O':
                squares.append(int(square))
        return squares
    def get_next_state(self, move):
        copy = self.board
        num_of_x = copy.count('X')
        num_of_o = copy.count('O')
        #x starts, o's turn 1 > 0 o's turn
        #o starts, x's turn 1 < 0 x's turn
        #x starts, x's turn 1 > 1 
        #o starts, o's turn 1 < 1
        if (self.x_went_first and num_of_x > num_of_o) or (self.x_went_first is not True and num_of_o == num_of_x):
            copy[move] = 'O'
        else:
            copy[move] = 'X'
        return GameState(copy)

def evals(game_state):
    for combo in [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,8]]:
        if game_state.board[0] == 'X' and game_state.board[1] == 'X' and game_state.board[2] == 'X':
            return 1    
        elif game_state.board[0] == 'O' and game_state.board[1] == 'O' and game_state.board[2] == 'O':
            return -1
        else:
            return 0



def min_play(game_state):
    if game_state.is_gameover():
        return evals(game_state)
    moves = game_state.get_possible_moves()
    best_move = moves[0]
    best_score = 2 #not possible, best score is -1
    for move in moves:
        clone = game_state.get_next_state(move)
        score = max_play(clone)
        if score < best_score:
            best_move = move
            best_score = score
    return best_score

def max_play(game_state):
    if game_state.is_gameover():
        return evals(game_state)
    moves = game_state.get_possible_moves()
    best_score = -2 #not possible, best score is 1
    for move in moves:
        clone = game_state.get_next_state(move)
        score = min_play(clone)
        if score > best_score:
            best_move = move
            best_score = score
    return best_score

def minimax(game_state):
    moves = game_state.get_possible_moves()
    best_move = moves[0]
    best_score = -2
    for move in moves:
        clone = game_state.get_next_state(move)
        score = min_play(clone)
        if score > best_score:
            best_move = move
            best_score = score
    return best_move


game = GameState(['X',1,2,
                    3,'O',5,
                    6,7,8])
print(minimax(game))

【问题讨论】:

  • 你至少应该解释一下你的程序要做什么...... 没有解释就转储 100 行代码不太可能引起任何注意...... How to Ask
  • print 是你的朋友。到处插入打印语句,看看发生了什么。如果您有 ide,请逐步调试。

标签: python python-3.x minimax


【解决方案1】:

我的evals 总是返回0,其中一个获胜组合搞砸了。新评估:

def evals:
    for combo in [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]:
        if game_state.board[0] == 'X' and game_state.board[1] == 'X' and game_state.board[2] == 'X':
            return 1    
        elif game_state.board[0] == 'O' and game_state.board[1] == 'O' and game_state.board[2] == 'O':
            return -1
     return 0

我还对其进行了修改,因此索引不在每个空槽中。在https://github.com/retep-mathwizard/pyai/blob/master/minimax_ttt查看完整代码

【讨论】:

    猜你喜欢
    • 2017-11-26
    • 1970-01-01
    • 2022-07-18
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 2015-07-21
    相关资源
    最近更新 更多