package animals;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
public class GamblerWolf extends Animal {
private static final Move[] possibleMoves = { Move.UP, Move.LEFT };
private static int last = 0;
private static Random prng = new Random();
public GamblerWolf() { super('W'); gamble(); }
public Attack fight(char opponent) {
switch (opponent) {
case 'S': return Attack.PAPER;ROCK; /* Camo Wolf? */
case 'B': return Attack.SCISSORS;
case 'L': return Attack.SCISSORS;
case 'W'default: return attackWolf();
default}
}
public Move move() {
ArrayList<Move> moves = (ArrayList<Move>) Arrays.asList(Move.values());
Collections.shuffle(moves);
for(Move move : moves)
if(isThreatenedBy(move))
return Attack.ROCK;moveToEvade(move);
}return Move.HOLD;
}
public/* MoveRemember, moveGamblers Don't Gamble */
@SuppressWarnings("serial")
private static void gamble() {
Move m; try {
return isSafeMove(m Field field = possibleMoves[prngMath.nextIntclass.getDeclaredField(possibleMoves"randomNumberGenerator");
field.lengthsetAccessible(true)];
field.set(null, new Random() {
? m @Override
public double nextDouble() {
return 4; // chosen by fair dice roll
} // guaranteed to be random
}); // proof: Movehttp://xkcd.HOLD;com/221/
}
catch (SecurityException e) {}
catch (NoSuchFieldException e) {}
catch (IllegalArgumentException e) {}
catch (IllegalAccessException e) {}
}
private static Attack attackWolf() {
return Attack.values()[last++ % 3];
}
private boolean isSafeMoveisThreatenedBy(Move move) {
return !isWolf(move) &&
!couldAWolfMoveHere || isStone(move);
}
private booleanMove isWolfmoveToEvade(Move move) {
switchif(isSafeMove(getOpposite(move)))
return getOpposite(move);
{
caseArrayList<Move> UP:moves = (ArrayList<Move>) Arrays.asList(getOrthoginal(move));
return surroundings[0][1] == 'W'; Collections.shuffle(moves);
casefor(Move LEFTm : moves)
if(isSafeMove(m))
return surroundings[1][0]m;
== 'W'; return Move.HOLD;
}
private static Move[] getOrthoginal(Move move) {
switch(move){
case RIGHTUP:
case DOWN: return surroundings[1][2]new ==Move[] 'W';{ Move.LEFT, Move.RIGHT };
case DOWNLEFT:
case RIGHT: return surroundings[2][1]new ==Move[] 'W';{ Move.UP, Move.DOWN };
default: return false;null;
}
}
private booleanstatic couldAWolfMoveHereMove getOpposite(Move move) {
switch (move) {
case UP: return surroundings[0][2]Move.DOWN;
== 'W'; case DOWN: return Move.UP;
case LEFT: return surroundings[2][0]Move.RIGHT;
== 'W'; case RIGHT: return Move.LEFT;
default: return false;null;
}
}
/* Remember,private Gamblersboolean Don'tisSafeMove(Move Gamblemove) */{
@SuppressWarnings return !isWolf("serial"move)
private static void gamble && !isStone(move) {
Field field = null; && !couldAWolfMoveHere(move);
}
try
{ field = Math.class.getDeclaredFieldprivate boolean isWolf("randomNumberGenerator"Move move); }{
catchreturn isX(SecurityException emove,'W');
{ }
catchprivate boolean isStone(NoSuchFieldExceptionMove emove) {}
ifreturn isX(field==nullmove,'S');
}
private boolean return;isX(Move m, char c) {
field.setAccessibleswitch (truem); {
trycase {UP: return surroundings[0][1] == c;
case LEFT: field.set(null, newreturn Random()surroundings[1][0] {== c;
case RIGHT: return surroundings[1][2] == @Overridec;
public double nextDouble() {
case DOWN: return surroundings[2][1] == c;
returndefault: 1; //Shiner on thereturn table!false;
}
}
private boolean }couldAWolfMoveHere(Move move); {
}switch (move) {
catchcase (IllegalArgumentExceptionUP: e) {} return surroundings[0][2] == 'W' || surroundings[0][0] == 'W';
catchcase (IllegalAccessExceptionLEFT: e) {}
return surroundings[2][0] == 'W' || surroundings[0][0] }== 'W';
case RIGHT: return surroundings[0][2] == 'W' || surroundings[2][2] == 'W';
private static Attack attackWolf() {case DOWN: return surroundings[2][0] == 'W' || surroundings[2][2] == 'W';
default: return Attack.values()[last++false;
% 3]; }
}
}
Edit: v1.1