I am working on a game where I utilize a class that will allow a user to input a choice as a string to do one of 3 options: "attack", "defend", or "flee". This can be logically handled by the 'exclusive OR' (XOR). I decided to try using a while loop using this logic instead of the usual Switch construct to see what happens, being armed with just a little bit of discrete math. I knew the while condition would be ugly and long, but it works dammit!, and I like it! I was wanting to know, since I would like to reuse this while loop in other sections of the code if there was some way to save the while loop condition (like as a variable, method or something) so that I can put it in the while loop condition and not take up 8 lines of code each time. Here is my while loop. Don't laugh, it works. AND, it avoids try-catch. It actually runs very cleanly. I posted the method that I use below. This method is called by another class:
public static void fighterAction(){
String selection = null;
Scanner userChoice = new Scanner(System.in);
//Fighter 1 chooses combat action to perform: this is performed by
//(XOR) logic:
//(( a || b ) && !( a && b ) || c ) && !((( a || b ) && !( a && b ) && c ))
while((( !"attack".equals(selection) || !"defend".equals(selection) )
&& !( !"attack".equals(selection) && !"defend".equals(selection)
) || !"flee".equals(selection) ) &&
!((( !"attack".equals(selection) || !"defend".equals(selection)
) && !( !"attack".equals(selection) &&
!"defend".equals(selection) ) && !"flee".equals(selection) )))
{
System.out.println("Choose action: attack defend flee\n\nEnter: ");
selection = userChoice.next();
if((( !"attack".equals(selection) || !"defend".equals(selection) )
&& !( !"attack".equals(selection) &&
!"defend".equals(selection) ) || !"flee".equals(selection) )
&& !((( !"attack".equals(selection) ||
!"defend".equals(selection) ) &&
!( !"attack".equals(selection) &&
!"defend".equals(selection) ) &&
!"flee".equals(selection) )))
{
System.out.println("Invalid Entry!");
}else{
System.out.println(selection + " was chosen");
System.out.println("");
}
}
}
Again, I am asking if there is a way to take this while clause (which I emphasize, works perfectly):
(( !"attack".equals(selection) || !"defend".equals(selection) ) && !( !"attack".equals(selection) && !"defend".equals(selection) ) || !"flee".equals(selection) ) && !((( !"attack".equals(selection) || !"defend".equals(selection) ) && !( !"attack".equals(selection) && !"defend".equals(selection) ) && !"flee".equals(selection) ))
so that it fits inside of the while loop condition:
while(FITS HERE){}
Thanks!
It will "fit" as is, in other words you can use it as is, but it will be hard to read and more importantly, hard to debug. To make it prettier, make it into a method.
Having said this, using Strings for this sort of thing is ugly and dangerous, plus it will limit your program should you decide to change the UI to be a GUI interface, say Swing or Android. I would instead consider creating an enum to encapsulate the user options:
public enum UserOption {
ATTACK, DEFEND, FLEE
}
A method expecting this enum can only accept one of the three enum constants (or null) thus giving you compile-time type checking and a limitation of the user's options and would also result in prettier more re-usable and extensible code.
Then your console app could have a validate method:
public boolean validateUserOptionsString(String text) {
for (UserOption option : UserOption.Values() {
if (text.equalsIgnoreCase(option.toString())) {
return true;
}
}
return false;
}