好吧,让我们考虑一个64位数字,其位形成一个8x8表.
例如
0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 1 0 1 1 1 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0
写作
a b c d e f g h
----------------
0 1 1 0 …
Run Code Online (Sandbox Code Playgroud) 我有一个位板,如果只有一位设置为1,我想检查C.
#include <stdint.h>
typedef uint64_t bboard;
bboard b = 0x0000000000000010;
if (only_one_bit_set_to_one (b)) // in this example expected true
// do something...
Run Code Online (Sandbox Code Playgroud)
有没有想过写这个功能int only_one_bit_set_to_one (bboard b)
?
这是关于如何使用魔术位板在国际象棋中验证滑动棋子移动的大图片的问题.只是为了澄清,我不是在问魔术比特板如何在内部工作.
现在,关于这个问题的更多细节.我正在使用位板编写棋盘表示,我想使用魔术位板验证滑动棋子移动.有人可以列出如何实现这一目标的主要步骤吗?作为一个例子,考虑以下董事会职位:
假设我们已经初始化并准备好使用所有魔术位板功能和数据结构.因此,仅使用魔术位板的功能签名,您是否可以列出步骤(伪代码或任何语言)来验证g3上白车的给定移动?
在许多棋盘游戏中(如跳棋,go和othello/reversi),每个方块可以用三种状态表示:白色,黑色或空白.
这种游戏引擎中的8x8板通常表示为两个位板:一个64位整数用于白色位置,另一个64位整数用于黑色.
然而,当存储本地游戏模式时,这种二进制表示可能需要大量空间.例如,为8平方行的所有可能值创建查找表将需要具有256*256 = 4 ^ 8 = 65536值的数组,而仅有3 ^ 8 = 6561个可能位置(因为正方形永远不可能是被黑色和白色片段占据).
另一种方法是将电路板存储为三元数 - 所谓的标题.但我没有找到任何在两个二进制整数表示和三元整数表示之间转换的快速算法.
因此,我的问题是
有没有一种有效的方法来转换(编码)三个数字中的两个互斥二进制数(w & b == 0
),这样每个唯一的这样的整数对将被映射到一个唯一的整数?(最好用C/C++.)
Python示例
这是我的Python解决方案:
white_black_empty = lambda w, b: int(format(w, 'b'), base=3) + \
int(format(b, 'b'), base=3)*2
Run Code Online (Sandbox Code Playgroud)
示例值:
我的大脑吸烟试图了解这种位板技术的机制.为了简单起见,让我们想象一下,我们有一个只有两个棋子和一个8个位置的游戏,而不是国际象棋和许多复杂的棋子动作.一件是三角形,另一件是圆形,如下所示:
?????????????????????????????????
? ? ? ? ? ? ? ? ? ? ?
?????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
三角形可以像车一样移动.水平位置任意数量,但不能跳过圆圈.
现在假设用户将三角形移动到最后位置,如下所示:
?????????????????????????????????
? ? ? ? ? ? ? ? ? ? ?
?????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
对于此示例,三角形移动位板是
1 1 0 1 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
圆圈位置掩码是
0 0 0 0 0 1 0 0
Run Code Online (Sandbox Code Playgroud)
显然这一举动是非法的,因为三角形不能跳过圆圈,但软件如何使用魔术位板技术检查移动是否合法?
我想通过位板系统构建一个棋盘.从12个位板开始,我想显示一个表(棋盘),在循环/迭代期间必须绘制一个块.
我如何循环所有位值?我想的是:for(i = 0; i <64; i ++)draw table/build array/draw empty square
这些是我开始游戏的价值观:
function init_game($whitePlayer,$blackPlayer)
{
$WhitePawns = '0000000000000000000000000000000000000000000000001111111100000000';
$WhiteKnights = '0000000000000000000000000000000000000000000000000000000001000010';
$WhiteBishops = '0000000000000000000000000000000000000000000000000000000000100100';
$WhiteRooks = '0000000000000000000000000000000000000000000000000000000010000001';
$WhiteQueens = '0000000000000000000000000000000000000000000000000000000000010000';
$WhiteKing = '0000000000000000000000000000000000000000000000000000000000001000';
$BlackPawns = '0000000011111111000000000000000000000000000000000000000000000000';
$BlackKnights = '0100001000000000000000000000000000000000000000000000000001000010';
$BlackBishops = '0010010000000000000000000000000000000000000000000000000000100100';
$BlackRooks = '1000000100000000000000000000000000000000000000000000000000000000';
$BlackQueens = '0000100000000000000000000000000000000000000000000000000000000000';
$BlackKing = '0001000000000000000000000000000000000000000000000000000000000000';
$WhitePieces = $WhitePawns|$WhiteKnights|$WhiteBishops|$WhiteRooks|$WhiteQueens|$WhiteKing;
$BlackPieces = $BlackPawns|$BlackKnights|$BlackBishops|$BlackRooks|$BlackQueens|$BlackKing;
}
Run Code Online (Sandbox Code Playgroud)
有人问我:为什么选择位线?答:关于位板
通常用于象棋,棋子和othello等棋盘游戏的位板是bitset数据结构的一种特殊化,其中每个位代表游戏位置或状态,旨在优化速度和/或内存或磁盘在质量计算中的使用.同一位板中的位在游戏规则中彼此相关,通常在一起形成游戏位置时.其他位板通常用作掩码来转换或回答关于位置的查询."游戏"可以是任何类似游戏的系统,其中信息以结构化形式紧密打包,其中"规则"影响各个单元或部件的相关性.
在某些位板国际象棋引擎中,棋子位板初始化如下:
white_pawns = 0x000000000000ff00
black_pawns = 0x00ff000000000000
white_knights = 0x000000000000042
black_knights = 0x4200000000000000
white_bishops =0x000000000000024
black_bishops = 0x2400000000000000
white_rooks = 0x000000000000081
black_rooks = 0x8100000000000000
white_queens = 0x0000000000000008
black_queens = 0x0800000000000000
white_king = 0x0000000000000010
black_king = 0x1000000000000000
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下这些片段如何获得各自的十六进制值吗?
我正在寻找创建一个基本的国际象棋(或失败,跳棋/草稿)引擎.在研究了这个主题之后,我非常有信心想要使用一系列的位板.我在基本层面理解这个概念,但是我在用Java表示它们时遇到了麻烦.
我试图将棋盘的白色部分表示为1,将其他所有部分表示为0,使用long:
long whitePieces = 0000000000000000000000000000000000000000000000001111111111111111L;
Run Code Online (Sandbox Code Playgroud)
但是当我打印出来时,我得到以下46位:
System.out.println(Long.toBinaryString(whitePieces));
1001001001001001001001001001001001001001001001
Run Code Online (Sandbox Code Playgroud)
是什么导致了这个结果?我确信这里有一些我从根本上误解的东西; 如果有人能指出我正确的方向,我将非常感激.
我正在尝试处理位板,这需要我在64位无符号整数中设置一个特定的位.要设置位i,我对所讨论的位板执行按位OR运算,左移数字.
#include <stdint.h>
uint64_t kings = 0ULL; // Also tried unsigned long long int before.
kings |= 1 << i;
Run Code Online (Sandbox Code Playgroud)
它从第0位到第31位工作正常,但不能用于第32位到第63位.我怀疑这是因为右侧的评估恰好是32位整数.因此,我尝试了一个临时变量.
uint64_t temp = 0ULL;
temp |= 1 << i;
Run Code Online (Sandbox Code Playgroud)
也许它仍然将右侧评估为32位整数,或者它是我无法弄清楚的其他问题.要输出整数,我使用的是std :: bitset <64>.例如:
uint64_t kings = 0ULL;
kings |= 1 << 3;
kings |= 1 << 59;
Run Code Online (Sandbox Code Playgroud)
预期小数值:576460752303423496
实际:8
std::bitset<64> x(kings);
std::cout << x;
Run Code Online (Sandbox Code Playgroud)
位值:0000000000000000000000000000000000000000000000000000000000001000
显然,只有国王| = 1 << 3; 工作正常.
总之,第32到63位有什么问题,我该如何解决?
我在C#中使用自己的国际象棋引擎.其实我在移动生成器上搜索错误,但我意识到我的实际国际象棋系统太慢了(甚至每分钟21分钟(6)).这是我的Github存储库.
我正在使用一个简单的层次结构和一个实现一个列表的板类.由于这个项目的面向对象性质,我选择不使用多维矩阵来表示板,因为每个块都有自己的位置.问题是,为了从板上获得一块,知道它的位置,它需要O(n),其中n是当前板上的件数.
在移动生成器中,我得到所有可能的移动假设一个empy板,然后我用静态类检查它们(因为一块不应该关心板状态).我访问了一些网站,包括国际象棋编程Wiki.我看到有很多类型的电路板表示,但在我的实际状态中,我不知道哪个是最好的(性能和简单性).我想这都是,我希望你会帮助我:)
我欢迎任何关于我的项目的建议;)谢谢大家.
这是我的董事会课程:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Chess_Engine___NOGUI
{
class Board
{
public const byte BoardSize = 8;
private Game game;
private List<Piece> pieceList = new List<Piece>();
private List<Piece> whitePieceList = new List<Piece>();
private List<Piece> blackPieceList = new List<Piece>();
public Board(Game game)
{
this.game = game;
}
public void AddPiece(Piece piece)
{
pieceList.Add(piece);
switch (piece.Color)
{
case PieceColor.Black:
blackPieceList.Add(piece);
break;
case PieceColor.White:
whitePieceList.Add(piece);
break;
}
}
public void RemovePiece(Piece piece)
{ …
Run Code Online (Sandbox Code Playgroud)