- package animals; 
-   
- import java.util.ArrayList; 
- import java.util.Collection; 
- import java.util.HashMap; 
- import java.util.Iterator; 
- import java.util.List; 
- import java.util.Map; 
- import java.util.Map.Entry; 
- import java.util.Random; 
-   
- /*public*/ class DeepWolf extends Animal { 
-   
-     private static final int-                     NUM_WOLF_SPECIES             = (int) Math- . round(Math- . pow(
 
-                                                                                     ((double) MAP_SIZE) / 20, 2) - 3) - 3; 
-     private static final int                    POPULATION                  = 100; 
-     private static int                          MAP_AREA; 
-   
-     private static final char                   EMPTY                       = ' '; 
-     private static final char                   STONE                       = 'S'; 
-     private static final char                   BEAR                        = 'B'; 
-     private static final char                   LION                        = 'L'; 
-     private static final char                   WOLF                        = 'W'; 
-     private static final char                   ENEMY_WOLF                  = 'w'; 
-     private static final char                   FRIENDLY_WOLF               = '@'; 
-   
-     private static final Attack[]               ATTACKS                     = { Attack.ROCK, Attack.PAPER, 
-             Attack.SCISSORS                                             }; 
-     private static final float                  EXPECTED_WIN_PERCENTAGE     = 1f / ATTACKS.length; 
-   
-     private static final float                  POTENTIAL_DANGER_DECAY      = 63 / 64f; 
-     private static final float                  PROXIMITY_DANGER_DECAY      = 3 / 4f; 
-     private static final float                  UNSEEN_DEATH_BASE_CHANCE    = 1 / 16f; 
-   
-   
-     private static final FightIntel             FIGHT_INTEL_OVERRIDE        = new FightIntel(); 
-     static { 
-         FIGHT_INTEL_OVERRIDE.registerWin(STONE, Attack.PAPER); 
-         FIGHT_INTEL_OVERRIDE.registerWin(BEAR, Attack.SCISSORS); 
-         FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS); 
-         FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS); 
-         FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS); 
-         FIGHT_INTEL_OVERRIDE.registerLoss(LION, Attack.SCISSORS); 
-     } 
-   
-     private static final FightIntel             fightIntel                  = new FightIntel(); 
-     private static final PopulationIntel        populationIntel             = new PopulationIntel(); 
-     static { 
-         populationIntel.addMany(STONE, POPULATION); 
-         populationIntel.addMany(BEAR, POPULATION); 
-         populationIntel.addMany(LION, POPULATION); 
-         populationIntel.addMany(WOLF, (NUM_WOLF_SPECIES - 1) * POPULATION); 
-     } 
-   
-     private static MoveIntel                    movesThisTurn; 
-   
-     private static final Collection<DeepWolf>   us                          = new ArrayList<DeepWolf>(); 
-   
-     private static int                          turn                        = -1; 
-     private static boolean                      movePhase                   = false; 
-   
-     private boolean                             calledToMoveThisTurn        = false; 
-     private final List<Fight>                   fightsLastTurn              = new ArrayList<Fight>(); 
-   
-     private int                                 y                           = 0; 
-     private int                                 x                           = 0; 
-   
-     private final PositionIntel                 positionIntel               = new PositionIntel(); 
-   
-     // for debug purposes 
-     private BetterMove                          moveThisTurn; 
-     private Map<BetterMove, List<Double>>       dangerThisTurn; 
-     private List<Double>                        dangerTemp; 
-   
-     public DeepWolf() { 
-         super(WOLF); 
-         us.add(this); 
-         populationIntel.addOne(FRIENDLY_WOLF); 
-         MAP_AREA = MAP_SIZE * MAP_SIZE; 
-     } 
-   
-     @Override 
-     public Attack fight(final char opponent) { 
-         if (movePhase) { 
-             enterFightPhase(); 
-         } 
-   
-         Attack attack = doFight(opponent); 
-         fightsLastTurn.add(new Fight(opponent, attack)); 
-   
-         return attack; 
-     } 
-   
-     private Attack doFight(final char opponent) { 
-         return getFightIntel(opponent).getBest(); 
-     } 
-   
-     private static SimpleFightIntel getFightIntel(final char opponent) { 
-         if (FIGHT_INTEL_OVERRIDE.hasData(opponent)) { 
-             return FIGHT_INTEL_OVERRIDE.getOpponentIntel(opponent); 
-         } else { 
-             return fightIntel.getOpponentIntel(opponent); 
-         } 
-     } 
-   
-     @Override 
-     public Move move() { 
-         if (calledToMoveThisTurn) { 
-             enterFightPhase(); 
-         } 
-         if (!movePhase) { 
-             enterMovePhase(); 
-         } 
-   
-         calledToMoveThisTurn = true; 
-   
-         surroundings[1][1] = EMPTY; 
-   
-         for (int row = 0; row < 3; row++) { 
-             for (int col = 0; col < 3; col++) { 
-                 positionIntel.add(y + (row - 1), x + (col - 1), surroundings[row][col]); 
-             } 
-         } 
-   
-         BetterMove move = doMove(); 
-         movesThisTurn.add(move); 
-         moveThisTurn = move; 
-   
-         y = clip(y + move.dy); 
-         x = clip(x + move.dx); 
-   
-         return move.toMove(); 
-     } 
-   
-     private BetterMove doMove() { 
-         double-  leastDanger  = Float- . POSITIVE_INFINITY;
 
-         BetterMove leastDangerousMove = null; 
-   
-         dangerThisTurn = new HashMap<BetterMove, List<Double>>(); 
-   
-         for (BetterMove move : BetterMove.values()) { 
-             dangerTemp = new ArrayList<Double>(5); 
-             for (int i = 0; i < 5; i++) { 
-                 dangerTemp.add(0d); 
-             } 
-   
-             double danger = positionIntel.assessDangerOnTurn(y + move.dy, x + move.dx, turn + 1); 
-   
-             if (move.hasOpposite()) { 
-                 double friendlyWolfCollideProbability = (movesThisTurn.percentageOf(move.getOpposite()) * (us.size() - 1)) 
-                         / MAP_AREA; 
-                 dangerTemp.set(4, friendlyWolfCollideProbability * getOpponentDanger(WOLF)); 
-                 danger += friendlyWolfCollideProbability * getOpponentDanger(WOLF); 
-             } 
-   
-             dangerThisTurn.put(move, dangerTemp); 
-   
-             if (danger < leastDanger) { 
-                 leastDanger = danger; 
-                 leastDangerousMove = move; 
-             } 
-         } 
-   
-         if (leastDangerousMove != null) { 
-             return leastDangerousMove; 
-         } else { 
-             throw new AssertionError(); 
-         } 
-     } 
-   
-     private static void enterMovePhase() { 
-         movePhase = true; 
-         turn++; 
-   
-         movesThisTurn = new MoveIntel(); 
-     } 
-   
-     private static void enterFightPhase() { 
-         movePhase = false; 
-   
-         Iterator<DeepWolf> wolves = us.iterator(); 
-         while (wolves.hasNext()) { 
-             DeepWolf wolf = wolves.next(); 
-   
-             Iterator<Fight> fights = wolf.fightsLastTurn.iterator(); 
-             while (fights.hasNext()) { 
-                 Fight fight = fights.next(); 
-                 char opponent = fight.getOpponent(); 
-                 Attack attack = fight.getAttack(); 
-   
-                 if (fights.hasNext() || wolf.calledToMoveThisTurn) { 
-                     fightIntel.registerWin(opponent, attack); 
-                     // TODO: don't assume that we killed an unfriendly wolf here? 
-                     populationIntel.removeOne(opponent); 
-                 } else { 
-                     fightIntel.registerLoss(opponent, attack); 
-                     populationIntel.removeOne(FRIENDLY_WOLF); 
-                     wolves.remove(); 
-                 } 
-             } 
-   
-             wolf.calledToMoveThisTurn = false; 
-             wolf.fightsLastTurn.clear(); 
-         } 
-     } 
-   
-     private static int clip(final int n) { 
-         return ((n % MAP_SIZE) + MAP_SIZE) % MAP_SIZE; 
-     } 
-   
-     private static int posDist(final int m, final int n) { 
-         return clip(n - m); 
-     } 
-   
-     private static int dist(final int m, final int n) { 
-         int posDist = posDist(m, n); 
-         return posDist < (MAP_SIZE / 2) ? posDist : MAP_SIZE - posDist; 
-     } 
-   
-     private boolean isVisible(final int y, final int x) { 
-         return (dist(y, this.y) <= 1) && (dist(x, this.x) <= 1); 
-     } 
-   
-     private static double getOpponentDanger(final char opponent) { 
-         double winPercentage; 
-   
-         if (opponent == FRIENDLY_WOLF) { 
-             winPercentage = 0; 
-   
-         } else { 
-             SimpleFightIntel opponentFightIntel = getFightIntel(opponent); 
-             winPercentage = opponentFightIntel.getWinPercentage(opponentFightIntel.getBest()); 
-   
-             if (winPercentage == 0) { 
-                 winPercentage = EXPECTED_WIN_PERCENTAGE; 
-             } 
-             if (opponent == WOLF) { 
-                 winPercentage *= (double) (NUM_WOLF_SPECIES - 1) / NUM_WOLF_SPECIES; 
-             } 
-         } 
-   
-         return (1 / winPercentage) - 1; 
-     } 
-   
-     private static double decayPotentialDanger(final double danger, final int turnsStale) { 
-         return decayDanger(danger, turnsStale, POTENTIAL_DANGER_DECAY); 
-     } 
-   
-     private static double decayProximityDanger(final double danger, final int proximity) { 
-         return decayDanger(danger, proximity, PROXIMITY_DANGER_DECAY); 
-     } 
-   
-     private static double decayDanger(final double danger, final int decay, final double factor) { 
-         return-  danger  * Math- . pow(- factor, decay );
 
-     } 
-   
-     private static class Fight { 
-   
-         private final char      opponent; 
-         private final Attack    attack; 
-   
-         Fight(final char opponent, final Attack attack) { 
-             this.opponent = opponent; 
-             this.attack = attack; 
-         } 
-   
-         private char getOpponent() { 
-             return opponent; 
-         } 
-   
-         private Attack getAttack() { 
-             return attack; 
-         } 
-   
-     } 
-   
-     private static class WinLossIntel { 
-   
-         private int total   = 0; 
-         private int wins    = 0; 
-   
-         WinLossIntel() {} 
-   
-         private int getTotal() { 
-             return total; 
-         } 
-   
-         private int getWins() { 
-             return wins; 
-         } 
-   
-         private int getLosses() { 
-             return total - wins; 
-         } 
-   
-         private double getWinPercentage() { 
-             return total == 0 ? 0 : (double) wins / total; 
-         } 
-   
-         private void registerWin() { 
-             total++; 
-             wins++; 
-         } 
-   
-         private void registerLoss() { 
-             total++; 
-         } 
-   
-         private void registerResult(final boolean won) { 
-             if (won) { 
-                 registerWin(); 
-             } else { 
-                 registerLoss(); 
-             } 
-         } 
-   
-         @Override 
-             return wins + "/" + total; 
-         } 
-     } 
-   
-     private static class SimpleFightIntel { 
-   
-         private final Map<Attack, WinLossIntel> attackIntel; 
-   
-         SimpleFightIntel() { 
-             attackIntel = new HashMap<Attack, WinLossIntel>(); 
-             for (Attack attack : ATTACKS) { 
-                 get(attack); 
-             } 
-         } 
-   
-         private WinLossIntel get(final Attack attack) { 
-             WinLossIntel result = attackIntel.get(attack); 
-             if (result == null) { 
-                 result = new WinLossIntel(); 
-                 attackIntel.put(attack, result); 
-             } 
-             return result; 
-         } 
-   
-         private int getTotal(final Attack attack) { 
-             return get(attack).getTotal(); 
-         } 
-   
-         private int getWins(final Attack attack) { 
-             return get(attack).getWins(); 
-         } 
-   
-         private int getLosses(final Attack attack) { 
-             return get(attack).getLosses(); 
-         } 
-   
-         private double getWinPercentage(final Attack attack) { 
-             return get(attack).getWinPercentage(); 
-         } 
-   
-         private Attack getBest() { 
-             Attack bestAttack = null; 
-             double bestPercentage = -1; 
-             List<Attack> leastUsedAttacks = new ArrayList<Attack>(ATTACKS.length); 
-   
-             for (Entry<Attack, WinLossIntel> entry : attackIntel.entrySet()) { 
-                 Attack attack = entry.getKey(); 
-                 WinLossIntel intel = entry.getValue(); 
-   
-                 double percentage = entry.getValue().getWinPercentage(); 
-                 if (percentage > bestPercentage) { 
-                     bestAttack = entry.getKey(); 
-                     bestPercentage = percentage; 
-                 } 
-   
-                 int uses = intel.getTotal(); 
-                 if (uses <= leastUses) { 
-                     leastUsedAttacks.add(attack); 
-                     leastUses = uses; 
-                 } 
-             } 
-   
-             if (((bestPercentage - EXPECTED_WIN_PERCENTAGE) / (1 - EXPECTED_WIN_PERCENTAGE)) < (1.0 / (leastUses + 2 + random 
-                     .nextDouble()))) { 
-                 return leastUsedAttacks.get(random.nextInt(leastUsedAttacks.size())); 
-             } else { 
-                 return bestAttack; 
-             } 
-         } 
-   
-         private void registerWin(final Attack attack) { 
-             registerResult(attack, true); 
-         } 
-   
-         private void registerLoss(final Attack attack) { 
-             registerResult(attack, false); 
-         } 
-   
-         private void registerResult(final Attack attack, final boolean won) { 
-             get(attack).registerResult(won); 
-         } 
-   
-         private boolean hasData() { 
-             for (WinLossIntel intel : attackIntel.values()) { 
-                 if (intel.getTotal() > 0) { 
-                     return true; 
-                 } 
-             } 
-             return false; 
-         } 
-   
-         @Override 
-             return attackIntel.toString(); 
-         } 
-     } 
-   
-     private static class FightIntel { 
-   
-         private final-  Map <Character- , SimpleFightIntel >-   fightIntel   = new-  HashMap <Character- , SimpleFightIntel >();
 
-   
-         FightIntel() {} 
-   
-         private-  SimpleFightIntel get (final Character-  opponent ) {
 
-             SimpleFightIntel result = fightIntel.get(opponent); 
-             if (result == null) { 
-                 result = new SimpleFightIntel(); 
-                 fightIntel.put(opponent, result); 
-             } 
-             return result; 
-         } 
-   
-         private-  SimpleFightIntel getOpponentIntel (final Character-  opponent ) {
 
-             return get(opponent); 
-         } 
-   
-         private-  WinLossIntel get (final Character-  opponent,  final-  Attack attack ) {
 
-             return get(opponent).get(attack); 
-         } 
-   
-         private int-  getTotal (final Character-  opponent,  final-  Attack attack ) {
 
-             return get(opponent, attack).getTotal(); 
-         } 
-   
-         private int-  getWins (final Character-  opponent,  final-  Attack attack ) {
 
-             return get(opponent, attack).getWins(); 
-         } 
-   
-         private int-  getLosses (final Character-  opponent,  final-  Attack attack ) {
 
-             return get(opponent, attack).getLosses(); 
-         } 
-   
-         private double-  getWinPercentage (final Character-  opponent,  final-  Attack attack ) {
 
-             return get(opponent, attack).getWinPercentage(); 
-         } 
-   
-         private-  Attack getBest (final Character-  opponent ) {
 
-             return get(opponent).getBest(); 
-         } 
-   
-         private void-  registerWin (final Character-  opponent,  final-  Attack attack ) {
 
-             registerResult(opponent, attack, true); 
-         } 
-   
-         private void-  registerLoss (final Character-  opponent,  final-  Attack attack ) {
 
-             registerResult(opponent, attack, false); 
-         } 
-   
-         private void-  registerResult (final Character-  opponent,  final-  Attack attack,  final boolean-  won ) {
 
-             get(opponent, attack).registerResult(won); 
-         } 
-   
-         private boolean-  hasData (final Character-  opponent ) {
 
-             return get(opponent).hasData(); 
-         } 
-   
-         @Override 
-             return fightIntel.toString(); 
-         } 
-   
-     } 
-   
-     private static class Coordinate { 
-   
-         private final int   x; 
-         private final int   y; 
-   
-         Coordinate(final int y, final int x) { 
-             this.x = clip(x); 
-             this.y = clip(y); 
-         } 
-   
-         private int getX() { 
-             return x; 
-         } 
-   
-         private int getY() { 
-             return y; 
-         } 
-   
-         @Override 
-         public int hashCode() { 
-             final int prime = 31; 
-             int result = 1; 
-             result = (prime * result) + x; 
-             result = (prime * result) + y; 
-             return result; 
-         } 
-   
-         @Override 
-         public boolean-  equals (final Object-  obj ) {
 
-             if (this == obj) { 
-                 return true; 
-             } 
-             if (obj == null) { 
-                 return false; 
-             } 
-             if (getClass() != obj.getClass()) { 
-                 return false; 
-             } 
-             Coordinate other = (Coordinate) obj; 
-             return (x == other.x) && (y == other.y); 
-         } 
-   
-         @Override 
-             return "[" + y + "," + x + "]"; 
-         } 
-   
-     } 
-   
-     private static class LionIntel { 
-   
-         private final Map<Coordinate, Integer>  lionIntel   = new HashMap<Coordinate, Integer>(); 
-   
-         LionIntel() {} 
-   
-         private static Coordinate getCoordinateOnTurn(final Coordinate coordinate, final int onTurn) { 
-             return getCoordinateOnTurn(coordinate.getY(), coordinate.getX(), onTurn); 
-         } 
-   
-         private static Coordinate getCoordinateOnTurn(final int y, final int x, final int onTurn) { 
-             return getCoordinateOnTurnRelativeToTurn(y, x, onTurn, 0); 
-         } 
-   
-         private static Coordinate getCoordinateOnTurnRelativeToTurn(final int y, final int x, final int onTurn, 
-                 final int relativeToTurn) { 
-             return new Coordinate(y + ((onTurn / 2) - (relativeToTurn / 2)), x 
-                     + (((onTurn + 1) / 2) - ((relativeToTurn + 1) / 2))); 
-         } 
-   
-         private void addOnTurn(final int y, final int x, final int onTurn) { 
-             lionIntel.put(getCoordinateOnTurnRelativeToTurn(y, x, 0, onTurn), onTurn); 
-         } 
-   
-         private void add(final int y, final int x) { 
-             addOnTurn(y, x, turn); 
-         } 
-   
-         private void add(final int y, final int x, final boolean isPresent) { 
-             if (isPresent) { 
-                 add(y, x); 
-             } else { 
-                 remove(y, x); 
-             } 
-         } 
-   
-         private void remove(final int y, final int x) { 
-             lionIntel.remove(getCoordinateOnTurnRelativeToTurn(y, x, 0, turn)); 
-         } 
-   
-         private int size() { 
-             return lionIntel.size(); 
-         } 
-   
-         private double assessDangerOnTurn(final int y, final int x, final int onTurn) { 
-             return assessDangerOnTurn(y, x, onTurn, false); 
-         } 
-   
-         private double assessDangerOnTurnWithFuture(final int y, final int x, final int onTurn) { 
-             return assessDangerOnTurn(y, x, onTurn, true); 
-         } 
-   
-         private double assessDangerOnTurn(final int y, final int x, final int onTurn, final boolean withFuture) { 
-             double danger = 0; 
-   
-             for (Entry<Coordinate, Integer> entry : lionIntel.entrySet()) { 
-                 Coordinate lion = entry.getKey(); 
-                 int turnLastSeen = entry.getValue(); 
-                 Coordinate lionWhenLastSeen = getCoordinateOnTurn(lion, turnLastSeen); 
-   
-                 int dy = posDist(lionWhenLastSeen.getY(), y); 
-                 int dx = posDist(lionWhenLastSeen.getX(), x); 
-                 if ((dy == 0) && (dx == 0)) { 
-                     dy = dx = MAP_SIZE; 
-                 } else if ((dy == 0) && (dx == (MAP_SIZE - 1))) { 
-                     dy = MAP_SIZE; 
-                 } else if ((dx == 0) && (dy == (MAP_SIZE - 1))) { 
-                     dx = MAP_SIZE; 
-                 } 
-   
-                 int turnsUntilClosestEncounterY = (dy * 2) - (turnLastSeen % 2); 
-                 int turnsUntilClosestEncounterX = ((dx * 2) - ((turnLastSeen + 1) % 2)); 
-   
-                 int-  turnsUntilClosestEncounter  = Math- . min(- turnsUntilClosestEncounterY, turnsUntilClosestEncounterX ) + 1;
 
-                 Coordinate lionAtClosestEncounter = getCoordinateOnTurn(lion, turnLastSeen + turnsUntilClosestEncounter); 
-                 int closestEncounterDist = dist(lionAtClosestEncounter.getY(), y) 
-                         + dist(lionAtClosestEncounter.getX(), x); 
-   
-                 if (((turnLastSeen + turnsUntilClosestEncounter) - onTurn) < closestEncounterDist) { 
-                     turnsUntilClosestEncounter  = Math- . max(- turnsUntilClosestEncounterY, turnsUntilClosestEncounterX );
-                     lionAtClosestEncounter = getCoordinateOnTurn(lion, turnLastSeen + turnsUntilClosestEncounter); 
-                     closestEncounterDist = dist(lionAtClosestEncounter.getY(), y) 
-                             + dist(lionAtClosestEncounter.getX(), x); 
-                 } 
-   
-                 if (withFuture || (((turnsUntilClosestEncounter == 1)) && (closestEncounterDist == 0))) { 
-                     double lionDanger = decayProximityDanger( 
-                             decayPotentialDanger(getOpponentDanger(LION), turnsUntilClosestEncounter), 
-                             closestEncounterDist); 
-                     danger += lionDanger; 
-                 } 
-             } 
-   
-             return danger; 
-         } 
-   
-         @Override 
-         public int hashCode() { 
-             return lionIntel.hashCode(); 
-         } 
-   
-         @Override 
-         public boolean-  equals (final Object-  obj ) {
 
-             if (this == obj) { 
-                 return true; 
-             } 
-             if (obj == null) { 
-                 return false; 
-             } 
-             if (getClass() != obj.getClass()) { 
-                 return false; 
-             } 
-             LionIntel other = (LionIntel) obj; 
-             return lionIntel == other.lionIntel; 
-         } 
-   
-         @Override 
-             return LionIntel.class.getSimpleName() + "[" + lionIntel.toString() + "]"; 
-         } 
-   
-     } 
-   
-     private static class WolfIntel { 
-   
-         private final Map<Coordinate, Integer>  wolfIntel   = new HashMap<Coordinate, Integer>(); 
-   
-         WolfIntel() {} 
-   
-         private void addOnTurn(final int y, final int x, final int onTurn) { 
-             wolfIntel.put(new Coordinate(y, x), onTurn); 
-         } 
-   
-         private void add(final int y, final int x) { 
-             addOnTurn(y, x, turn); 
-         } 
-   
-         private void add(final int y, final int x, final boolean isPresent) { 
-             if (isPresent) { 
-                 add(y, x); 
-             } else { 
-                 remove(y, x); 
-             } 
-         } 
-   
-         private void remove(final int y, final int x) { 
-             wolfIntel.remove(new Coordinate(y, x)); 
-         } 
-   
-         private int size() { 
-             return wolfIntel.size(); 
-         } 
-   
-         private double assessDangerOnTurn(final int y, final int x, final int onTurn) { 
-             double danger = 0; 
-   
-             for (Entry<Coordinate, Integer> entry : wolfIntel.entrySet()) { 
-                 Coordinate wolf = entry.getKey(); 
-                 int turnsStale = onTurn - entry.getValue(); 
-                 int dist = dist(x, wolf.getX()) + dist(y, wolf.getY()); 
-   
-                 // if (turnsStale >= dist) { 
-                 // danger += decayPotentialDanger(getOpponentDanger(WOLF) * Math.pow(.75, dist - 1), turnsStale - 1); 
-                 // } 
-                 if ((turnsStale >= dist) && (dist <= 1)) { 
-                     danger  +=-  decayPotentialDanger (- getOpponentDanger (- WOLF ) * Math- . pow(- PROXIMITY_DANGER_DECAY, dist )- , 
-                             turnsStale - 1); 
-                 } 
-             } 
-   
-             return danger; 
-         } 
-   
-         @Override 
-         public int hashCode() { 
-             return wolfIntel.hashCode(); 
-         } 
-   
-         @Override 
-         public boolean-  equals (final Object-  obj ) {
 
-             if (this == obj) { 
-                 return true; 
-             } 
-             if (obj == null) { 
-                 return false; 
-             } 
-             if (getClass() != obj.getClass()) { 
-                 return false; 
-             } 
-             WolfIntel other = (WolfIntel) obj; 
-             return wolfIntel == other.wolfIntel; 
-         } 
-   
-         @Override 
-             return WolfIntel.class.getSimpleName() + "[" + wolfIntel.toString() + "]"; 
-         } 
-   
-     } 
-   
-     private static class MoveIntel { 
-   
-         private final Map<BetterMove, Integer>  moves   = new HashMap<BetterMove, Integer>(); 
-         private int                             total   = 0; 
-   
-         MoveIntel() {} 
-   
-         private int get(final BetterMove move) { 
-             if (result == null) { 
-                 return 0; 
-             } else { 
-                 return result; 
-             } 
-         } 
-   
-         private void add(final BetterMove move) { 
-             moves.put(move, get(move) + 1); 
-             total++; 
-         } 
-   
-         private int size() { 
-             return total; 
-         } 
-   
-         private double percentageOf(final BetterMove move) { 
-             int moveCount = get(move); 
-             return moveCount == 0 ? 0 : ((double) moveCount) / total; 
-         } 
-   
-     } 
-   
-     private class PositionIntel { 
-   
-         private final LionIntel lionIntel   = new LionIntel(); 
-         private final WolfIntel wolfIntel   = new WolfIntel(); 
-   
-         PositionIntel() {} 
-   
-         private void add(final int y, final int x, final char animal) { 
-             lionIntel.add(y, x, animal == LION); 
-             wolfIntel.add(y, x, animal == WOLF); 
-         } 
-   
-         private double assessDangerOnTurn(final int y, final int x, final int onTurn) { 
-             LionIntel potentialLionIntel = new LionIntel(); 
-             WolfIntel potentialWolfIntel = new WolfIntel(); 
-   
-             for (BetterMove move : BetterMove.values()) { 
-                 int potentialY = y + move.dy; 
-                 int potentialX = x + move.dx; 
-                 if (!isVisible(potentialY, potentialX)) { 
-                     potentialLionIntel.addOnTurn(potentialY, potentialX, onTurn - 1); 
-                     potentialWolfIntel.addOnTurn(potentialY, potentialX, onTurn - 1); 
-                 } 
-             } 
-   
-             double potentialLionDanger = potentialLionIntel.assessDangerOnTurn(y, x, onTurn) 
-                     * (Math- . max(0- , populationIntel. guessOnTurn(- LION, onTurn  - 1) --  lionIntel. size()) /-  MAP_AREA );
 
-             double potentialWolfDanger = potentialWolfIntel.assessDangerOnTurn(y, x, onTurn) 
-                             0, 
-                             populationIntel.guessOnTurn(WOLF, onTurn - 1) 
-                                     + (populationIntel.guessOnTurn(FRIENDLY_WOLF, onTurn - 1) - 1)) / MAP_AREA); 
-             double lionDanger = lionIntel.assessDangerOnTurnWithFuture(y, x, onTurn); 
-             double wolfDanger = wolfIntel.assessDangerOnTurn(y, x, onTurn); 
-   
-             dangerTemp.set(0, potentialLionDanger); 
-             dangerTemp.set(1, potentialWolfDanger); 
-             dangerTemp.set(2, lionDanger); 
-             dangerTemp.set(3, wolfDanger); 
-   
-             return potentialLionDanger + potentialWolfDanger + lionDanger + wolfDanger; 
-         } 
-   
-         @Override 
-         public int hashCode() { 
-             final int prime = 31; 
-             int result = 1; 
-             result = (prime * result) + lionIntel.hashCode(); 
-             result = (prime * result) + wolfIntel.hashCode(); 
-             return result; 
-         } 
-   
-         @Override 
-         public boolean-  equals (final Object-  obj ) {
 
-             if (this == obj) { 
-                 return true; 
-             } 
-             if (obj == null) { 
-                 return false; 
-             } 
-             if (getClass() != obj.getClass()) { 
-                 return false; 
-             } 
-             PositionIntel other = (PositionIntel) obj; 
-             return lionIntel.equals(other.lionIntel) && wolfIntel.equals(other.wolfIntel); 
-         } 
-   
-         @Override 
-             return PositionIntel.class.getSimpleName() + "[" + lionIntel.toString() + ", " + wolfIntel.toString() + "]"; 
-         } 
-     } 
-   
-     private static class PopulationIntel { 
-   
-   
-         PopulationIntel() {} 
-   
-         private int get(final char animal) { 
-             Integer-  result  =-  populations. get(- animal );
 
-             if (result == null) { 
-                 return 0; 
-             } else { 
-                 return result; 
-             } 
-         } 
-   
-         private int getMax(final char animal) { 
-             return get(animal); 
-         } 
-   
-         private void addOne(final char animal) { 
-             addMany(animal, 1); 
-         } 
-   
-         private void addMany(final char animal, final int n) { 
-             populations.put(animal, get(animal) + n); 
-         } 
-   
-         private void removeOne(final char animal) { 
-             removeMany(animal, 1); 
-         } 
-   
-         private void removeMany(final char animal, final int n) { 
-             populations.put(animal, get(animal) - n); 
-         } 
-   
-         private double guess(final char animal) { 
-             return guessOnTurn(animal, turn); 
-         } 
-   
-         private double guessOnTurn(final char animal, final int onTurn) { 
-             int max = get(animal); 
-   
-             switch (animal) { 
-             case FRIENDLY_WOLF: 
-                 return max; 
-             default: 
-                 return-  max  * Math- . pow(1 - Math- . pow(- UNSEEN_DEATH_BASE_CHANCE,  (- getOpponentDanger (- animal ) + 1))- , onTurn );
 
-             } 
-         } 
-   
-         @Override 
-         public int hashCode() { 
-             return populations.hashCode(); 
-         } 
-   
-         @Override 
-         public boolean-  equals (final Object-  obj ) {
 
-             if (this == obj) { 
-                 return true; 
-             } 
-             if (obj == null) { 
-                 return false; 
-             } 
-             if (getClass() != obj.getClass()) { 
-                 return false; 
-             } 
-             PopulationIntel other = (PopulationIntel) obj; 
-             return populations.equals(other.populations); 
-         } 
-   
-         @Override 
-             return PopulationIntel.class.getSimpleName() + "[" + populations + "]"; 
-         } 
-   
-     } 
-   
-     private static enum BetterMove { 
-         UP(0, -1), RIGHT(1, 0), DOWN(0, 1), LEFT(-1, 0), HOLD(0, 0); 
-   
-         public final int    dx; 
-         public final int    dy; 
-   
-         BetterMove(final int dx, final int dy) { 
-             this.dx = dx; 
-             this.dy = dy; 
-         } 
-   
-         public Move toMove() { 
-             return toMove(this); 
-         } 
-   
-         public static Move toMove(final BetterMove move) { 
-             return Move.valueOf(move.name()); 
-         } 
-   
-         public static BetterMove fromMove(final Move move) { 
-             return BetterMove.valueOf(move.name()); 
-         } 
-   
-         public boolean hasOpposite() { 
-             return hasOpposite(this); 
-         } 
-   
-         public static boolean hasOpposite(final BetterMove move) { 
-             return getOpposite(move) != null; 
-         } 
-   
-         public BetterMove getOpposite() { 
-             return getOpposite(this); 
-         } 
-   
-         public static BetterMove getOpposite(final BetterMove move) { 
-             switch (move) { 
-             case UP: 
-                 return DOWN; 
-             case RIGHT: 
-                 return LEFT; 
-             case DOWN: 
-                 return UP; 
-             case LEFT: 
-                 return RIGHT; 
-             case HOLD: 
-                 return null; 
-             default: 
-                 throw new AssertionError(); 
-             } 
-         } 
-     } 
-   
- }