我正在搞乱按位操作,想要实现简单的逻辑谜题,你有一只狐狸(狼),鸡(鹅),谷物(玉米)和一个试图过河的人。我正在使用前4位来表示它们所在河的哪一侧。
我在尝试实现逻辑方面遇到了一些麻烦。
如何检查这两位是1还是0而不是1和0?
int game()
{
int state = 0;
int done = 0;
while (!done)
{
int input = 0;
input = move();
/*
0000 0000
|||\_grain
||\__chicken
|\___fox
\____person
0 = left side of the river
1 = right side
*/
if (input == 3)// Moves person and grain
{
// Move the grain if the person is on the same side.
if (!(state & 1 << 3 ^ state & 1<< 0))
{
state ^= 1 << 3;
state ^= 1 << 0;
}
else
{
// Always switch the person no matter what
state ^= 1 << 3;
}
}
else if (input == 2) // Moves person and chicken
{
// Move Chicken only if person is on the same side
if (!(state & 1 << 3 ^ state & 1<< 1))
{
state ^= 1 << 3;
state ^= 1 << 1;
}
else
{
// Always switch the person no matter what
state ^= 1 << 3;
}
}
else if (input == 1)// Moves person and fox
{
// Move the fox if the person is on the same side.
if (!(state & 1 << 3 ^ state & 1<< 2))
{
state ^= 1 << 3;
state ^= 1 << 2;
}
else
{
// Always switch the person no matter what
state ^= 1 << 3;
}
}
// Fox and Chicken on one side and person on the other = lost
if ((state & 1 << 2 && state & 1 << 1) && ~(state & 1 << 3))
{
printf("Failed\n");
}
}
return 1;
}
我猜测按位检查将是更优雅的代码,但它似乎更像是一种痛苦。当我厌倦了用按位逻辑击中墙壁时,我总是这样做。
int game()
{
int state = 0;
int done = 0;
while (!done)
{
int input = 0;
input = move();
/*
0000 0000
| | | \_grain
| | \__chicken
| \___fox
\____person
0 = left side of the river
1 = right side
*/
if (input == 3)// Moves person and grain
{
// Are they on the same side?
if (state == 9 || state == 11 || state == 13 || state == 15 ||
state == 0 || state == 2 || state == 4 || state == 6)
{
// Move the person and grain
state ^= 1 << 3;
state ^= 1 << 0;
}
else
{
state ^= 1 << 3;
}
}
else if (input == 2) // Moves person and chicken
{
// Are they on the same side?
if (state == 10 || state == 11 || state == 14 || state == 15 ||
state == 0 || state == 1 || state == 4 || state == 5)
{
// Move the person and chicken
state ^= 1 << 3;
state ^= 1 << 1;
}
else
{
state ^= 1 << 3;
}
}
else if (input == 1)// Moves person and fox
{
// Are they on the same side?
if (state == 12 || state == 13 || state == 14 || state == 15 ||
state == 0 || state == 1 || state == 2 || state == 3)
{
// Move the person and fox
state ^= 1 << 3;
state ^= 1 << 2;
}
else
{
state ^= 1 << 3;
}
}
else
{
// Always switch the person no matter what
state ^= 1 << 3;
}
//Check if you won or lost
if (state == 3 || state == 6 || state == 8 || state == 9 || state == 12) // Lost
{
return 0;
}
if (state == 15) // Won
{
return 1;
}
}
return 1;
}
答案 0 :(得分:2)
如何检查这两位是1还是0而不是1和0?
如何比较它们的平等性?
#define MAN_MASK (1<<3)
#define GRAIN_MASK (1<<0)
if(
((state & MAN_MASK) == 0)
==
((state & GRAIN_MASK) == 0)
);
答案 1 :(得分:2)
只要它不为零,C就会将if语句的条件评估为true。
XOR运算符(^)可能不是您想用来测试是否设置了一个位,例如:
// Move the grain if the person is on the same side.
if (state ^ 1 << 3 && state ^ 1 << 0)
假设在这种情况下状态变量应该失败,忽略sizeof int,并使用1110 0001
的位掩码。这使人处于河流的高阶侧,谷物处于低阶侧。
if语句的第一个条件state ^ 1 << 3
将创建1110 1001
的临时掩码。第二种,状态^ 1&lt;&lt; 0,将创建1110 0000
的位掩码。这是胡说八道,而不是你想要的。
因此,如果输入要失败(1110 0001
),则此if语句类似于:
if ( 0b11101001 && 0b11100000 )
哪个成功(这很糟糕。)
您可能想要做的是确保谷物和人都位于“河流”的右侧,在各自的位置(1 <&lt;&lt; 3&lt;&lt; 0&lt; 0) 。您可以使用的最佳按位运算符是AND运算符。
这有点像家庭作业问题,所以我不会完全回答你的问题;但是你应该有足够的背景来让自己指向正确的方向。
答案 2 :(得分:1)
要检查两个位是否处于相同状态,将其中一个位移到另一个位,XOR
将它们放在一起,AND
指示位置,并检查结果为零。例如,要查看第1位与第3位相同,请执行以下操作:
// Shift bit 3 to position 1, XOR, mask with 2, and check for zero
if ((2 & ((state >> 2) ^ state)) == 0) {
...
}