【发布时间】:2009-05-06 12:07:58
【问题描述】:
你会为
创建3个列表(坐标)吗?- 空位
- 黑色位置
- 白色位置
或者只是在需要时循环遍历数组并每次都使用结果?
什么是最好的? (速度方面)
【问题讨论】:
-
@neil,我只是看了看这不是骗子。我的问题是一个特定的问题,而您链接的那个问题没有回答它
你会为
创建3个列表(坐标)吗?或者只是在需要时循环遍历数组并每次都使用结果?
什么是最好的? (速度方面)
【问题讨论】:
您的两个主要选择是在速度和代码清晰度之间。
如果速度是您的首要任务,那么您必须为棋盘上的每组棋子使用 64 位数据类型(例如白棋子、黑皇后、过路棋子)。然后,您可以在生成移动和测试移动合法性时利用本机按位运算。
如果优先考虑代码的清晰性,那么请忘记位混洗,并像其他人已经建议的那样使用抽象的数据类型。请记住,如果您这样做,您可能会达到性能上限。
首先,请查看 Crafty (C) 和 SharpChess (C#) 的代码。
(原贴here)
【讨论】:
您正在寻找的是董事会代表。 Chess Programming Wiki 有一个关于这个主题的非常详细的部分(如果你真的想写一个 AI,绝对值得一读),而 Wikipedia 提供了一个很好的主题概述。
在选择合适的棋盘表示时要深思熟虑,这一点很重要——它们都有自己独特的优势(和缺陷)——主要与某些操作的速度/执行有关,例如执行动作和评估棋盘状态(通常是范围从 O(1) 到 O(n) 时间复杂度取决于方法和任务)。据我所知,关于“最佳”董事会代表仍然没有达成共识,尽管现在有些人通常比其他人更受欢迎(例如,bitboards 几乎是必备品)。这就是为什么大多数强大的国际象棋 AI 在搜索移动时通常使用几种(最多 4 或 5 种)不同的棋盘表示。
【讨论】:
我建议一个包含 64 个项目的数组,例如:
byte [64] Squares;
这样你只需要用一个字节来表示棋盘的位置,速度要快得多。
在处理参考棋盘位置的单个索引时,必须知道某些事情才能使生活更轻松。例如,您如何知道两个位置都在同一行或同一列?有一个简单的技巧可以解决这个问题。
行
要计算出位置的行,您将位置除以 8 并取结果的整数部分。例如,位置 63 除以 8 为 7.875,等于第 7 行。位置 3 除以 8 为 0.375,因此为 0。在 C# 中,通过转换为整数,您将始终只获得数字的整数部分,因此:
Row = (int)(position / 8)
栏目
要找出一个位置的列,您可以通过执行位置模数 8 来使用模数运算符。例如,位置 24 模数 8 是第 0 列。位置 15 模数 8 是 7,因此
Column = position % 8
有了这两个概念,我们可以将 64 平方板上的任何位置转换为列和行。
如果您想了解有关创建自己的国际象棋引擎的更多信息,请查看http://www.chessbin.com
【讨论】: