回答
从维基百科文章中,一个位板似乎是一个简单的位数组。 .NET中有一个名为BitArray的类,它具有执行按位操作的方法。
例如,对于白色车位置的棋盘可以声明如下:
'Create bit array to store white rooks
Dim whiteRooks As New BitArray(64)
'Set white rooks at initial position
whiteRooks(0) = True 'Corresponds to A1 on chess board
whiteRooks(56) = True 'Corresponds to H1 on chess board
国际象棋中棋盘的全部重点是某些操作的可用性和速度。对于这两个方面来说,BitArray比简单的UInt64差得多。我将很快用一些例子添加一个答案。 – RoadWarrior 2012-03-16 11:16:21
同意上面的RoadWarrior。 BitArray可能是不适用于国际象棋的可扩展性原因的一个好选择,因为总是有64个方格。但更重要的是,大多数涉及UInt64的二进制操作都将在x64架构的单CPU周期中完成,这是我怀疑BitArray保证的。 – bytefire 2013-05-31 13:28:01
在这里有一些关于这方面的其他文章,在答案中有一些有用的信息,希望他们帮助。
我会尝试稍后应用第一个链接..我必须去这个时间 – jasperagrante 2012-03-09 14:20:55
......怎么
Dim mArray(8,8) As Boolean
替代Boolean
为自己的类或结构和functionalty扩展到您的要求。
另一种选择,如果你不想使用数组,是简单地创建一个类/结构包含董事会或州在你想指定的很多“行业”。例如,您可以指定4个long来表示128x128板,每个long代表一个“扇区”(假设为32位处理器)。然后,您只需重写Equals方法(或==运算符)以运行直接比较来检查每个“部分”是否相等,即IE this.Quadrant1 == that.Quadrant1
。最终,一个位板的整个概念是,你使用数据类型本身的位来表示你的环境的位置/状态(int = 32bits = 32个位置,long = 64bits = 64个位置等)。对于数值类型,这意味着您可以轻松进行直接相等比较(x == y
)以查看比特是否相等。这也使得检查有效移动非常容易,因为它只需要移动位X的位置来表示移动,并且对对手棋盘进行按位&。例如,棋子可以向上移动一个空间(相对于他们的棋盘),如果他们还没有移动,或者可以捕捉,则棋子移动两个。所以为了检查有效的移动,你需要移动小兵位置8(一个空格),16(两个空格,检查是否还没有移动)或者7/9(捕捉)。对于一次或两次空间移动,您必须在棋盘和对手棋盘上为新“位置”执行一次按位&,并检查它是否大于0(表示某人占据空间,因此无效移动)。对于捕捉移动,你只能检查你的对手棋盘,并且只有在结果&大于0时才允许移动。对于两个空格,首先必须对初始棋子“行”进行按位比较(255 < < < 8代表白色,255代表< < 48代表黑色)与有问题的棋子一起看看是否可能。如果你为每一个棋子创建对象,你可以简单地检查一下Pawn对象本身的布尔值,指出它是否已经移动。
使用位板时要考虑的最后一件事是您是否使用带符号的值(至少在.NET中)。这一点很重要,因为如果负数位被设置为有符号值,则该负数位将传播到右移位(意味着它将引入与移位数相同数量的1)。在这种情况下绝对考虑使用无符号值类型,否则你会得到一些时髦的结果。
要在VB(或C#)中实现位板,请使用System.UInt64。这可以容纳64位,棋盘的每个方格都有1位。该值类型适用于许多快速按位操作。我不建议使用另一张海报推荐的BitArray,因为它太慢了。任何像样的象棋引擎的基本要求之一就是速度。
要回答你的第二个问题,这是一个good bitboard tutorial。
下面是我自己的C#象棋引擎的一些例子。从代码中可以看到,使用位板可能需要一段时间,但它们通常非常快,特别是对于位置评估。
实施例1 - 棋盘定义:
internal UInt64 WhiteKing;
internal UInt64 WhiteQueens;
internal UInt64 WhiteRooks;
internal UInt64 WhiteBishops;
internal UInt64 WhiteKnights;
internal UInt64 WhitePawns;
internal UInt64 WhitePieces;
实施例2 - 棋盘初始化:
// Initialise piece bitboards using square contents.
private void InitPieceBitboards()
{
this.WhiteKing = 0;
this.WhiteQueens = 0;
this.WhiteRooks = 0;
this.WhiteBishops = 0;
this.WhiteKnights = 0;
this.WhitePawns = 0;
for (Int16 i = 0; i < 64; i++)
{
if (this.Squares[i] == Constants.WHITE_KING)
{
this.WhiteKing = this.WhiteKing | Constants.BITSET[i];
}
if (this.Squares[i] == Constants.WHITE_QUEEN)
{
this.WhiteQueens = this.WhiteQueens | Constants.BITSET[i];
}
if (this.Squares[i] == Constants.WHITE_ROOK)
{
this.WhiteRooks = this.WhiteRooks | Constants.BITSET[i];
}
if (this.Squares[i] == Constants.WHITE_BISHOP)
{
this.WhiteBishops = this.WhiteBishops | Constants.BITSET[i];
}
if (this.Squares[i] == Constants.WHITE_KNIGHT)
{
this.WhiteKnights = this.WhiteKnights | Constants.BITSET[i];
}
if (this.Squares[i] == Constants.WHITE_PAWN)
{
this.WhitePawns = this.WhitePawns | Constants.BITSET[i];
}
this.WhitePieces = this.WhiteKing | this.WhiteQueens |
this.WhiteRooks | this.WhiteBishops |
this.WhiteKnights | this.WhitePawns;
this.BlackPieces = this.BlackKing | this.BlackQueens |
this.BlackRooks | this.BlackBishops |
this.BlackKnights | this.BlackPawns;
this.SquaresOccupied = this.WhitePieces | this.BlackPieces;
}
}
实施例3 - 移动代:
// We can't capture one of our own pieces.
eligibleSquares = ~this.WhitePieces;
// Generate moves for white knights.
remainingKnights = this.WhiteKnights;
// Generate the moves for each knight...
while (remainingKnights != 0)
{
squareFrom = BitOps.BitScanForward(remainingKnights);
generatedMoves = Constants.ATTACKS_KNIGHT[squareFrom] & eligibleSquares;
while (generatedMoves != 0)
{
squareTo = BitOps.BitScanForward(generatedMoves);
moveList.Add(new Move(squareFrom, squareTo, Constants.WHITE_KNIGHT,
this.Squares[squareTo], Constants.EMPTY));
generatedMoves ^= Constants.BITSET[squareTo];
}
// Finished with this knight - move on to the next one.
remainingKnights ^= Constants.BITSET[squareFrom];
}
实施例4 - 计算材料的分数:
// Material score from scratch, in centipawns from White's perspective.
internal static Int32 ScoreMaterial(Board position)
{
return BitOps.BitCountWegner(position.WhitePawns) * Constants.VALUE_PAWN +
BitOps.BitCountWegner(position.WhiteKnights) * Constants.VALUE_KNIGHT +
BitOps.BitCountWegner(position.WhiteBishops) * Constants.VALUE_BISHOP +
BitOps.BitCountWegner(position.WhiteRooks) * Constants.VALUE_ROOK +
BitOps.BitCountWegner(position.WhiteQueens) * Constants.VALUE_QUEEN -
BitOps.BitCountWegner(position.BlackPawns) * Constants.VALUE_PAWN -
BitOps.BitCountWegner(position.BlackKnights) * Constants.VALUE_KNIGHT -
BitOps.BitCountWegner(position.BlackBishops) * Constants.VALUE_BISHOP -
BitOps.BitCountWegner(position.BlackRooks) * Constants.VALUE_ROOK -
BitOps.BitCountWegner(position.BlackQueens) * Constants.VALUE_QUEEN;
}
例5 - 计算一块流动性:
// Calculate mobility score for white knights.
remainingPieces = position.WhiteKnights;
while (remainingPieces != 0)
{
squareFrom = BitOps.BitScanForward(remainingPieces);
mobilityKnight += BitOps.BitCountWegner(Constants.ATTACKS_KNIGHT[squareFrom]
& unoccupiedSquares);
remainingPieces ^= Constants.BITSET[squareFrom];
}
嘿@RoadWarrior,这是你发布的一段非常有趣的代码,你有没有在任何地方发布完整的源代码? – Lu4 2013-08-29 13:21:32
@ Lu4:Amaia目前是一个私人国际象棋程序,所以完整的源代码不可用。 – RoadWarrior 2013-08-29 16:41:28
我明白了,谢谢... – Lu4 2013-08-29 18:16:46
- 1. 如何在UWP VB.NET中实现WinRTXamlToolkit.Controls.DataVisualization.Charting
- 2. 如何在VB.NET中实现GetStableHash方法
- 3. 在VB.NET中实现WCF
- 4. 在VB.NET中实现属性
- 5. 在vb.net中实现des-ede2
- 6. vb.net实现IAsyncResult.AsyncState
- 7. 如何在VC++/CLI中实现VB.net中定义的接口?
- 8. 如何在VB.NET中实现向导控件
- 9. 如何在vb.net中实现这个通用的
- 10. 如何在我的VB.Net应用程序中实现XMPP
- 11. 我如何在VB.net中实现类似Facebook的按钮
- 12. 如何在VB.NET中实现从Web表单的桌面下载
- 13. 如何在VB.NET中实现IEqualityComparer <T>?
- 14. 如何在VB.NET中使用隐式实现创建接口
- 15. 如何在Delphi中实现XIRR实现?
- 16. 在JavaScript中如何实现?
- 17. 如何在Java中实现
- 18. 如何在PHP中实现
- 19. 如何在ASP.NET中实现
- 20. 如何在JNI中实现
- 21. 如何在OOP中实现?
- 22. 如何在Java中实现
- 23. 如何在JavaScript中实现?
- 24. 如何在Java中实现
- 25. **如何在Python中实现?
- 26. 如何在Java中实现
- 27. VB.NET类实现事件
- 28. vb.net和接口实现
- 29. VB.NET必须实现错误
- 30. VB.NET显式接口实现
这是对一盘棋? – GrandMasterFlush 2012-03-09 14:10:40
嗯,很好。不知道他们。但是,根据维基百科页面上的描述,实现一个实现并不困难。 – Joey 2012-03-09 14:11:33
是的,这是一个国际象棋游戏。 – jasperagrante 2012-03-09 14:14:08