为主教生成对角线移动的位板不起作用
Generating bitboard with diagonal moves for the bishop not working
我正在编写国际象棋人工智能程序。在尝试计算象的所有可能对角线移动时,我遇到了 运行 问题。我认为问题在于函数:reverse_bits()。我不认为我在我的程序中正确处理负二进制数,但我可能是错的。
# ranks
rank1 = int("0000000000000000000000000000000000000000000000000000000011111111", 2)
rank2 = int("0000000000000000000000000000000000000000000000001111111100000000", 2)
rank3 = int("0000000000000000000000000000000000000000111111110000000000000000", 2)
rank4 = int("0000000000000000000000000000000011111111000000000000000000000000", 2)
rank5 = int("0000000000000000000000001111111100000000000000000000000000000000", 2)
rank6 = int("0000000000000000111111110000000000000000000000000000000000000000", 2)
rank7 = int("0000000011111111000000000000000000000000000000000000000000000000", 2)
rank8 = int("1111111100000000000000000000000000000000000000000000000000000000", 2)
# files
filea = int("1000000010000000100000001000000010000000100000001000000010000000", 2)
fileb = int("0100000001000000010000000100000001000000010000000100000001000000", 2)
filec = int("0010000000100000001000000010000000100000001000000010000000100000", 2)
filed = int("0001000000010000000100000001000000010000000100000001000000010000", 2)
filee = int("0000100000001000000010000000100000001000000010000000100000001000", 2)
filef = int("0000010000000100000001000000010000000100000001000000010000000100", 2)
fileg = int("0000001000000010000000100000001000000010000000100000001000000010", 2)
fileh = int("0000000100000001000000010000000100000001000000010000000100000001", 2)
# diagonals
d0 = int("0000000100000000000000000000000000000000000000000000000000000000", 2)
d1 = int("0000001000000001000000000000000000000000000000000000000000000000", 2)
d2 = int("0000010000000010000000010000000000000000000000000000000000000000", 2)
d3 = int("0000100000000100000000100000000100000000000000000000000000000000", 2)
d4 = int("0001000000001000000001000000001000000001000000000000000000000000", 2)
d5 = int("0010000000010000000010000000010000000010000000010000000000000000", 2)
d6 = int("0100000000100000000100000000100000000100000000100000000100000000", 2)
d7 = int("1000000001000000001000000001000000001000000001000000001000000001", 2)
d8 = int("0000000010000000010000000010000000010000000010000000010000000010", 2)
d9 = int("0000000000000000100000000100000000100000000100000000100000000100", 2)
d10 = int("0000000000000000000000001000000001000000001000000001000000001000", 2)
d11 = int("0000000000000000000000000000000010000000010000000010000000010000", 2)
d12 = int("0000000000000000000000000000000000000000100000000100000000100000", 2)
d13 = int("0000000000000000000000000000000000000000000000001000000001000000", 2)
d14 = int("0000000000000000000000000000000000000000000000000000000010000000", 2)
# anti-diagonal
ad0 = int("1000000000000000000000000000000000000000000000000000000000000000", 2)
ad1 = int("0100000010000000000000000000000000000000000000000000000000000000", 2)
ad2 = int("0010000001000000100000000000000000000000000000000000000000000000", 2)
ad3 = int("0001000000100000010000001000000000000000000000000000000000000000", 2)
ad4 = int("0000100000010000001000000100000010000000000000000000000000000000", 2)
ad5 = int("0000010000001000000100000010000001000000100000000000000000000000", 2)
ad6 = int("0000001000000100000010000001000000100000010000001000000000000000", 2)
ad7 = int("0000000100000010000001000000100000010000001000000100000010000000", 2)
ad8 = int("0000000000000001000000100000010000001000000100000010000001000000", 2)
ad9 = int("0000000000000000000000010000001000000100000010000001000000100000", 2)
ad10 = int("0000000000000000000000000000000100000010000001000000100000010000", 2)
ad11 = int("0000000000000000000000000000000000000001000000100000010000001000", 2)
ad12 = int("0000000000000000000000000000000000000000000000010000001000000100", 2)
ad13 = int("0000000000000000000000000000000000000000000000000000000100000010", 2)
ad14 = int("0000000000000000000000000000000000000000000000000000000000000001", 2)
# masks
rankmask = [rank1, rank2, rank3, rank4, rank5, rank6, rank7, rank8]
filemask = [filea, fileb, filec, filed, filee, filef, fileg, fileh]
diagonal = [d14, d13, d12, d11, d10, d9, d8, d7, d6, d5, d4, d3, d2, d1, d0]
antidiagonal = [ad14, ad13, ad12, ad11, ad10, ad9, ad8, ad7, ad6, ad5, ad4, ad3, ad2, ad1, ad0]
last_black_pm = [53, 45]
# bitboards
wp = 0
wr = 0
wn = 0
wb = 0
wq = 0
wk = 0
bp = 0
br = 0
bn = 0
bb = 0
bq = 0
bk = 0
def print_bitboard(bitboard):
board = '{:064b}'.format(bitboard)
for i in range(8):
print(board[8*i+0] + " " + board[8*i+1] + " " + board[8*i+2] + " " + board[8*i+3] + " " + board[8*i+4] + " " + board[8*i+5] + " " + board[8*i+6] + " " + board[8*i+7])
def print_chess_board(bitboard):
board = bitboard
for i in range(8):
print(board[8*i+0] + " " + board[8*i+1] + " " + board[8*i+2] + " " + board[8*i+3] + " " + board[8*i+4] + " " + board[8*i+5] + " " + board[8*i+6] + " " + board[8*i+7])
def integer_to_bitboard(integer):
bitboard = '{:064b}'.format(integer)
return bitboard
def create_starting_bitboards():
global last_black_pm, wp, wr, wn, wb, wq, wk, bp, bn, bb, bq, bk, br
bitboard_all_pieces = "rnbqkbnrpppppppp0000000000B000000000000000000000PPPPPPPPRNBQKBNR"
print_chess_board(bitboard_all_pieces)
for i in range(64):
if bitboard_all_pieces[i] == "P":
wp += 2**(63-i)
if bitboard_all_pieces[i] == "R":
wr += 2**(63-i)
if bitboard_all_pieces[i] == "N":
wn += 2**(63-i)
if bitboard_all_pieces[i] == "B":
wb += 2**(63-i)
if bitboard_all_pieces[i] == "Q":
wq += 2**(63-i)
if bitboard_all_pieces[i] == "K":
wk += 2**(63-i)
if bitboard_all_pieces[i] == "p":
bp += 2**(63-i)
if bitboard_all_pieces[i] == "r":
br += 2**(63-i)
if bitboard_all_pieces[i] == "n":
bn += 2**(63-i)
if bitboard_all_pieces[i] == "b":
bb += 2**(63-i)
if bitboard_all_pieces[i] == "q":
bq += 2**(63-i)
if bitboard_all_pieces[i] == "k":
bk += 2**(63-i)
occupied = wp | wr | wn | wb | wq | wk | bp | br | bn | bb | bq | bk
# g_white_pawn_moves(wp, wr, wn, wb, wq, wk, bp, br, bn, bb, bq, bk)
g_white_bishop_moves(wp, wr, wn, wb, wq, wk, occupied)
def reverse_bits(num):
num = '{:064b}'.format(num)[::-1]
if num[-1] == "-":
num = num[:-1]
return int(num, 2)
def vertical_horizontal_moves(s, occupied):
global rankmask, filemask
ranknum = int(s/8)
filenum = 7 - int(s % 8)
slider = 1 << s
horizontal = ((occupied - 2*slider) ^ reverse_bits(reverse_bits(occupied)-2*reverse_bits(slider))) & rankmask[ranknum]
vertical = (((occupied & filemask[filenum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & filemask[filenum]) - 2 * reverse_bits(slider))) & filemask[filenum]
print_bitboard(vertical ^ horizontal)
return vertical ^ horizontal
def diagonal_antidiagonal_moves(s, occupied):
global diagonal, antidiagonal
diagonalnum = 7 - int(s % 8) + int(s/8)
antidiagonalnum = int(s / 8) + int(s % 8)
slider = 1 << s
diag1 = (((occupied & diagonal[diagonalnum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & diagonal[diagonalnum]) - 2 * reverse_bits(slider))) & diagonal[diagonalnum]
diag2 = (((occupied & antidiagonal[antidiagonalnum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & antidiagonal[antidiagonalnum]) - 2 * reverse_bits(slider))) & antidiagonal[antidiagonalnum]
return diag1 ^ diag2
def g_white_bishop_moves(wp, wr, wn, wb, wq, wk, occupied):
white_pieces = wp | wr | wn | wb | wq | wk
moves_list = []
for i in range(64):
if (wb >> i) & 1 == 1:
moves = diagonal_antidiagonal_moves(i, occupied) & ~white_pieces
for j in range(64):
if (moves >> j) & 1 == 1:
moves_list.extend((i, j))
print("")
print_bitboard(moves)
def g_white_pawn_moves(wp, wr, wn, wb, wq, wk, bp, br, bn, bb, bq, bk):
global rank8, rank4, rank5, fileh, filea, filemask
empty = ~(wp | wr | wn | wb| wq | wk | bp | br | bn | bb | bq | bk)
black = bp | br | bn | bb | bq
moves_list = []
# pawn 1 forward
moves = (wp << 8) & empty & ~ rank8
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i-8, i, ""))
# pawn 2 forward
moves = (wp << 16) & empty & (empty << 8) & rank4
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i-16, i, ""))
# pawn left capture
moves = (wp << 9) & black & ~ rank8 & ~ fileh
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, ""))
# pawn right capture
moves = (wp << 7) & black & ~ rank8 & ~ filea
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, ""))
# en passant
if last_black_pm[0] - last_black_pm[1] == 16:
filenum = 7 - int(last_black_pm[1] % 8)
# en passant left
moves = (wp << 1) & black & rank5 & ~fileh & filemask[filenum] # pawn_capture_right
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 1, i + 8, "E")) # store piece field/ and move field 0-63
# en passant right
moves = (wp >> 1) & black & rank5 & ~filea & filemask[filenum] # pawn_capture_left
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i + 1, i + 8, "E")) # store piece field/ and move field 0-63
# pawn promotion
# pawn 1 forward
moves = (wp << 8) & empty & rank8
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 8, i, "P"))
# pawn left capture
moves = (wp << 9) & black & rank8 & ~ fileh
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, "P"))
# pawn right capture
moves = (wp << 7) & black & rank8 & ~ filea
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, "P"))
print(moves_list)
create_starting_bitboards()
例如在这种情况下,它会正确计算出所有可能的主教移动:
r n b q k b n r
p p p p p p p p
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 B 0 0 0 0 0
0 0 0 0 0 0 0 0
P P P P P P P P
R N B Q K B N R
0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0
1 0 0 0 1 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
但是当我将主教移动到另一个方格时,会发生这种情况:
r n b q k b n r
p p p p p p p p
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 B 0 0 0 0 0 0
0 0 0 0 0 0 0 0
P P P P P P P P
R N B Q K B N R
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
当我检查名为 diagonal_antidiagonal_moves() 的函数中的代码时,它找到了所有 diagonal/antidiagonal 步,我开始打印出不同的位板。我注意到一些位板上有“-”符号。例如我拿了: reverse_bits(occupied & antidiagonal[antidiagonalnum]) - 2 * reverse_bits(slider) from
diag2 = (((occupied & antidiagonal[antidiagonalnum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & antidiagonal[antidiagonalnum]) - 2 * reverse_bits(slider))) & antidiagonal[antidiagonalnum]
并打印出位板。这是结果:
- 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 0 1 1 1 1
1 1 1 0 0 0 0 0
这就是为什么我认为我在reverse_bits-函数中反转负整数时一定有问题。
有趣的是,函数 vertical_horizontal_moves() 用于查找所有可能的车移动,似乎工作得很好。
我希望有人能告诉我我的代码到底出了什么问题。
正如您所怀疑的,reverse_bits
确实是错误的。这很容易用一个例子来证明:reverse_bits(-1)
returns 值 0x4000000000000000。
reverse_bits
的当前实现已经适用于非负数,因此可以通过屏蔽输入将其变为非负数同时保留与此上下文相关的所有位(最低 64 ):
def reverse_bits(num):
num = num & 0xffffffffffffffff
num = '{:064b}'.format(num)[::-1]
return int(num, 2)
我正在编写国际象棋人工智能程序。在尝试计算象的所有可能对角线移动时,我遇到了 运行 问题。我认为问题在于函数:reverse_bits()。我不认为我在我的程序中正确处理负二进制数,但我可能是错的。
# ranks
rank1 = int("0000000000000000000000000000000000000000000000000000000011111111", 2)
rank2 = int("0000000000000000000000000000000000000000000000001111111100000000", 2)
rank3 = int("0000000000000000000000000000000000000000111111110000000000000000", 2)
rank4 = int("0000000000000000000000000000000011111111000000000000000000000000", 2)
rank5 = int("0000000000000000000000001111111100000000000000000000000000000000", 2)
rank6 = int("0000000000000000111111110000000000000000000000000000000000000000", 2)
rank7 = int("0000000011111111000000000000000000000000000000000000000000000000", 2)
rank8 = int("1111111100000000000000000000000000000000000000000000000000000000", 2)
# files
filea = int("1000000010000000100000001000000010000000100000001000000010000000", 2)
fileb = int("0100000001000000010000000100000001000000010000000100000001000000", 2)
filec = int("0010000000100000001000000010000000100000001000000010000000100000", 2)
filed = int("0001000000010000000100000001000000010000000100000001000000010000", 2)
filee = int("0000100000001000000010000000100000001000000010000000100000001000", 2)
filef = int("0000010000000100000001000000010000000100000001000000010000000100", 2)
fileg = int("0000001000000010000000100000001000000010000000100000001000000010", 2)
fileh = int("0000000100000001000000010000000100000001000000010000000100000001", 2)
# diagonals
d0 = int("0000000100000000000000000000000000000000000000000000000000000000", 2)
d1 = int("0000001000000001000000000000000000000000000000000000000000000000", 2)
d2 = int("0000010000000010000000010000000000000000000000000000000000000000", 2)
d3 = int("0000100000000100000000100000000100000000000000000000000000000000", 2)
d4 = int("0001000000001000000001000000001000000001000000000000000000000000", 2)
d5 = int("0010000000010000000010000000010000000010000000010000000000000000", 2)
d6 = int("0100000000100000000100000000100000000100000000100000000100000000", 2)
d7 = int("1000000001000000001000000001000000001000000001000000001000000001", 2)
d8 = int("0000000010000000010000000010000000010000000010000000010000000010", 2)
d9 = int("0000000000000000100000000100000000100000000100000000100000000100", 2)
d10 = int("0000000000000000000000001000000001000000001000000001000000001000", 2)
d11 = int("0000000000000000000000000000000010000000010000000010000000010000", 2)
d12 = int("0000000000000000000000000000000000000000100000000100000000100000", 2)
d13 = int("0000000000000000000000000000000000000000000000001000000001000000", 2)
d14 = int("0000000000000000000000000000000000000000000000000000000010000000", 2)
# anti-diagonal
ad0 = int("1000000000000000000000000000000000000000000000000000000000000000", 2)
ad1 = int("0100000010000000000000000000000000000000000000000000000000000000", 2)
ad2 = int("0010000001000000100000000000000000000000000000000000000000000000", 2)
ad3 = int("0001000000100000010000001000000000000000000000000000000000000000", 2)
ad4 = int("0000100000010000001000000100000010000000000000000000000000000000", 2)
ad5 = int("0000010000001000000100000010000001000000100000000000000000000000", 2)
ad6 = int("0000001000000100000010000001000000100000010000001000000000000000", 2)
ad7 = int("0000000100000010000001000000100000010000001000000100000010000000", 2)
ad8 = int("0000000000000001000000100000010000001000000100000010000001000000", 2)
ad9 = int("0000000000000000000000010000001000000100000010000001000000100000", 2)
ad10 = int("0000000000000000000000000000000100000010000001000000100000010000", 2)
ad11 = int("0000000000000000000000000000000000000001000000100000010000001000", 2)
ad12 = int("0000000000000000000000000000000000000000000000010000001000000100", 2)
ad13 = int("0000000000000000000000000000000000000000000000000000000100000010", 2)
ad14 = int("0000000000000000000000000000000000000000000000000000000000000001", 2)
# masks
rankmask = [rank1, rank2, rank3, rank4, rank5, rank6, rank7, rank8]
filemask = [filea, fileb, filec, filed, filee, filef, fileg, fileh]
diagonal = [d14, d13, d12, d11, d10, d9, d8, d7, d6, d5, d4, d3, d2, d1, d0]
antidiagonal = [ad14, ad13, ad12, ad11, ad10, ad9, ad8, ad7, ad6, ad5, ad4, ad3, ad2, ad1, ad0]
last_black_pm = [53, 45]
# bitboards
wp = 0
wr = 0
wn = 0
wb = 0
wq = 0
wk = 0
bp = 0
br = 0
bn = 0
bb = 0
bq = 0
bk = 0
def print_bitboard(bitboard):
board = '{:064b}'.format(bitboard)
for i in range(8):
print(board[8*i+0] + " " + board[8*i+1] + " " + board[8*i+2] + " " + board[8*i+3] + " " + board[8*i+4] + " " + board[8*i+5] + " " + board[8*i+6] + " " + board[8*i+7])
def print_chess_board(bitboard):
board = bitboard
for i in range(8):
print(board[8*i+0] + " " + board[8*i+1] + " " + board[8*i+2] + " " + board[8*i+3] + " " + board[8*i+4] + " " + board[8*i+5] + " " + board[8*i+6] + " " + board[8*i+7])
def integer_to_bitboard(integer):
bitboard = '{:064b}'.format(integer)
return bitboard
def create_starting_bitboards():
global last_black_pm, wp, wr, wn, wb, wq, wk, bp, bn, bb, bq, bk, br
bitboard_all_pieces = "rnbqkbnrpppppppp0000000000B000000000000000000000PPPPPPPPRNBQKBNR"
print_chess_board(bitboard_all_pieces)
for i in range(64):
if bitboard_all_pieces[i] == "P":
wp += 2**(63-i)
if bitboard_all_pieces[i] == "R":
wr += 2**(63-i)
if bitboard_all_pieces[i] == "N":
wn += 2**(63-i)
if bitboard_all_pieces[i] == "B":
wb += 2**(63-i)
if bitboard_all_pieces[i] == "Q":
wq += 2**(63-i)
if bitboard_all_pieces[i] == "K":
wk += 2**(63-i)
if bitboard_all_pieces[i] == "p":
bp += 2**(63-i)
if bitboard_all_pieces[i] == "r":
br += 2**(63-i)
if bitboard_all_pieces[i] == "n":
bn += 2**(63-i)
if bitboard_all_pieces[i] == "b":
bb += 2**(63-i)
if bitboard_all_pieces[i] == "q":
bq += 2**(63-i)
if bitboard_all_pieces[i] == "k":
bk += 2**(63-i)
occupied = wp | wr | wn | wb | wq | wk | bp | br | bn | bb | bq | bk
# g_white_pawn_moves(wp, wr, wn, wb, wq, wk, bp, br, bn, bb, bq, bk)
g_white_bishop_moves(wp, wr, wn, wb, wq, wk, occupied)
def reverse_bits(num):
num = '{:064b}'.format(num)[::-1]
if num[-1] == "-":
num = num[:-1]
return int(num, 2)
def vertical_horizontal_moves(s, occupied):
global rankmask, filemask
ranknum = int(s/8)
filenum = 7 - int(s % 8)
slider = 1 << s
horizontal = ((occupied - 2*slider) ^ reverse_bits(reverse_bits(occupied)-2*reverse_bits(slider))) & rankmask[ranknum]
vertical = (((occupied & filemask[filenum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & filemask[filenum]) - 2 * reverse_bits(slider))) & filemask[filenum]
print_bitboard(vertical ^ horizontal)
return vertical ^ horizontal
def diagonal_antidiagonal_moves(s, occupied):
global diagonal, antidiagonal
diagonalnum = 7 - int(s % 8) + int(s/8)
antidiagonalnum = int(s / 8) + int(s % 8)
slider = 1 << s
diag1 = (((occupied & diagonal[diagonalnum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & diagonal[diagonalnum]) - 2 * reverse_bits(slider))) & diagonal[diagonalnum]
diag2 = (((occupied & antidiagonal[antidiagonalnum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & antidiagonal[antidiagonalnum]) - 2 * reverse_bits(slider))) & antidiagonal[antidiagonalnum]
return diag1 ^ diag2
def g_white_bishop_moves(wp, wr, wn, wb, wq, wk, occupied):
white_pieces = wp | wr | wn | wb | wq | wk
moves_list = []
for i in range(64):
if (wb >> i) & 1 == 1:
moves = diagonal_antidiagonal_moves(i, occupied) & ~white_pieces
for j in range(64):
if (moves >> j) & 1 == 1:
moves_list.extend((i, j))
print("")
print_bitboard(moves)
def g_white_pawn_moves(wp, wr, wn, wb, wq, wk, bp, br, bn, bb, bq, bk):
global rank8, rank4, rank5, fileh, filea, filemask
empty = ~(wp | wr | wn | wb| wq | wk | bp | br | bn | bb | bq | bk)
black = bp | br | bn | bb | bq
moves_list = []
# pawn 1 forward
moves = (wp << 8) & empty & ~ rank8
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i-8, i, ""))
# pawn 2 forward
moves = (wp << 16) & empty & (empty << 8) & rank4
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i-16, i, ""))
# pawn left capture
moves = (wp << 9) & black & ~ rank8 & ~ fileh
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, ""))
# pawn right capture
moves = (wp << 7) & black & ~ rank8 & ~ filea
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, ""))
# en passant
if last_black_pm[0] - last_black_pm[1] == 16:
filenum = 7 - int(last_black_pm[1] % 8)
# en passant left
moves = (wp << 1) & black & rank5 & ~fileh & filemask[filenum] # pawn_capture_right
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 1, i + 8, "E")) # store piece field/ and move field 0-63
# en passant right
moves = (wp >> 1) & black & rank5 & ~filea & filemask[filenum] # pawn_capture_left
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i + 1, i + 8, "E")) # store piece field/ and move field 0-63
# pawn promotion
# pawn 1 forward
moves = (wp << 8) & empty & rank8
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 8, i, "P"))
# pawn left capture
moves = (wp << 9) & black & rank8 & ~ fileh
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, "P"))
# pawn right capture
moves = (wp << 7) & black & rank8 & ~ filea
for i in range(64):
if (moves >> i) & 1 == 1:
moves_list.extend((i - 9, i, "P"))
print(moves_list)
create_starting_bitboards()
例如在这种情况下,它会正确计算出所有可能的主教移动:
r n b q k b n r
p p p p p p p p
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 B 0 0 0 0 0
0 0 0 0 0 0 0 0
P P P P P P P P
R N B Q K B N R
0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0
1 0 0 0 1 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
但是当我将主教移动到另一个方格时,会发生这种情况:
r n b q k b n r
p p p p p p p p
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 B 0 0 0 0 0 0
0 0 0 0 0 0 0 0
P P P P P P P P
R N B Q K B N R
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
当我检查名为 diagonal_antidiagonal_moves() 的函数中的代码时,它找到了所有 diagonal/antidiagonal 步,我开始打印出不同的位板。我注意到一些位板上有“-”符号。例如我拿了: reverse_bits(occupied & antidiagonal[antidiagonalnum]) - 2 * reverse_bits(slider) from
diag2 = (((occupied & antidiagonal[antidiagonalnum]) - 2 * slider) ^ reverse_bits(reverse_bits(occupied & antidiagonal[antidiagonalnum]) - 2 * reverse_bits(slider))) & antidiagonal[antidiagonalnum]
并打印出位板。这是结果:
- 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 0 1 1 1 1
1 1 1 0 0 0 0 0
这就是为什么我认为我在reverse_bits-函数中反转负整数时一定有问题。
有趣的是,函数 vertical_horizontal_moves() 用于查找所有可能的车移动,似乎工作得很好。
我希望有人能告诉我我的代码到底出了什么问题。
reverse_bits
确实是错误的。这很容易用一个例子来证明:reverse_bits(-1)
returns 值 0x4000000000000000。
reverse_bits
的当前实现已经适用于非负数,因此可以通过屏蔽输入将其变为非负数同时保留与此上下文相关的所有位(最低 64 ):
def reverse_bits(num):
num = num & 0xffffffffffffffff
num = '{:064b}'.format(num)[::-1]
return int(num, 2)