下面的代码确实按照我需要的方式工作,但它很丑,过多或其他一些事情。我已经看了公式,并试图写一些解决方案,但我最终得到了类似数量的语句。
在这种情况下,是否有一种数学公式对我有益,或者是否可以接受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;
}
说实话,每个人都有自己的代码风格。我没想到性能会受到太大影响。如果您比使用开关箱版本更能理解这一点,那么请继续使用此版本。
您可以嵌套if语句,因此最后的if检查可能会略微提高性能,因为它不会经过那么多if语句。但是在你的java基础课程中,它可能不会有什么好处。
else if(one == 3 && two == 3) { result = 3; }
所以,与其…
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; }
你会做……
if(one == 0)
{
if(two == 0) { result = 0; }
else if(two == 1) { result = 0; }
else if(two == 2) { result = 1; }
else if(two == 3) { result = 2; }
}
按照你的喜好重新格式化。
这并没有使代码看起来更好,但我相信它可能会加快一点速度。
下面是一个相当简洁的版本,类似于JAB的回应。这使用地图来存储哪个移动战胜其他移动。
public enum Result {
P1Win, P2Win, BothWin, NeitherWin;
}
public enum Move {
BLOCK_HIGH, BLOCK_LOW, ATTACK_HIGH, ATTACK_LOW;
static final Map<Move, List<Move>> beats = new EnumMap<Move, List<Move>>(
Move.class);
static {
beats.put(BLOCK_HIGH, new ArrayList<Move>());
beats.put(BLOCK_LOW, new ArrayList<Move>());
beats.put(ATTACK_HIGH, Arrays.asList(ATTACK_LOW, BLOCK_LOW));
beats.put(ATTACK_LOW, Arrays.asList(ATTACK_HIGH, BLOCK_HIGH));
}
public static Result compare(Move p1Move, Move p2Move) {
boolean p1Wins = beats.get(p1Move).contains(p2Move);
boolean p2Wins = beats.get(p2Move).contains(p1Move);
if (p1Wins) {
return (p2Wins) ? Result.BothWin : Result.P1Win;
}
if (p2Wins) {
return (p1Wins) ? Result.BothWin : Result.P2Win;
}
return Result.NeitherWin;
}
}
例子:
System.out.println(Move.compare(Move.ATTACK_HIGH, Move.BLOCK_LOW));
打印:
P1Win
感谢@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; }
}
}
您可以创建包含结果的矩阵
int[][] results = {{0, 0, 1, 2}, {0, 0, 2, 1},{2, 1, 3, 3},{2, 1, 3, 3}};
当你想要获得价值时,你就会使用
public int fightMath(int one, int two) {
return this.results[one][two];
}
我希望我正确理解了逻辑。比如:
public int fightMath (int one, int two)
{
int oneHit = ((one == 3 && two != 1) || (one == 2 && two != 0)) ? 1 : 0;
int twoHit = ((two == 3 && one != 1) || (two == 2 && one != 0)) ? 2 : 0;
return oneHit+twoHit;
}
检查一个击中高或一个击中低不被阻止,同样的球员二。
编辑:算法不完全理解,“命中”奖励时,我没有意识到(谢谢elias):
public int fightMath (int one, int two)
{
int oneAttack = ((one == 3 && two != 1) || (one == 2 && two != 0)) ? 1 : (one >= 2) ? 2 : 0;
int twoAttack = ((two == 3 && one != 1) || (two == 2 && one != 0)) ? 2 : (two >= 2) ? 1 : 0;
return oneAttack | twoAttack;
}
这使用了一点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;
}
}
或者我应该建议把这两个信息分离成单独的变量?
主要基于上面这样的位操作的代码通常很难维护。