%E4%BD%8D%E6%A3%8B%E7%9B%98%28BitBoard%29 - yangboz/godpaper GitHub Wiki

位棋盘(BitBoard).

Table of Contents

有关位棋盘的问题

什么是位棋盘?

位棋盘其实就是一个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
  • ------------------
那么记录白棋棋子初始位置的位棋盘“WhitePieces”是什么样子的呢? 记录(包括黑棋和白棋的)将军和车的初始位置的位棋盘“RookMarshal”是什么样子的呢?
  • ------------------
  • 100010001
  • 000000000
  • 000000000
  • 000000000
  • 000000000
  • 000000000
  • 000000000
  • 000000000
  • 000000000
  • ------------------  

对位棋盘的基本操作

要成功应用位棋盘你必须理解三种基本操作。他们是(1)与,(2)或,(3)异或。关键是这些位操作的速度!回忆以下高中几何学……还记得原理表吗?  

与(&)

  • 0 1 0 1
  • 1 0 0 1
  • ————————
  • 0 0 0 1
相“与”的两“位”必须都是1,结果才是1。  

或(|)

  • 0 1 0 1
  • 1 0 0 1
  • ————————
  • 1 1 0 1
相“或”的两“位”只要有一个是1,结果就是1;否则为0。  

异或(^)

  • 0 1 0 1
  • 1 0 0 1
  • ————————
  • 1 1 0 0
相“异或”的两“位”只要不同,结果就是1;否则为0。 好了,最后,即使不能算“位”操作,我仍然要把这个概念介绍给你。它就是“取补(~)”,你只要记住:如果 a = 0001,那么 ~a = 1110 对应中国象棋,用面向对象的写法这些逻辑运算在位棋盘中就可以这样表示:

棋盘与(&)

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格,吃掉黑棋的一个兵。   哪些位棋盘需要更新?嗯,我们来算一下……

参考: http://www.xqbase.com/computer/struct_bitboard.htm

⚠️ **GitHub.com Fallback** ⚠️