首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实现Minimax算法

实现Minimax算法
EN

Stack Overflow用户
提问于 2018-12-07 16:07:46
回答 1查看 686关注 0票数 2

我已经在web上搜索了psuedocode、工作示例、相同领域的堆栈溢出问题/解决方案,到目前为止,我还没有发现任何有帮助的地方,所以我在这里进行了探讨。

我正试图在我的Tic脚趾游戏中以一种非常基本的方式实现Minimax算法(没有alpha/beta剪枝)。让我解释一下我拥有的每个助手方法,然后如果您需要的话,我可以共享我的实际代码的一部分。Note (在检查终端状态、只检查win或检查抽签时,我不使用深度)。

首先,我有一个实用程序MakeBestMove,它将在计算机移动时被调用,然后在MakeBestMove中调用MiniMax,然后调用它自己,直到boardState达到终端状态,或者当没有移动时。

我希望MakeBestMove返回最好的移动,我的MiniMax函数返回boardState的分数。

如果您熟悉MiniMax,当状态结束时,状态就会被评分。我用过-100代表O赢,100代表X赢,0打平我的比赛。这是在我的EvaluateScore助手函数中完成的,我也有一个函数,它将根据游戏板的当前状态来确定可用的动作,以帮助我迭代打开的移动。另外,需要注意的是,玩家"X“永远是人,玩家"O”永远是计算机。

我正在尝试使用我在Python中使用的方法来用MiniMax实现F#,而且理论上它应该能工作,即使它不忠于F#功能范例。

由于某种原因,它不像我所期望的那样。我花了几个小时来检查每一行代码,以确保我没有出现任何奇怪的副作用,但没有取得任何成功。如果有人能给我指明正确的方向,我将不胜感激。我知道我写它是非常必要的,但我确实认为它可以这样工作,但我似乎不知道为什么它没有,以及我可能错过了什么。任何帮助都是非常感谢的!

代码行为问题: 1.在bestMove中没有正确返回MakeBestMove 2。虽然Minimax函数看起来是通过递归遍历不同的终端boardStates来正确运行的,但是MakeBestMove不会阻止"O“的移动,但是当它移动一步时,就会采取获胜的移动。

我希望我的代码表现如何: 1.正确评分boardState的能力(我相信我已经在这么做了) 2.如果boardState是终端的话返回该分数的能力,或者如果没有更多的动作需要采取(我正在做的) 3.使用该分数来做出最佳的移动选择的能力(这就是问题所在)

编辑我想在我的程序中添加一个“遍历”调用,以防您想要通过Visual运行我的代码并测试出来。

在Program.fs中,我的代码是从这里开始的,当它调用ComputerPlayerTurn()时,它将使用Game.fs,然后调用ComputerPlayerTurn()将变量let mutable computerMove初始化为= MakeBestMove(board)。在调用MakeBestMove(board)之后,函数中就是调用MiniMax(board) marker的位置。

下面的代码是我遇到的行为问题所在:

代码语言:javascript
运行
复制
let rec MiniMax(board) marker = 
    let mutable bestValue = 0
    let mutable board = board
    let mutable moves = GetListOfMoves(board) 
    if GameWon(board) marker = true || GetListOfMoves(board).Count = 0 then
        bestValue <- EvaluateScore(board)
    else
        if marker = "X" then
            bestValue <- -100
            for move in moves do  
                board <- ModifyBoard(board) move marker
                bestValue <- max(MiniMax(board) "O")(bestValue) 
                board <- ModifyBoard(board) move " "
            bestValue <- bestValue
        else 
            bestValue <- 100
            for move in moves do  
                board <- ModifyBoard(board) move marker
                bestValue <- min(MiniMax(board) "X")(bestValue) 
                board <- ModifyBoard(board) move " "
            bestValue <- bestValue
    bestValue

let MakeBestMove (board) marker = 
    let mutable board = board
    let mutable bestMove = 0
    let mutable bestValue = 0
    let mutable bestMoves = ResizeArray<int>()
    let moves = GetListOfMoves(board)
    for move in moves do
        board <- ModifyBoard(board) move marker
        bestValue <- MiniMax(board) "X" 
        board <- ModifyBoard(board) move " "
        if marker = "X" then
            if bestValue = 100 then
                bestMove <- move
            if bestValue > 0 then
                bestMoves.Add(move)
            else if bestValue = 0 then
                bestMoves.Add(move)
        elif marker = "O" then
            if bestValue = -100 then
                bestMove <- move
            if bestValue < 0 then
                bestMoves.Add(move)
            else if bestValue = 0 then
                bestMoves.Add(move)
    if bestMove = 0 && bestMoves.Count > 0 then
        bestMove <- bestMoves.[0]
    elif bestMove <> 0 then
        bestMove <- bestMove
    else
        bestMove <- GetListOfMoves(board).[0]
    bestMove 

我的代码在存储库的主分支https://github.com/sinnmk/fsharp-tictactoe

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-08 00:22:39

问题在于:

代码语言:javascript
运行
复制
if ((GameWon(board) marker) = true || (moves.Count = 0)) then

它只是考虑到marker赢下的平局和游戏。它还应该考虑marker输掉的游戏:

代码语言:javascript
运行
复制
if GameWon board "O" || GameWon board "X" || moves.Count = 0 then

我去掉了不必要的括号和条件,比如= true

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53673100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档