为什么我的极小极大算法不能撤消每一步?

扫地机

我正在为我制作的原始 4 人棋盘游戏创建一个 AI。

棋盘游戏详情:

4 名玩家轮流在四个主要方向之一同时移动他们的彩色棋子。棋子可以移出棋盘。玩家在开始时每人有 5 条生命。每移出一块棋子,玩家就会失去 1 点生命。新作品将在整个游戏中确定性地产生。

我查找了如何进行极小极大算法并找到了这个我通读了一遍并认为我理解了所有内容,因此我尝试将第 1.5 节中的 Java 代码翻译成 Swift。

以下是我的思考过程:

  • 由于我的游戏有 4 个玩家,我会将其他人视为最小化玩家。
  • 在 Java 代码中,有一行用于撤消移动。由于我的游戏状态在每次移动中都会发生巨大变化,我会将所有游戏状态存储在一个数组中,当需要撤消某些操作时,我可以调用dropLast该数组。
  • 由于我的游戏中的移动被表示为一个Direction枚举,(Int, Direction)如果像 Java 代码这样的 int 数组,我将返回一个元组。
  • game 是一个只返回的计算属性 gameStates.last!
  • game.currentPlayer每次我调用 上的moveUp/Down/Left/Right方法之一时都会改变game,所以我不需要编写额外的代码来决定谁是下一个玩家。
  • 在最后一行,我需要 return (bestScore, bestDirection),但我意识到有时bestDirection没有分配。因此,我做了bestDirection一个可选的。如果它没有在 return 语句中赋值,我将只返回一个任意方向。

这是我的尝试:

private func minimax(depth: Int, color: Color) -> (score: Int, direction: Direction) {
    var bestScore = color == myColor ? Int.min : Int.max
    var currentScore: Int
    var bestDirection: Direction?
    if game.players.filter({$0.lives > 0}).count < 2 || depth == 0 {
        // This is a call to my heuristic evaluation function
        bestScore = evaluateHeuristics()
    } else {
        // if the player has no pieces on the board, just move up since moving in any direction won't change anything
        for move in (game.board.indicesOf(color: color).count == 0 ? [Direction.up] : [Direction.up, .down, .left, .right]) {
            let gameCopy = game.createCopy()
            switch move {
            case .up: gameCopy.moveUp()
            case .down: gameCopy.moveDown()
            case .left: gameCopy.moveLeft()
            case .right: gameCopy.moveRight()
            }
            gameStates.append(gameCopy)
            // myColor is like mySeed in the original Java code
            if color == myColor {
                currentScore = minimax(depth: depth - 1, color: game.currentPlayer.color).score
                if currentScore > bestScore {
                    bestScore = currentScore
                    bestDirection = move
                }
            } else {
                currentScore = minimax(depth: depth - 1, color: game.currentPlayer.color).score
                if currentScore < bestScore {
                    bestScore = currentScore
                    bestDirection = move
                }
            }
            _ = gameStates.dropLast()
        }
    }
    return (bestScore, bestDirection ?? .left)
}

当我用depth4测试这个 AI 时,它似乎要么做愚蠢的动作,比如将他的棋子从棋盘上移开,要么只向一个方向移动他的棋子。

我还注意到,gameStates当递归调用返回时它的长度约为 90。通常它应该是 1 对吗?因为在递归调用返回时,AI 尝试的所有移动都应该已撤消,并且gameStates只会包含初始状态。

我做错了什么?

杰里米

dropLast()返回一个包含除数组最后一个元素之外的所有元素的数组切片。它不会修改原始数组。使用removeLast()

编辑

您真正想要的是堆栈数据结构。这是一个。

public struct Stack<Element>
{
    fileprivate var elements: [Element] = []

    public init() {}

    ///    Push an element onto the top of the stack
    ///
    /// - parameter newElement: The element to push
    public mutating func push(_ newElement: Element)
    {
        elements.append(newElement)
    }

    ///    Pops the top element off the stack
    ///
    ///    - returns: The top element or nil if the stack is empty.
    public mutating func pop() -> Element?
    {
        let ret = elements.last
        if ret != nil
        {
            elements.removeLast()
        }
        return ret
    }

    ///  The top element of the stack. Will be nil if the stack is empty
    public var top: Element?
    {
        return elements.last
    }

    /// Number of items in the stack
    public var count: Int
    {
        return elements.count
    }

    /// True if the stack is empty
    public var isEmpty: Bool
    {
        return elements.isEmpty
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么我不能用滤波器作为我在流最后一步

为什么不能从data step到proc一步一步解析值?

为什么我的React组件落后一步?

为什么我的KeyAdapter总是落后一步?

为什么决策树在每一步的值都不等于样本数?

插入排序算法。一步一步发生了什么?

为什么并行处理不能进一步加快速度?

为什么git不能进一步减小存储库的大小?

改进malloc()算法的下一步是什么?

为什么下一步按钮打开和关闭我的日历?

与SSE2相比,AVX为什么不能进一步提高性能?

为什么包含需要进一步的依赖?

函数未处理每一步

转移元素并打印每一步

我可以一步一步定义状态

我如何进一步理解为什么Go会以这种方式处理错误?

为什么调用indexedDB.deleteDatabase阻止我进行任何进一步的事务?

Ruby遍历哈希,在每一步更新值的最惯用的方法是什么?

java.lang.OutOfMemoryError当试图实现极大极小算法

Tic Tac Toe 的极小极大算法输出不正确

链表:添加元素时为什么是当前元素。下一步指向新节点,为什么我们要覆盖当前节点

Python Gurobi:循环中每一步的addContrs

执行期间在 DAG 中的每一步缓存

增值并使用innerHTML打印每一步

如何在CSV列的每一步求和

Laravel 如何保护每一步的命令

实施极小极大

为什么DynamoDB一步一步删除项目将使写入吞吐量增加一倍

为什么我的按钮不能设置50%的宽度并在每一侧分开?

TOP 榜单

热门标签

归档