gpt4 book ai didi

c# - Perft 测试结果 - 找不到 Bug?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:26:21 25 4
gpt4 key购买 nike

我现在为我的糟糕英语道歉,我是意大利人。

我正在用 C# 编写一个完整的国际象棋游戏实现,玩家对玩家和玩家对计算机,现在我在实现 NegaMax 算法时遇到了一些困难。对于感兴趣的人,这是我的 github 存储库:https://github.com/crybot/ChessEngine_NOGUI/tree/master/Chess%20Engine%20-%20NOGUI

我已经尽力使这个项目尽可能面向对象,所以,如果您认为我的设计不正确,请告诉我:)

这是我的问题:

我实现了一个非常简单的评估函数,它对所有玩家对称地工作:

public static float Evaluate(PieceColor playerColor, Game game)
{
float score = 0;

score += 1 * (game.board.GetNumberOfPieces(PieceType.Pawn, playerColor)
- game.board.GetNumberOfPieces(PieceType.Pawn, playerColor.GetOpposite()));

score += 3 * (game.board.GetNumberOfPieces(PieceType.Bishop, playerColor)
- game.board.GetNumberOfPieces(PieceType.Bishop, playerColor.GetOpposite()));

score += 3 * (game.board.GetNumberOfPieces(PieceType.Knight, playerColor)
- game.board.GetNumberOfPieces(PieceType.Knight, playerColor.GetOpposite()));

score += 5 * (game.board.GetNumberOfPieces(PieceType.Rook, playerColor)
- game.board.GetNumberOfPieces(PieceType.Rook, playerColor.GetOpposite()));

score += 9 * (game.board.GetNumberOfPieces(PieceType.Queen, playerColor)
- game.board.GetNumberOfPieces(PieceType.Queen, playerColor.GetOpposite()));

score += 0.1f * (game.GetPlayer(playerColor).GetMoves(game).Count);

return score;
}

这是我的 NegaMax 函数,它接受一个 Game 参数(包括棋盘、玩家、ecc.ecc。)、枚举提供的 playerColor 和深度搜索;

我首先扫描 EnginePlayer 的所有可能移动,然后从 NegaMax 函数中获得它们的分数,但有些东西不起作用...

private float NegaMax(Game game, PieceColor playerColor, int depth)
{
if (depth == 0)
return EvaluateMove(playerColor, game);

float max = float.MinValue;
float score;

foreach (Move move in game.GetPlayer(playerColor.GetOpposite()).GetMoves(game))
{
game.board.SimulateMove(move);
score = Math.Max(max, -NegaMax(game, playerColor.GetOpposite(), depth - 1));

game.board.CancelMove(move);

if (score > max)
max = score;
}

return max;
}


public Move ThinkMove(Game game, PieceColor playerColor, int depth)
{

Move bestMove = new NullMove();
float bestScore = float.MinValue;
float temp = 0;

foreach (Move move in GetMoves(game))
{
game.board.SimulateMove(move);
temp = NegaMax(game, playerColor, depth);
game.board.CancelMove(move);

if (temp > bestScore)
{
if (Judge.IsLegal(move, game))
{
bestMove = move;
bestScore = temp;
}
}
}

if (bestMove is NullMove)
throw new NotImplementedException();
return bestMove;
}

我想这就是全部......我希望你会发现我做错了什么:)谢谢。

编辑:我实现了一个 Perft,它显示了移动生成器的不正确性。找了一些比较容易找的bug帮了大忙,但最后还是有些结果不对。以下是结果:

Perft Depth: 1
Nodes: 20 Captures: 0 Checks: 0 Castles: 0 Mates: 0 EnPassant: 0

Perft Depth: 2
Nodes: 400 Captures: 0 Checks: 0 Castles: 0 Mates: 0 EnPassant: 0

Perft Depth: 3
Nodes: 8902 Captures: 34 Checks: 12 Castles: 0 Mates: 0 EnPassant: 0

Perft Depth: 4
Nodes: 197281 Captures: 1610 Checks: 473 Castles: 0 Mates: 8 EnPassant: 0

这是正确的结果:https://chessprogramming.wikispaces.com/Perft+Results

如您所见,在深度 4,我分析了正确的节点,但捕获和检查值不正确(而配合是正确的)。

由于这些结果,我尝试通过在深度 4 划分每次移动分析的节点来隔离错误,得到这些结果:

Move    Nodes
a2a3 8457
a2a4 9329
b2b3 9345
b2b4 9332
c2c3 9272
c2c4 9744
d2d3 11959
d2d4 12435
e2e3 13134
e2e4 13160
f2f3 8457
f2f4 8929
g2g3 9345
g2g4 9328
h2h3 8457
h2h4 9329
b1a3 8885
b1c3 9755
g1f3 9748
g1h3 8881
Total Nodes: 197281

以及与那些从 Sharper 获得的结果的比较:

 Sharper v0.17 by Albert Bertilsson
divide 4
b1c3 9755
b1a3 8885
g1h3 8881
g1f3 9748
a2a3 8457
a2a4 9329
b2b3 9345
b2b4 9332
c2c3 9272
c2c4 9744
d2d3 11959
d2d4 12435
e2e3 13134
e2e4 13160
f2f3 8457
f2f4 8929
g2g3 9345
g2g4 9328
h2h3 8457
h2h4 9329
Nodes: 197281
Moves: 20

但即使在这里,值也是正确的...所以我尝试了深度 5 性能得到这些结果:

Move    Nodes
a2a3 181046
a2a4 217813
b2b3 215255
b2b4 216110
c2c3 222861
c2c4 240044
d2d3 328511
d2d4 361753
e2e3 402988
e2e4 405348
f2f3 178891
f2f4 198437
g2g3 217210
g2g4 214017
h2h3 181044
h2h4 218810
b1a3 198572
b1c3 234656
g1f3 233491
g1h3 198502
Total Nodes: 4865359

然后与 Sharper 的结果进行比较:

 Sharper v0.17 by Albert Bertilsson
divide 5
b1c3 234656
b1a3 198572
g1h3 198502
g1f3 233491
a2a3 181046
a2a4 217832
b2b3 215255
b2b4 216145
c2c3 222861
c2c4 240082
d2d3 328511
d2d4 361790
e2e3 402988
e2e4 405385
f2f3 178889
f2f4 198473
g2g3 217210
g2g4 214048
h2h3 181044
h2h4 218829
Nodes: 4865609
Moves: 20

所以我意识到问题是由兵的双推产生的 Action 引起的......但我无法真正找到错误......有人遇到过同样的问题吗?或类似的东西,或者只是一个找到那个错误的提示......

感谢大家:)

最佳答案

您应该首先确保着法生成一致,have a look here on how to .这称为性能测试。另一件奇怪的事情是我在你的算法中看不到威胁的“伙伴”:当根本没有移动并且国王被俘虏时你应该返回一个非常糟糕的值(否则是一个立场).然后你应该采取一些策略来对移动进行排序以便从 negamax 算法中获益,然后是一些“地平线”策略(也就是说,如果在 depth== 0 时仍然有捕获会发生什么?)。如果您在移动生成方面遇到问题,请尝试用一些更有趣的位置来挑战您的引擎,have a look here for example , 或者如果你想要更难的东西 this is the file that I use for testing my engine .它由许多行组成,其中包含 FEN 格式的位置,然后是以下格式的深度移动计数:

D1 50; D2 279

这意味着(例如)在深度 1 移动 50 次,在深度 2 移动 279 次

我提出的位置来 self 对护目镜的旧研究,关于挑战位置。你需要能够 support FEN notation ,如果您还没有,我强烈建议您实现,因为它是国际象棋引擎(不仅是)世界中交流位置的“事实上的”标准。

关于c# - Perft 测试结果 - 找不到 Bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11365221/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com