问题标签 [bitboard]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 如何在连接四游戏中列出所有可能的动作
我正在按照这篇文章制作一个 AI 。基本思想是使用位板制作一个非常快速的协议,用于对板进行修改并通过可能的游戏结果进行排列。
但是这篇文章是用 python 写的,我在最初的位板设置之后遇到了麻烦。我去了他们参考的github 自述文件,希望为我的 AI 开发框架,然后担心 alpha-beta 修剪和机器学习。基本上,我通过了 、 和 的方法checkWin
,makeMove
并undoMove
为列的高度、移动、移动的计数以及代表玩家位板的长变量数组建立了所需的字段。
但我目前停留在 generate move 方法上,因为它试图初始化列之外位板顶部的所有值。但是在java中我似乎不能这样做:它只是给了我这个文字类型超出了long类型范围的错误。另外看到动作是int[]
我不知道如何使用moves.push(col)
. 因为这给出了错误 cannot invoke push(int)
。您将在下面找到损坏的listMoves
方法和我当前的代码,如果有人能告诉我一些我可能在我的代码中做错的事情以及或如何修复该listMoves
方法,我将非常感激。干杯!
我的代码
java - Java连接四个位功能和位板错误
本质上,我试图创建一个连接四个 Ai,我遇到了一篇文章,它使用位板来优化移动和检查胜利。基本上我从 git hub自述文件中获取了一些方法这应该在你的位板上进行移动并撤消移动,不幸的是,这些方法似乎无法正常工作,因为它将它们放在位串的末尾而不是将它们间隔 7。我认为这可能是一些 java阻止这些正常工作的事情,我已经发布了一个示例程序,我认为它可以准确地说明问题。例如,如果我设置一个长变量,使其在第 5 行有一行四个 1 并显示它。它正确显示而没有开头的零,但另一方面,如果我在第一列中添加三个标记。然后是第三列的三个标记。它显示为 111 和 111。它应该是什么时候
并且没有前导零,所以
然后,如果我用这些列下降 1、3、1、3、2、4 运行另一个测试,这应该会导致这种板状态。
它应该显示 10、10
或者
这是一些演示第二种情况的测试代码。在这一点上,我不知所措,因为这些方法的操作非常优雅和复杂,尽管它们只有 3 行代码,如果有人能告诉我我在做什么有什么问题,我将不胜感激。干杯!
python - 使用位板在奥赛罗中产生动作
我制作了两个非常相似的奥赛罗 AI。在第一个中,板表示为长度为 100 (10x10) 的数组,其中 8x8 板表示在数组的“中间”,数组的其余部分是边缘周围的缓冲区(索引 11 位于左上角8x8 板的一角,索引 88 是右下角)。要在 position 移动index
,我使用以下代码:
为了生成移动,然后我检查可能的索引(内部 8x8 板上的图块)并检查是否len(changed) > 1
. 如果是,我将棋盘上的图块设置changed
给该玩家。
在第二个 AI 中,我原以为移动速度会更快,棋盘被表示为两个 64 位的位板——一个用于目标最大化分数的玩家,另一个用于试图最小化分数的玩家。为了采取行动,我使用与此处相同的代码,刚刚转换为 Python:
使用位板表示,玩 1000 个随机游戏大约需要 7 秒,而数组表示需要 4 秒。
如何使位板表示在生成和移动时更快,是否可以检查可能的移动并同时返回新的位板?
swift - 有没有办法反转 UInt64 中的位顺序?
我正在根据用 Java 编写的教程在 Swift 中构建一个国际象棋引擎。在本教程中,Java 的有符号 64 位整数long
有一个静态方法reverse(long i)
,称为“返回通过反转指定 long 值的二进制补码二进制表示中的位顺序获得的值”。它基本上颠倒了二进制位的顺序,以便为简单起见使用 8 位,01000000
将变为00000010
.
我很好奇是否有办法用 Swift 的UInt64
. 我知道 Java 的long
(有符号,2s 补码)和 Swift 的UInt64
(无符号)是不同的,但我想用UInt64
.
我试过UInt64.byteSwapped
了,但这似乎并没有让我得到我期望的行为。
swift - 了解使用无符号位板生成滑动块移动的“o^(o-2r)”公式?
我正在尝试做什么 我正在
尝试执行一些按位运算来创建一个国际象棋引擎。为了制作这个引擎,我需要能够生成棋子的移动,比如车。有一个方便的公式可以创建一个可让车移动到的方块位板:bitboardOfOccupiedSquares ^ (bitboardOfOccupiedSquares - 2 * bitboardOfPieceToMove)
.
我正在尝试生成 h1 上的车可以移动到的所有方格。所以这应该很容易,我只需抓住占据方格 ( 18410433801713942527
) 的位板并抓住 h1 上的车的位板 (2^63 或9223372036854775808
) 并将它们代入方程:
我
的问题我面临的问题是没有bitboardOfOccupiedSquares
大于的值,所以当作为 的值传递时2 * (2^63)
,操作(bitboardOfOccupiedSquares - 2 * bitboardOfPieceToMove)
总是产生一个负数。当然,负数不能用无符号整数表示,所以每当 h1 上的一块被传递时,程序就会在我身上崩溃。2^63
bitboardOfPieceToMove
我已经看到一个 youtuber 通过在 Java 中使用有符号整数来完成此方法(如此处和此处所见)。我曾尝试在整个引擎中使用签名位板而不是未签名位板,但这只会导致其他问题在其他地方出现。另外,我知道大多数引擎都可以毫无问题地使用未签名的位板。
此外,2 * (2^63)
equals18446744073709551616
高于 的UInt64
最大值18446744073709551615
,我认为这与整个“2s 补码”的想法有关。
我想知道
国际象棋引擎编程世界中是否有人使用过这个o^(o-2r)
公式,尤其是未签名的位板?我能够掌握文章和 youtube 视频中传达的想法,但似乎无法使其在未签名位板的实践中发挥作用。
swift - 溢出运算符的效率是否低于执行不会导致溢出的操作?
我在做什么:我正在用 Swift 编写一个国际象棋引擎。编写强大的国际象棋引擎最重要的部分之一是能够在尽可能短的时间内生成尽可能多的未来棋盘位置。您的引擎可以在更短的时间内生成和评估的位置越多,引擎就越强大。
话虽如此,我已经编写了用于生成滑动件(主教、车和皇后)移动的函数。这些函数使用溢出运算符( &+
, &-
, &*
),因为使用普通的按位运算符经常会导致溢出错误。
生成所述移动需要两个函数,一个用于为滑动块生成所有合法的垂直和水平移动,另一个用于为滑动块生成所有合法的对角线移动。这两个函数有效地做同样的事情,我们只是稍微不同地操纵参数。下面是生成水平和垂直移动的函数的样子:
关于上述函数,您需要认识到的唯一重要的事情是它为我们提供了预期的输出,并且它使用溢出运算符来实现。
现在,我之前对相同方法的迭代(在我了解如何使用溢出运算符规避溢出之前)更加冗长。它需要运行四个 while 循环,这些循环将在“北”、“南”、“东”或“西”方向上远离当前棋子,直到它与阻止沿相应方向进一步移动的棋子接触. 这是该horizontalAndVerticalMoves
函数的迭代的样子:
我认为我新实现的这个函数的版本(使用溢出运算符的那个)不仅更简洁,而且效率更高。关于同一函数的此迭代,您需要注意的唯一重要的事情是它为我们提供了预期的输出,但看起来更加冗长并且不使用溢出运算符。
我注意到的:如前所述,我希望使用溢出运算符的更新、更简洁的代码比使用一堆 while 循环的迭代执行得更快。在运行测试以查看生成国际象棋移动的速度时,我发现使用 while 循环而不是溢出运算符的版本明显更快。计算国际象棋游戏中前三步棋的每个组合只需要不到6 秒的时间,而使用溢出运算符的新函数需要不到13 秒的时间。
我想知道的是:由于我想创建可能的最强大的国际象棋引擎,我正在寻找可以使执行速度更快的代码。旧功能比新功能执行得更快,这对我来说似乎违反直觉。所以我想知道,Swift 中的溢出运算符是出了名的缓慢/低效吗?
以下是生成这些动作的相关类的样子:https ://github.com/ChopinDavid/Maestro/blob/master/Maestro/Moves.swift
python - 超过 64 位的 Python Bitboard 使用 Numpy lib
我实际上是在尝试创建一个可以玩棋盘游戏的 AI。我的问题是棋盘游戏使用的是 9x9 正方形,所以我不能像通常那样使用 64 位棋盘。有什么办法可以使用超过 64 位板?
我虽然使用 3 个 32 位整数,但我真的不知道该怎么做
c#-4.0 - 查找二进制数的二进制组合
对 C# 来说非常新,所以这可能是一个愚蠢的问题。
我正在使用很多 UInt64。这些都表示为十六进制对吗?如果我们查看它的二进制表示,我们是否可以返回这样一个数组,如果我们对其应用“或”操作,我们将返回原始 UInt64?
例如,假设
然后,我正在寻找一种有效的方法来达到,
这些数字是十六进制的,而不是二进制的。对不起,我也是十六进制的新手。
我已经有一个方法,但感觉效率低下。我首先转换为二进制字符串,然后遍历该字符串以找到每个“1”。然后我将相应的二进制数添加到数组中。
有什么想法吗?
这是一个更好的例子。我有一个十六进制数 x,形式为
其中 x 的二进制表示是
我希望找到一个由十六进制数 (UInt64??) 组成的数组,这样应用于该数组所有成员的 or 操作将再次导致 x 。例如,
我认为问题归结为找到一种有效的方法来找到二进制扩展中'1'的索引......
kotlin - kotlin 中的国际象棋 BitBoards。哪种数据类型?
我认为这个问题还没有被问到。
问题是,在国际象棋中,我们使用位板来加快移动生成周期,方法是用 bit=1 表示位置,用 bit=0 表示其他位置。在国际象棋中,我们有 8*8 个位置。结合现代 CPU,最推荐在无符号 64 位整数中实现这一点。在 c++ 中,我们可以使用一个无符号的 64 位地址 int64_t 并将其分配如下: 0b00000000_00000001_00000001_00000001_00000001_00000001_00000001_00000001
然而,我的问题是,我们将如何在 kotlin 中做到这一点。由于 kotlin 继承了 java 数据类型,我们不能有一个无符号的 64 位位板,只有 63 位,这对于国际象棋来说是不够的。例如。
我不想让事情变得更糟并在不同的数组中拆分行,就像我读过几次一样,因为它丑陋并且可能没有那么快。
因此,偶然发现了“kotlin-stdlib / kotlin / Experimental”中的 ULong 数据类型,到目前为止,我所写的内容看起来很有希望。所以,首先感谢您阅读到这里,其次,这是要走的路还是我错过了更好的东西?
java - 超类上受保护数组的值意外更改
我正在使用位板编写一个国际象棋引擎,我想为位板初始化器制作一个可扩展的 API,这将允许我在未来添加更多变体,如 chess960。
所以我想出了下面的抽象超类,它为所有类型的初始化器提供了一个统一的接口:它分配用于存储位板的数组,然后调用必须由任何子类实现的抽象方法 init(),在里面应该创建位板并将其分配给相应的数组
An implementation to initialize standard chess bitboards, it simply assign the hard-coded bitboards values because standard chess starts always in one way. Side.White and Side.Black are two static final fields used as array indexes to avoid inconsistence. white = 0, black = 1:
The problem is that by calling any superclass' getter method I get binary 1000 for white (index 0) and 100000000000000000000000000000000000000000000000000000000000 for black (index 1) instead of the assigned values
An explanation of this strange behaviour would be highly appreciated, thanks in advance.