ビットボードの水平反転
盤面の左右の反転は、Hacker's Delight 的アプローチで簡単にできる。
3回のビット交換を行った後、5筋を追加すればよい。(変換処理は24基本RISC命令で分岐不要)
各段について以下の処理を行うイメージ。
x ← abcdefghi 初期状態
y ← .a.c..f.h + b.d..g.i. = badc.gfih 隣り合うビットを交換
y ← ..ba...gf + dc...ih.. = dcba.ihgf 2ビットを交換
.....dcba + ihgf..... + ....e.... = ihgfedcba 4ビットを交換した後、中央のビットを抽出して加算
def mirror_horizontal(self): """Return bitboard mirrored horizontally.""" x = self.data y = ((x & int('101001010' * 9, 2)) >> 1) + ((x & int('010100101' * 9, 2)) << 1) y = ((y & int('110001100' * 9, 2)) >> 2) + ((y & int('001100011' * 9, 2)) << 2) return BitBoard(((y & int('111100000' * 9, 2)) >> 5) + ((y & int('000001111' * 9, 2)) << 5) + (x & int('000010000' * 9, 2)))
反転前 | 反転後 |
--------* |
*-------- |
加算部分は、論理和演算でも同値だが、手元の計測では加算のほうが性能がよかった。
>>> min(timeit.Timer("0x155555555555555555555 | 0xaaaaaaaaaaaaaaaaaaaa").repeat(100)) 0.03194931199357143 >>> min(timeit.Timer("0x155555555555555555555 + 0xaaaaaaaaaaaaaaaaaaaa").repeat(100)) 0.026588016074668985
参考:
http://chessprogramming.wikispaces.com/Flipping+Mirroring+and+Rotating
0 件のコメント:
コメントを投稿