下面的代码确实按照我需要的方式工作,但它很丑,过多或其他一些事情。我已经看了公式,并试图写一些解决方案,但我最终得到了类似数量的语句。
在这种情况下,是否有一种数学公式对我有益,或者是否可以接受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;
}
您可以创建包含结果的矩阵
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];
}
我想到的第一件事基本上与Francisco Presencia给出的答案相同,但有所优化:
public int fightMath(int one, int two)
{
switch (one*10 + two)
{
case 0:
case 1:
case 10:
case 11:
return 0;
case 2:
case 13:
case 21:
case 30:
return 1;
case 3:
case 12:
case 20:
case 31:
return 2;
case 22:
case 23:
case 32:
case 33:
return 3;
}
}
你可以进一步优化它,使最后的情况(3)为默认情况:
//case 22:
//case 23:
//case 32:
//case 33:
default:
return 3;
此方法的优点是,与其他一些建议的方法相比,更容易看到1和2的哪个值对应于哪个返回值。
如果你无法想出一个公式,你可以使用一个表格来描述有限的结果:
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];
使用常量或枚举使代码更具可读性
尝试将代码拆分为更多的函数
试着利用问题的对称性
这里是一个建议,但在这里使用int型仍然有点难看:
static final int BLOCK_HIGH = 0;
static final int BLOCK_LOW = 1;
static final int ATTACK_HIGH = 2;
static final int ATTACK_LOW = 3;
public static int fightMath(int one, int two) {
boolean player1Wins = handleAttack(one, two);
boolean player2Wins = handleAttack(two, one);
return encodeResult(player1Wins, player2Wins);
}
private static boolean handleAttack(int one, int two) {
return one == ATTACK_HIGH && two != BLOCK_HIGH
|| one == ATTACK_LOW && two != BLOCK_LOW
|| one == BLOCK_HIGH && two == ATTACK_HIGH
|| one == BLOCK_LOW && two == ATTACK_LOW;
}
private static int encodeResult(boolean player1Wins, boolean player2Wins) {
return (player1Wins ? 1 : 0) + (player2Wins ? 2 : 0);
}
使用结构化类型作为输入和输出会更好。输入实际上有两个字段:位置和类型(阻挡或攻击)。输出也有两个字段:player1Wins和player2Wins。将其编码为单个整数会使代码更难阅读。
class PlayerMove {
PlayerMovePosition pos;
PlayerMoveType type;
}
enum PlayerMovePosition {
HIGH,LOW
}
enum PlayerMoveType {
BLOCK,ATTACK
}
class AttackResult {
boolean player1Wins;
boolean player2Wins;
public AttackResult(boolean player1Wins, boolean player2Wins) {
this.player1Wins = player1Wins;
this.player2Wins = player2Wins;
}
}
AttackResult fightMath(PlayerMove a, PlayerMove b) {
return new AttackResult(isWinningMove(a, b), isWinningMove(b, a));
}
boolean isWinningMove(PlayerMove a, PlayerMove b) {
return a.type == PlayerMoveType.ATTACK && !successfulBlock(b, a)
|| successfulBlock(a, b);
}
boolean successfulBlock(PlayerMove a, PlayerMove b) {
return a.type == PlayerMoveType.BLOCK
&& b.type == PlayerMoveType.ATTACK
&& a.pos == b.pos;
}
不幸的是,Java并不擅长表达这类数据类型。