我正在尝试理解这个片段
for (; game->boxes_left > 0; game->turns++)
{
if ( (game->turns & 1) ^ game->computer_first )
game->human_move();
else
game->computer_move();
}
因为inf game->turns
是一个整数,它的值越来越大,而game->comp_first
是一个布尔值,有人请告诉我if ( (game->turns & 1) ^ game->computer_first )
如何将它返回1(真)或0(假的)?
因为我理解&
是按位运算符,而当turns & 1
它总是返回0,因为turns
是一个递增的值,{if {1}}在这个if语句中的作用是什么?有没有办法在java中编写这个片段。提前致谢
答案 0 :(得分:3)
当game->turns
经历连续值时,其最后一位在每次迭代时在0和1之间切换。结果,game->turns & 1
也介于0和1之间。如果bool为假,则使用bool对结果进行异或,给出相同的值,如果bool为真,则为反转值。
game->turns Last bit XOR 0 XOR 1
----------- -------- ----- -----
0 0 0 1
1 1 1 0
2 0 0 1
3 1 1 0
4 0 0 1
5 1 1 0
注意game->computer_first
为false
时序列为0-1-0-1-0-1,game->computer_first
为1-0-1-0-1-0是true
。
要将此代码段转换为Java,请将game.turns & 1
的结果与)
进行比较:
if (((game.turns & 1) != 0) ^ game->computer_first) ...
答案 1 :(得分:2)
game-> turn& 1对于游戏的每个值都将返回true - >转为奇数。 E.g:
turns= 0x00001111
one= 0x00000001
result=0x00000001
因为两个值的最右边的位都是“1”。如果computer_first也是“1”,例如true,if语句将返回false,因为1 ^ 1 = 0。
如果你问我,看起来像是一种相当迂回的做事方式。问题与if (game->turns % 2) != game->computer_first
有什么关系?
答案 2 :(得分:0)
正如其他人已经指出的那样,这段代码是基于这样一个事实:当你递增一个数字时,它的二进制表示的最低有效位在on和off之间交替。
IMO,缺乏可读性主要是一个更大问题的症状:代码的逻辑并不是最好的。我想我的做法有点不同。这是一个极少数情况,其中一些指向成员函数的指针真正有意义并且简化了代码。
由于我不知道实际的类型,我将假设game
是指向Game
类型的对象的指针。从那里开始,定义指向第一个和第二个玩家的成员函数的指针,然后编写一个由一对移动而不是单个移动组成的循环(或者,根据您的观点,更像是一个每次迭代完成移动。)
typedef void (Game::*pmf)();
pmf first_player = &Game::human_move;
pmf second_player = &Game::computer_move;
if (game->comp_first)
std::swap(first_player, second_player);
for ( ; game->boxes_left > 0; game->turns+=2) {
game->*first_player();
game->*second_player();
}
不幸的是,虽然这使得代码更简洁,更简单,但它也使得转换为Java变得更加困难 - Java没有直接模拟C ++指向成员函数的指针。通常的替代方法是定义一个接口,然后是一个实现该接口的匿名类。在你完成所有这些之前,从一些代码重复的东西开始可能更简单:
if (game->comp_first)
for (; game->boxes_left > 0; game->turns+=2) {
game->computer_move();
game->player_move();
}
else
for (; game->boxes_left > 0; game->turns+=2) {
game->player_move();
game->computer_move();
}
...由于此代码不使用任何高级功能,因此将其转换为Java等低级语言应该相当简单。对我来说,使用指向成员函数的指针给我看起来很明显,它提供了最干净的结果,但我仍然认为最后一个版本比你开始时更清晰。
我想我应该再添加一个细节。根据具体情况,您可能必须在只有一名玩家移动后退出循环。如果这对你正在实施的任何游戏都有可能,你可以改变这两行:
game->*first_player();
game->*second_player();
而是让每个move函数返回一个布尔值,指示在该移动之后是否仍然可以进一步播放,并且你的循环体将变成类似:
if (game->*first_player())
game->*second_player();