下面的代码确实按照我需要的方式工作,但它很丑,过多或其他一些事情。我已经看了公式,并试图写一些解决方案,但我最终得到了类似数量的语句。
在这种情况下,是否有一种数学公式对我有益,或者是否可以接受16个if语句?
为了解释代码,这是一款基于同时回合制的游戏。两名玩家各有四个操作按钮,结果来自一个数组(0-3),但变量“1”和“2”可以赋值任何东西,如果这有帮助的话。结果是,0 =双方都不赢,1 = p1赢,2 = p2赢,3 =双方都赢。
public int fightMath(int one, int two) {
if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }
else if(one == 1 && two == 0) { result = 0; }
else if(one == 1 && two == 1) { result = 0; }
else if(one == 1 && two == 2) { result = 2; }
else if(one == 1 && two == 3) { result = 1; }
else if(one == 2 && two == 0) { result = 2; }
else if(one == 2 && two == 1) { result = 1; }
else if(one == 2 && two == 2) { result = 3; }
else if(one == 2 && two == 3) { result = 3; }
else if(one == 3 && two == 0) { result = 1; }
else if(one == 3 && two == 1) { result = 2; }
else if(one == 3 && two == 2) { result = 3; }
else if(one == 3 && two == 3) { result = 3; }
return result;
}
感谢@Joe Harper,因为我最终使用了他的答案的变体。为了进一步瘦身,每4个结果中有2个是相同的,我进一步瘦身。
我可能会在某个时候回到这个问题上,但如果没有由多个if语句引起的主要阻力,那么我现在就保留这个问题。我将进一步研究表格矩阵和开关语句解决方案。
public int fightMath(int one, int two) {
if (one === 0) {
if (two === 2) { return 1; }
else if(two === 3) { return 2; }
else { return 0; }
} else if (one === 1) {
if (two === 2) { return 2; }
else if (two === 3) { return 1; }
else { return 0; }
} else if (one === 2) {
if (two === 0) { return 2; }
else if (two === 1) { return 1; }
else { return 3; }
} else if (one === 3) {
if (two === 0) { return 1; }
else if (two === 1) { return 2; }
else { return 3; }
}
}
如果你无法想出一个公式,你可以使用一个表格来描述有限的结果:
final int[][] result = new int[][] {
{ 0, 0, 1, 2 },
{ 0, 0, 2, 1 },
{ 2, 1, 3, 3 },
{ 1, 2, 3, 3 }
};
return result[one][two];
这使用了一点bitmagic(你已经通过在一个整数中保存两个比特信息(low/high & attack/block)来做到这一点):
我没有运行,只是在这里输入,请仔细检查。这个想法肯定有效。
编辑:现在对每个输入进行测试,工作正常。
public int fightMath(int one, int two) {
if(one<2 && two<2){ //both players blocking
return 0; // nobody hits
}else if(one>1 && two>1){ //both players attacking
return 3; // both hit
}else{ // some of them attack, other one blocks
int different_height = (one ^ two) & 1; // is 0 if they are both going for the same height - i.e. blocker wins, and 1 if height is different, thus attacker wins
int attacker = one>1?1:0; // is 1 if one is the attacker, two is the blocker, and 0 if one is the blocker, two is the attacker
return (attacker ^ different_height) + 1;
}
}
或者我应该建议把这两个信息分离成单独的变量?
主要基于上面这样的位操作的代码通常很难维护。
看看我们都知道些什么
1:你的答案对于参与人1 P1和参与人2 P2是对称的。这对于格斗游戏来说很有意义,但你也可以利用它来完善你的逻辑。
2:3拍0拍2拍1拍3。这些情况中唯一不包括的情况是0对1和2对3的组合。换句话说,唯一的胜利表是这样的:0击败2,1击败3,2击败1,3击败0。
3:如果0/1人对位,则平局无命中,但如果2/3人对位,则双方均命中
首先,让我们构建一个单向函数,告诉我们是否赢了:
// returns whether we beat our opponent
public boolean doesBeat(int attacker, int defender) {
int[] beats = {2, 3, 1, 0};
return defender == beats[attacker];
}
然后我们可以使用这个函数来组合最终的结果:
// returns the overall fight result
// bit 0 = one hits
// bit 1 = two hits
public int fightMath(int one, int two)
{
// Check to see whether either has an outright winning combo
if (doesBeat(one, two))
return 1;
if (doesBeat(two, one))
return 2;
// If both have 0/1 then its hitless draw but if both have 2/3 then they both hit.
// We can check this by seeing whether the second bit is set and we need only check
// one's value as combinations where they don't both have 0/1 or 2/3 have already
// been dealt with
return (one & 2) ? 3 : 0;
}
虽然这可以说比许多答案中提供的查找表更复杂,而且可能更慢,但我相信这是一种更好的方法,因为它实际上封装了代码的逻辑,并向阅读您代码的任何人描述它。我认为这是一个更好的实现。
(这是一段时间以来,我做任何Java,所以抱歉,如果语法错误,希望它仍然是可理解的,如果我有一点错误)
顺便说一下,0-3显然意味着什么;它们不是任意的值,所以给它们命名会有帮助。