Another thing, this time more for readability than reducing logic:
Any time you have a bunch of statements that are used identically in many places, you can “un-inline” them, by putting them in a private method (with a good, descriptive name!), and replace all usages of those statement bundles with that method. Example, these two statements are used together a lot:
System.out.println(c.getName() + " is dead.");
System.out.println(p.getName() + " wins.");
Could be put into, say [icode]printStatus();[/icode] or something.
Another thing to do, in this code here:
//Player wins:
if (playerWins) {
p.setExperience(p.getExperience() + (c.getLevel() * 6));
p.statistics.levelUp();
System.out.println(p.getName() + " wins.");
}
//Creature wins:
else {
System.out.println(c.getName() + " wins.");
}
You could get rid of the serveral [icode]playerWins[/icode] if/else blocks entirely by simply:
System.out.println((playerWins ? p : c).getName() + " wins.");
Of course, this only would replace the System.out calls in the blocks, although in this specific case it eliminates the if/else entirely.
Again, not actually reducing logic really, but much more concise and readable, in my opinion.
Do elsewhere accordingly as you see fit.
But an object with only final public variables is useful since you know those values will never change even if you share it with another section of code. Look at the length variable of the String class. It is a final public int and its value depends on what gets passed to String’s constructor.
