正如其他人已经指出的那样,此代码基于这样一个事实,即当您增加一个数字时,其二进制表示的最低有效位会在开和关之间交替。
IMO,缺乏可读性很大程度上是一个更大问题的症状:代码的逻辑并不是最好的。我想我会做一些不同的事情。这是少数几个指向成员函数的指针真正有意义并大大简化代码的情况之一。
由于我不知道实际的类型,我将假设它game
是一个指向 type 对象的指针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 之类的低级语言应该相当简单。在我看来,使用指向成员函数的指针可以得到最干净的结果,但我仍然认为最后一个版本比你开始的版本要干净得多。
I suppose I should add one more detail. Depending on the situation, it's possible that you may have to exit the loop after only one player has made a move. If that's possible for whatever game you're implementing, you'd change the two lines like this:
game->*first_player();
game->*second_player();
and instead have each of the move functions return a boolean indicating whether further play remains possible following that move, and your loop body would become something like:
if (game->*first_player())
game->*second_player();