我正在使用Java为Conway's Game of Life
建模。我先设置好一点,然后再打印。
我当前的setCell
方法正在更改指定的位以及该位索引之后的所有位,而不只是更改指定索引处的位。
我需要如何更改班级?
public class TinyLife {
private final int side_length = 8;
private long world;
public TinyLife(long world){
this.world = world;
}
public void printWorld(){
System.out.println("\nThe current world:");
for (int row = 0; row < side_length; row++){
for (int col = 0; col < side_length; col++){
System.out.print(getCell(col, row) ? " # " : " _ ");
}
System.out.println();
}
}
public boolean getCell(int col, int row){
int index = (row * side_length) + col;
long a = world >> index; // Shift the bits by position.
long c = a & 1;
return (c == 1);
}
public void setCell(int col, int row, boolean value) {
int index = col + (row * side_length);
System.out.println(index);
/* I think that the error is below. Why are all the bits to the left of the bit at the index also being set? */
if (value) {
world |= (1 << index);
}
else world = world & ~(1 << index);
}
public static void main(String[] args) {
long first_world = 0x20272000027202L;
TinyLife world = new TinyLife(first_world);
world.printWorld();
System.out.println("Binary rep before setCell = " + Long.toBinaryString(world.world));
world.setCell(7, 3, true);
System.out.println("Binary rep after setCell = " + Long.toBinaryString(world.world));
world.printWorld();
}
}
预期的打印输出:
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ # _ _
# # # _ _ # _ _
_ _ _ _ _ # _ _
_ _ _ _ _ _ _ _
Binary rep before setCell = 100000001001110010000000000000000000100111001000000010
31
Binary rep after setCell = 100000001001110010000010000000000000100111001000000010
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ #
_ _ _ _ _ # _ _
# # # _ _ # _ _
_ _ _ _ _ # _ _
_ _ _ _ _ _ _ _
实际打印输出:
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ # _ _
# # # _ _ # _ _
_ _ _ _ _ # _ _
_ _ _ _ _ _ _ _
Binary rep before setCell = 100000001001110010000000000000000000100111001000000010
31
Binary rep after setCell = 1111111111111111111111111111111110000000000000100111001000000010
The current world:
_ # _ _ _ _ _ _
_ # _ _ # # # _
_ # _ _ _ _ _ _
_ _ _ _ _ _ _ #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
(请注意,我在上面的文本中添加了一些换行符,以使我的问题更易于阅读)
非常感谢您的帮助。
答案 0 :(得分:1)
问题是1 <<索引是int操作,而不是long 操作。
这对 Andreas 是正确的。我想补充一点,您在3个地方使用索引计算,但是这个问题仅出现在其中一个地方。我认为您可以将其提取为单独的方法并使用它。可能会更清楚。
// convert given `cal` and `row` to long with single bit set
private long bit(int col, int row) {
// optionally you could add check for correct col and row (0 <= col (row) <= side_length - 1)
return 1L << (row * side_length) + col;
}
然后您可以简化代码:
public boolean getCell(int col, int row) {
return (world & bit(col, row)) != 0;
}
public void setCell(int col, int row, boolean value) {
if (value)
world |= bit(col, row);
else
world &= ~bit(col, row);
}
答案 1 :(得分:0)
问题在于1 << index
是int
操作,而不是long
操作。
使用输入col = 7, row = 3
,计算index = col + (row * side_length)
产生值31
,该值在int
中是符号位。>
world |= (1 << index)
然后使用 sign-extension 将int
的值扩展为long
,并将所有高32位设置为1。
将代码更改为world |= (1L << index)
,因此将移位作为long
完成。这样,它也可以为index
值大于31的情况工作。