我已经在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的位置。
下面的代码是我遇到的行为问题所在:
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上
发布于 2018-12-08 00:22:39
问题在于:
if ((GameWon(board) marker) = true || (moves.Count = 0)) then它只是考虑到marker赢下的平局和游戏。它还应该考虑marker输掉的游戏:
if GameWon board "O" || GameWon board "X" || moves.Count = 0 then我去掉了不必要的括号和条件,比如= true。
https://stackoverflow.com/questions/53673100
复制相似问题