位棋盘(BitBoard) - yangboz/godpaper GitHub Wiki
位棋盘(BitBoard).
位棋盘其实就是一个90(9×10)位长度的变量,用来记录棋盘上的某些布尔值。因为棋盘上有90格,所以90位正好对应它的90格。对于面向对象的编程语言例如AS3,你可以象下面这样来定义这个变量类型:
public function BitBoard(column:int,row:int)
位棋盘的全部作用就是记录中国象棋棋盘上的某些布尔条件。你可能会问:
那是什么类型的“条件”? 位棋盘是如何“描绘”这种“条件”的?
一旦你理解这些问题的答案,你就已经开了一个好头。 首先,那是什么类型的条件?嗯,就象上面提到的,就是布尔条件。换句话说,布尔条件就是“哪些格子上面符合 (由你来填空)的条件。”例如:
“哪些格子上面有棋子?” “哪些格子上面有白棋棋子?” “哪些格子上面有车?” “哪些格子上面有象或将” “哪些格子受到F7格上的棋子的攻击?”(不用管格子上是否有棋子或是什么颜色的棋子,译者注。) “如果有马在F3格上,哪些格子会受到它的攻击?”
你还可以列出许多许多这样的条件. 然后,位棋盘如何来“描绘”这种“条件”?就象上面说过的,“位棋盘”就是一个90位的字。中国象棋棋盘上有90格。这意味着棋盘上的每一格在位棋盘里都有对应的一位。 现在是关键部分——如果位棋盘中对应某一格的“位”是“1”,那么这一格上的条件就是“真”;如果是“0”,对应格上的条件就是假。我知道这句话可能让你困惑,让我说得更具体一些。 假如我们需要一个记录所有棋子位置的位棋盘“AllPieces”。“AllPieces”告诉我们棋盘上哪些格子有棋子,哪些没有。当棋子处于最初位置的时候,“AllPieces”看上去是这个样子的: 11111111 11111111 00000000 00000000 00000000 00000000 11111111 11111111 其最高位对应第90格(I1格),最低位对应第0格(A9格)。 这样显示位棋盘可能更形象一点: 白棋
- ------------------
- 000000000
- 000000000
- 000000000
- 000000000
- 101010101
- 010000010
- 000000000
- 111111111
- ------------------
- ------------------
- 111111111
- 000000000
- 010000010
- 000000000
- 101010101
- 000000000
- 000000000
- 000000000
- 000000000
- ------------------
- ------------------
- 100010001
- 000000000
- 000000000
- 000000000
- 000000000
- 000000000
- 000000000
- 000000000
- 000000000
- ------------------
要成功应用位棋盘你必须理解三种基本操作。他们是(1)与,(2)或,(3)异或。关键是这些位操作的速度!回忆以下高中几何学……还记得原理表吗?
- 0 1 0 1
- 1 0 0 1
- ————————
- 0 0 0 1
- 0 1 0 1
- 1 0 0 1
- ————————
- 1 1 0 1
- 0 1 0 1
- 1 0 0 1
- ————————
- 1 1 0 0
public function and(value:BitBoard):BitBoard
{
var bb:BitBoard = new BitBoard(this.column,this.row);
for(var h:int=0;h<_row;h++)
{
for(var w:int=0;w<_column;w++)
{
bb.setBitt(h,w,Boolean((value.getBitt(h,w)&this.getBitt(h,w))));
}
}
return bb;
}
public function or(value:BitBoard):BitBoard
{
var bb:BitBoard = new BitBoard(this.column,this.row);
for(var h:int=0;h<_row;h++)
{
for(var w:int=0;w<_column;w++)
{
bb.setBitt(h,w,Boolean((value.getBitt(h,w)|this.getBitt(h,w))));
}
}
return bb;
}
public function xor(value:BitBoard):BitBoard
{
var bb:BitBoard = new BitBoard(this.column,this.row);
for(var h:int=0;h<_row;h++)
{
for(var w:int=0;w<_column;w++)
{
bb.setBitt(h,w,Boolean((value.getBitt(h,w)^this.getBitt(h,w))));
}
}
return bb;
}
某些位棋盘从程序开始运行到结束都不会改变。还记得那个位棋盘数组“knight[90]”吗?(他实际上记录了当马在任意格子上时,它下一步可以走的格子。)这个数组将在程序开始执行的时候被初始化并且不再改变。其余的位棋盘将不断变化。例如“AllPieces”位棋盘。当中国象棋棋盘变化时,它也跟着变化。然而,他们的初始化方式相同。 我是这样初始化位棋盘的…… 待续。。。
刚才说过,当棋盘变动后,某些位棋盘就需要被更新。例如记录白子所在位置的“WhitePieces”位棋盘。假如我们把 E1格的白车移动到E4格,吃掉黑棋的一个兵。 哪些位棋盘需要更新?嗯,我们来算一下……