我正在尝试制作带有位板的Bejeweled级联模拟器。到目前为止,我已经能够检测并删除匹配,但现在我需要让珠宝掉下来。我的状态由位板列表代表,每种类型的宝石都有一个。我有一个被删除的所有珠宝的面具。
是否可以使用一些按位魔术来做到这一点?
两个初始位板的示例(我们假设只有两种类型的珠宝,它是4x4板而不是8x8)。第一位是左下角,第四位是左上角,最后一位是右上角。
0 0 1 1 1 1 0 0
1 0 0 0 0 1 1 1
1 1 1 1 0 0 0 0
0 0 1 0 1 1 0 1
删除匹配后:
0 0 1 1 1 1 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 0 1 1 0 1
使用的面具是:
0 0 0 0
0 1 1 1
1 1 1 1
0 0 0 0
在重力之后它应该看起来像:
0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
1 0 1 1 0 1 0 0
0 0 1 0 1 1 0 1
这是用整数实现的,步骤如下:
[43814, 21721] # Initial state
[35076, 4249], 26210 # State after matches have been removed, mask used to remove matches
[8962, 4149] # State after gravity has been applied
答案 0 :(得分:0)
要使用bithift将你的面具移动一行所需的位数。使用掩码从上面的行中选择位,并使用位移和oring将所选位复制一行。简单的算法会将掩码循环到顶部并逐行向下移动。但优化可能是通过位移和自我进行扩展来扩展掩码,然后通过单次操作将所有上面的位移动。
位板操作的良好来源是国际象棋维基:https://chessprogramming.wikispaces.com/General+Setwise+Operations
答案 1 :(得分:0)
让我们打电话给左边的宝石,A
;右边,B
;以及董事会的物理代表,AB
。
在删除之后,我们有:
0 0 1 1 1 1 0 0 1111
AB = A | B = 1 0 0 0 or 0 0 0 0 = 1000
0 0 0 0 0 0 0 0 0000
0 0 1 0 1 1 0 1 1111
算法:
For each row (r, a temporary variable) above the lowest row with removals:
For each jewel type:
starting with the lowest row where removals occurred (AB_row)
While r is not zero
make a temporary copy of AB_row (AB_row_copy)
new row for jewel_type := (row | AB_row) ^ same_row_for_other_jewel_types
r := r & AB_row_copy
ascend to next row of AB
示例:
使用删除更新最低行上方的第一行:
# AB_row is the lowest row with removals from the bitboard that combines all
# jewel types; r_A is a copy from the A bitboard of the first row above AB_row
r_A = 1 0 0 0, AB_row = 0 0 0 0
# make a copy of AB_row
AB_row_copy = 0 0 0 0
# calculate the new row for jewel type A
# new row for jewel_type := (row | AB_row) ^ same_row_for_other_jewel_types
new row for A = (1 0 0 0 | 0 0 0 0) ^ 0 0 0 0 = 1 0 0 0
# update the fallen bits from r_A
# r := r & AB_row_copy
r_A = 1 0 0 0 & 0 0 0 0 = 0 0 0 0
# r_B at this row is zero, nothing to do.
r_B = 0 0 0 0
使用删除更新最低行上方的第二行:
# row for A has the same process same as above
r_A = 0 0 1 1, AB_row = 1 0 0 0 // AB_row is the lowest row with removals
AB_row_copy = 1 0 0 0
new row for A = (0 0 1 1 | 1 0 0 0) ^ 0 0 0 0 = 1 0 1 1
r_A = 0 0 1 1 & 1 0 0 0 = 0 0 0 0
# AB_row is the lowest row with removals from the bitboard that combines all
# jewel types; r_B is a copy from the B bitboard of the second row above AB_row
r_B = 1 1 0 0, AB_row = 1 0 1 1
# make a copy of AB_row
AB_row_copy = 1 0 1 1
# calculate the new row for jewel type B
# new row for jewel_type := (row | AB_row) ^ same_row_for_other_jewel_types
new row for B = (1 1 0 0 | 1 0 1 1) ^ 1 0 1 1 = 0 1 0 0
# update the fallen bits from r_B
# r := r & AB_row_copy
r_B = 1 1 0 0 & 1 0 1 1 = 1 0 0 0
# since there are still set bits remaining in r_B after removing the fallen
# bit, we continue with r_B, proceeding to the next row up.
# AB_row now is the next row up from the lowest row with removals, again from
# the bitboard combining all jewel types; r_B is the same variable, now with
# one set bit less (one "fallen" bit)
r_B = 1 0 0 0, AB_row = 0 0 0 0
# make a copy of AB_row
AB_row_copy = 0 0 0 0
# calculate the new row for jewel type B
# new row for jewel_type := (row | AB_row) ^ same_row_for_other_jewel_types
new row for B = (1 0 0 0 | 0 0 0 0) ^ 0 0 0 0 = 1 0 0 0
# update the fallen bits from r_B
r_B = 1 0 0 0 & 0 0 0 0 = 0 0 0 0
#r_B is now zero so the while loop is terminated