The following code does work how I need it to, but it's ugly, excessive or a number of other things. I've looked at formulas and attempted to write a few solutions, but I end up with a similar amount of statements.
Is there a type of math formula that would benefit me in this instance or are 16 if statements acceptable?
To explain the code, it's for a kind of simultaneous-turn-based game.. two players have four action buttons each and the results come from an array (0-3), but the variables 'one' & 'two' can be assigned anything if this helps. The result is, 0 = neither win, 1 = p1 wins, 2 = p2 wins, 3 = both win.
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;
}
Thanks to @Joe Harper as I ended up using a variation of his answer. To slim it down further as 2 results per 4 were the same I slimmed it down further.
I may come back to this at some point, but if there's no major resistance caused by multiple
if
-statements then I'll keep this for now. I will look into the table matrix and switch statement solutions further.Here is a suggestion how this could look like, but using an ints here is still kind of ugly:
It would be nicer to use a structured type for the input and the output. The input actually has two fields: the position and the type (block or attack). The output also has two fields: player1Wins and player2Wins. Encoding this into a single integer makes it harder to read the code.
Unfortunately, Java is not very good at expressing those kinds of data-types.
I hope I understand the logic correctly. How about something like:
Checking one hit high or one hit low is not blocked and the same for player two.
Edit: Algorithm was not fully understood, "hit" awarded when blocking which I did not realize (Thx elias):
static int val(int i, int u){ int q = (i & 1) ^ (u & 1); return ((i >> 1) << (1 ^ q))|((u >> 1) << q); }
I don't like any of the solutions presented except for JAB's. None of the others make it easy to read the code and understand what is being computed.
Here's how I would write this code -- I only know C#, not Java, but you get the picture:
Now it is much more clear what is being computed here: this emphasizes that we are computing who gets hit by what attack, and returning both results.
However this could be even better; that Boolean array is somewhat opaque. I like the table lookup approach but I would be inclined to write it in such a way that made it clear what the intended game semantics were. That is, rather than "an attack of zero and a defense of one results in no hit", instead find a way to make the code more clearly imply "a low kick attack and a low block defense results in no hit". Make the code reflect the business logic of the game.
The first thing that occurred to me was essentially the same answer given by Francisco Presencia, but optimized somewhat:
You could further optimize it by making the last case (for 3) the default case:
The advantage of this method is that it is easier to see which values for
one
andtwo
correspond to which return values than some of the other suggested methods.