fork download
  1. package animals;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.HashMap;
  6. import java.util.Iterator;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Map.Entry;
  10. import java.util.Random;
  11.  
  12. /*public*/ class DeepWolf extends Animal {
  13.  
  14. private static final int NUM_WOLF_SPECIES = (int) Math.round(Math.pow(
  15. ((double) MAP_SIZE) / 20, 2) - 3) - 3;
  16. private static final int POPULATION = 100;
  17. private static int MAP_AREA;
  18.  
  19. private static final char EMPTY = ' ';
  20. private static final char STONE = 'S';
  21. private static final char BEAR = 'B';
  22. private static final char LION = 'L';
  23. private static final char WOLF = 'W';
  24. private static final char ENEMY_WOLF = 'w';
  25. private static final char FRIENDLY_WOLF = '@';
  26.  
  27. private static final Attack[] ATTACKS = { Attack.ROCK, Attack.PAPER,
  28. Attack.SCISSORS };
  29. private static final float EXPECTED_WIN_PERCENTAGE = 1f / ATTACKS.length;
  30.  
  31. private static final float POTENTIAL_DANGER_DECAY = 63 / 64f;
  32. private static final float PROXIMITY_DANGER_DECAY = 3 / 4f;
  33. private static final float UNSEEN_DEATH_BASE_CHANCE = 1 / 16f;
  34.  
  35. public static final Random random = new Random();
  36.  
  37. private static final FightIntel FIGHT_INTEL_OVERRIDE = new FightIntel();
  38. static {
  39. FIGHT_INTEL_OVERRIDE.registerWin(STONE, Attack.PAPER);
  40. FIGHT_INTEL_OVERRIDE.registerWin(BEAR, Attack.SCISSORS);
  41. FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS);
  42. FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS);
  43. FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS);
  44. FIGHT_INTEL_OVERRIDE.registerLoss(LION, Attack.SCISSORS);
  45. }
  46.  
  47. private static final FightIntel fightIntel = new FightIntel();
  48. private static final PopulationIntel populationIntel = new PopulationIntel();
  49. static {
  50. populationIntel.addMany(STONE, POPULATION);
  51. populationIntel.addMany(BEAR, POPULATION);
  52. populationIntel.addMany(LION, POPULATION);
  53. populationIntel.addMany(WOLF, (NUM_WOLF_SPECIES - 1) * POPULATION);
  54. }
  55.  
  56. private static MoveIntel movesThisTurn;
  57.  
  58. private static final Collection<DeepWolf> us = new ArrayList<DeepWolf>();
  59.  
  60. private static int turn = -1;
  61. private static boolean movePhase = false;
  62.  
  63. private boolean calledToMoveThisTurn = false;
  64. private final List<Fight> fightsLastTurn = new ArrayList<Fight>();
  65.  
  66. private int y = 0;
  67. private int x = 0;
  68.  
  69. private final PositionIntel positionIntel = new PositionIntel();
  70.  
  71. // for debug purposes
  72. private BetterMove moveThisTurn;
  73. private Map<BetterMove, List<Double>> dangerThisTurn;
  74. private List<Double> dangerTemp;
  75.  
  76. public DeepWolf() {
  77. super(WOLF);
  78. us.add(this);
  79. populationIntel.addOne(FRIENDLY_WOLF);
  80. MAP_AREA = MAP_SIZE * MAP_SIZE;
  81. }
  82.  
  83. @Override
  84. public Attack fight(final char opponent) {
  85. if (movePhase) {
  86. enterFightPhase();
  87. }
  88.  
  89. Attack attack = doFight(opponent);
  90. fightsLastTurn.add(new Fight(opponent, attack));
  91.  
  92. return attack;
  93. }
  94.  
  95. private Attack doFight(final char opponent) {
  96. return getFightIntel(opponent).getBest();
  97. }
  98.  
  99. private static SimpleFightIntel getFightIntel(final char opponent) {
  100. if (FIGHT_INTEL_OVERRIDE.hasData(opponent)) {
  101. return FIGHT_INTEL_OVERRIDE.getOpponentIntel(opponent);
  102. } else {
  103. return fightIntel.getOpponentIntel(opponent);
  104. }
  105. }
  106.  
  107. @Override
  108. public Move move() {
  109. if (calledToMoveThisTurn) {
  110. enterFightPhase();
  111. }
  112. if (!movePhase) {
  113. enterMovePhase();
  114. }
  115.  
  116. calledToMoveThisTurn = true;
  117.  
  118. surroundings[1][1] = EMPTY;
  119.  
  120. for (int row = 0; row < 3; row++) {
  121. for (int col = 0; col < 3; col++) {
  122. positionIntel.add(y + (row - 1), x + (col - 1), surroundings[row][col]);
  123. }
  124. }
  125.  
  126. BetterMove move = doMove();
  127. movesThisTurn.add(move);
  128. moveThisTurn = move;
  129.  
  130. y = clip(y + move.dy);
  131. x = clip(x + move.dx);
  132.  
  133. return move.toMove();
  134. }
  135.  
  136. private BetterMove doMove() {
  137. double leastDanger = Float.POSITIVE_INFINITY;
  138. BetterMove leastDangerousMove = null;
  139.  
  140. dangerThisTurn = new HashMap<BetterMove, List<Double>>();
  141.  
  142. for (BetterMove move : BetterMove.values()) {
  143. dangerTemp = new ArrayList<Double>(5);
  144. for (int i = 0; i < 5; i++) {
  145. dangerTemp.add(0d);
  146. }
  147.  
  148. double danger = positionIntel.assessDangerOnTurn(y + move.dy, x + move.dx, turn + 1);
  149.  
  150. if (move.hasOpposite()) {
  151. double friendlyWolfCollideProbability = (movesThisTurn.percentageOf(move.getOpposite()) * (us.size() - 1))
  152. / MAP_AREA;
  153. dangerTemp.set(4, friendlyWolfCollideProbability * getOpponentDanger(WOLF));
  154. danger += friendlyWolfCollideProbability * getOpponentDanger(WOLF);
  155. }
  156.  
  157. dangerThisTurn.put(move, dangerTemp);
  158.  
  159. if (danger < leastDanger) {
  160. leastDanger = danger;
  161. leastDangerousMove = move;
  162. }
  163. }
  164.  
  165. if (leastDangerousMove != null) {
  166. return leastDangerousMove;
  167. } else {
  168. throw new AssertionError();
  169. }
  170. }
  171.  
  172. private static void enterMovePhase() {
  173. movePhase = true;
  174. turn++;
  175.  
  176. movesThisTurn = new MoveIntel();
  177. }
  178.  
  179. private static void enterFightPhase() {
  180. movePhase = false;
  181.  
  182. Iterator<DeepWolf> wolves = us.iterator();
  183. while (wolves.hasNext()) {
  184. DeepWolf wolf = wolves.next();
  185.  
  186. Iterator<Fight> fights = wolf.fightsLastTurn.iterator();
  187. while (fights.hasNext()) {
  188. Fight fight = fights.next();
  189. char opponent = fight.getOpponent();
  190. Attack attack = fight.getAttack();
  191.  
  192. if (fights.hasNext() || wolf.calledToMoveThisTurn) {
  193. fightIntel.registerWin(opponent, attack);
  194. // TODO: don't assume that we killed an unfriendly wolf here?
  195. populationIntel.removeOne(opponent);
  196. } else {
  197. fightIntel.registerLoss(opponent, attack);
  198. populationIntel.removeOne(FRIENDLY_WOLF);
  199. wolves.remove();
  200. }
  201. }
  202.  
  203. wolf.calledToMoveThisTurn = false;
  204. wolf.fightsLastTurn.clear();
  205. }
  206. }
  207.  
  208. private static int clip(final int n) {
  209. return ((n % MAP_SIZE) + MAP_SIZE) % MAP_SIZE;
  210. }
  211.  
  212. private static int posDist(final int m, final int n) {
  213. return clip(n - m);
  214. }
  215.  
  216. private static int dist(final int m, final int n) {
  217. int posDist = posDist(m, n);
  218. return posDist < (MAP_SIZE / 2) ? posDist : MAP_SIZE - posDist;
  219. }
  220.  
  221. private boolean isVisible(final int y, final int x) {
  222. return (dist(y, this.y) <= 1) && (dist(x, this.x) <= 1);
  223. }
  224.  
  225. private static double getOpponentDanger(final char opponent) {
  226. double winPercentage;
  227.  
  228. if (opponent == FRIENDLY_WOLF) {
  229. winPercentage = 0;
  230.  
  231. } else {
  232. SimpleFightIntel opponentFightIntel = getFightIntel(opponent);
  233. winPercentage = opponentFightIntel.getWinPercentage(opponentFightIntel.getBest());
  234.  
  235. if (winPercentage == 0) {
  236. winPercentage = EXPECTED_WIN_PERCENTAGE;
  237. }
  238. if (opponent == WOLF) {
  239. winPercentage *= (double) (NUM_WOLF_SPECIES - 1) / NUM_WOLF_SPECIES;
  240. }
  241. }
  242.  
  243. return (1 / winPercentage) - 1;
  244. }
  245.  
  246. private static double decayPotentialDanger(final double danger, final int turnsStale) {
  247. return decayDanger(danger, turnsStale, POTENTIAL_DANGER_DECAY);
  248. }
  249.  
  250. private static double decayProximityDanger(final double danger, final int proximity) {
  251. return decayDanger(danger, proximity, PROXIMITY_DANGER_DECAY);
  252. }
  253.  
  254. private static double decayDanger(final double danger, final int decay, final double factor) {
  255. return danger * Math.pow(factor, decay);
  256. }
  257.  
  258. private static class Fight {
  259.  
  260. private final char opponent;
  261. private final Attack attack;
  262.  
  263. Fight(final char opponent, final Attack attack) {
  264. this.opponent = opponent;
  265. this.attack = attack;
  266. }
  267.  
  268. private char getOpponent() {
  269. return opponent;
  270. }
  271.  
  272. private Attack getAttack() {
  273. return attack;
  274. }
  275.  
  276. }
  277.  
  278. private static class WinLossIntel {
  279.  
  280. private int total = 0;
  281. private int wins = 0;
  282.  
  283. WinLossIntel() {}
  284.  
  285. private int getTotal() {
  286. return total;
  287. }
  288.  
  289. private int getWins() {
  290. return wins;
  291. }
  292.  
  293. private int getLosses() {
  294. return total - wins;
  295. }
  296.  
  297. private double getWinPercentage() {
  298. return total == 0 ? 0 : (double) wins / total;
  299. }
  300.  
  301. private void registerWin() {
  302. total++;
  303. wins++;
  304. }
  305.  
  306. private void registerLoss() {
  307. total++;
  308. }
  309.  
  310. private void registerResult(final boolean won) {
  311. if (won) {
  312. registerWin();
  313. } else {
  314. registerLoss();
  315. }
  316. }
  317.  
  318. @Override
  319. public String toString() {
  320. return wins + "/" + total;
  321. }
  322. }
  323.  
  324. private static class SimpleFightIntel {
  325.  
  326. private final Map<Attack, WinLossIntel> attackIntel;
  327.  
  328. SimpleFightIntel() {
  329. attackIntel = new HashMap<Attack, WinLossIntel>();
  330. for (Attack attack : ATTACKS) {
  331. get(attack);
  332. }
  333. }
  334.  
  335. private WinLossIntel get(final Attack attack) {
  336. WinLossIntel result = attackIntel.get(attack);
  337. if (result == null) {
  338. result = new WinLossIntel();
  339. attackIntel.put(attack, result);
  340. }
  341. return result;
  342. }
  343.  
  344. private int getTotal(final Attack attack) {
  345. return get(attack).getTotal();
  346. }
  347.  
  348. private int getWins(final Attack attack) {
  349. return get(attack).getWins();
  350. }
  351.  
  352. private int getLosses(final Attack attack) {
  353. return get(attack).getLosses();
  354. }
  355.  
  356. private double getWinPercentage(final Attack attack) {
  357. return get(attack).getWinPercentage();
  358. }
  359.  
  360. private Attack getBest() {
  361. Attack bestAttack = null;
  362. double bestPercentage = -1;
  363. List<Attack> leastUsedAttacks = new ArrayList<Attack>(ATTACKS.length);
  364. int leastUses = Integer.MAX_VALUE;
  365.  
  366. for (Entry<Attack, WinLossIntel> entry : attackIntel.entrySet()) {
  367. Attack attack = entry.getKey();
  368. WinLossIntel intel = entry.getValue();
  369.  
  370. double percentage = entry.getValue().getWinPercentage();
  371. if (percentage > bestPercentage) {
  372. bestAttack = entry.getKey();
  373. bestPercentage = percentage;
  374. }
  375.  
  376. int uses = intel.getTotal();
  377. if (uses <= leastUses) {
  378. leastUsedAttacks.add(attack);
  379. leastUses = uses;
  380. }
  381. }
  382.  
  383. if (((bestPercentage - EXPECTED_WIN_PERCENTAGE) / (1 - EXPECTED_WIN_PERCENTAGE)) < (1.0 / (leastUses + 2 + random
  384. .nextDouble()))) {
  385. return leastUsedAttacks.get(random.nextInt(leastUsedAttacks.size()));
  386. } else {
  387. return bestAttack;
  388. }
  389. }
  390.  
  391. private void registerWin(final Attack attack) {
  392. registerResult(attack, true);
  393. }
  394.  
  395. private void registerLoss(final Attack attack) {
  396. registerResult(attack, false);
  397. }
  398.  
  399. private void registerResult(final Attack attack, final boolean won) {
  400. get(attack).registerResult(won);
  401. }
  402.  
  403. private boolean hasData() {
  404. for (WinLossIntel intel : attackIntel.values()) {
  405. if (intel.getTotal() > 0) {
  406. return true;
  407. }
  408. }
  409. return false;
  410. }
  411.  
  412. @Override
  413. public String toString() {
  414. return attackIntel.toString();
  415. }
  416. }
  417.  
  418. private static class FightIntel {
  419.  
  420. private final Map<Character, SimpleFightIntel> fightIntel = new HashMap<Character, SimpleFightIntel>();
  421.  
  422. FightIntel() {}
  423.  
  424. private SimpleFightIntel get(final Character opponent) {
  425. SimpleFightIntel result = fightIntel.get(opponent);
  426. if (result == null) {
  427. result = new SimpleFightIntel();
  428. fightIntel.put(opponent, result);
  429. }
  430. return result;
  431. }
  432.  
  433. private SimpleFightIntel getOpponentIntel(final Character opponent) {
  434. return get(opponent);
  435. }
  436.  
  437. private WinLossIntel get(final Character opponent, final Attack attack) {
  438. return get(opponent).get(attack);
  439. }
  440.  
  441. private int getTotal(final Character opponent, final Attack attack) {
  442. return get(opponent, attack).getTotal();
  443. }
  444.  
  445. private int getWins(final Character opponent, final Attack attack) {
  446. return get(opponent, attack).getWins();
  447. }
  448.  
  449. private int getLosses(final Character opponent, final Attack attack) {
  450. return get(opponent, attack).getLosses();
  451. }
  452.  
  453. private double getWinPercentage(final Character opponent, final Attack attack) {
  454. return get(opponent, attack).getWinPercentage();
  455. }
  456.  
  457. private Attack getBest(final Character opponent) {
  458. return get(opponent).getBest();
  459. }
  460.  
  461. private void registerWin(final Character opponent, final Attack attack) {
  462. registerResult(opponent, attack, true);
  463. }
  464.  
  465. private void registerLoss(final Character opponent, final Attack attack) {
  466. registerResult(opponent, attack, false);
  467. }
  468.  
  469. private void registerResult(final Character opponent, final Attack attack, final boolean won) {
  470. get(opponent, attack).registerResult(won);
  471. }
  472.  
  473. private boolean hasData(final Character opponent) {
  474. return get(opponent).hasData();
  475. }
  476.  
  477. @Override
  478. public String toString() {
  479. return fightIntel.toString();
  480. }
  481.  
  482. }
  483.  
  484. private static class Coordinate {
  485.  
  486. private final int x;
  487. private final int y;
  488.  
  489. Coordinate(final int y, final int x) {
  490. this.x = clip(x);
  491. this.y = clip(y);
  492. }
  493.  
  494. private int getX() {
  495. return x;
  496. }
  497.  
  498. private int getY() {
  499. return y;
  500. }
  501.  
  502. @Override
  503. public int hashCode() {
  504. final int prime = 31;
  505. int result = 1;
  506. result = (prime * result) + x;
  507. result = (prime * result) + y;
  508. return result;
  509. }
  510.  
  511. @Override
  512. public boolean equals(final Object obj) {
  513. if (this == obj) {
  514. return true;
  515. }
  516. if (obj == null) {
  517. return false;
  518. }
  519. if (getClass() != obj.getClass()) {
  520. return false;
  521. }
  522. Coordinate other = (Coordinate) obj;
  523. return (x == other.x) && (y == other.y);
  524. }
  525.  
  526. @Override
  527. public String toString() {
  528. return "[" + y + "," + x + "]";
  529. }
  530.  
  531. }
  532.  
  533. private static class LionIntel {
  534.  
  535. private final Map<Coordinate, Integer> lionIntel = new HashMap<Coordinate, Integer>();
  536.  
  537. LionIntel() {}
  538.  
  539. private static Coordinate getCoordinateOnTurn(final Coordinate coordinate, final int onTurn) {
  540. return getCoordinateOnTurn(coordinate.getY(), coordinate.getX(), onTurn);
  541. }
  542.  
  543. private static Coordinate getCoordinateOnTurn(final int y, final int x, final int onTurn) {
  544. return getCoordinateOnTurnRelativeToTurn(y, x, onTurn, 0);
  545. }
  546.  
  547. private static Coordinate getCoordinateOnTurnRelativeToTurn(final int y, final int x, final int onTurn,
  548. final int relativeToTurn) {
  549. return new Coordinate(y + ((onTurn / 2) - (relativeToTurn / 2)), x
  550. + (((onTurn + 1) / 2) - ((relativeToTurn + 1) / 2)));
  551. }
  552.  
  553. private void addOnTurn(final int y, final int x, final int onTurn) {
  554. lionIntel.put(getCoordinateOnTurnRelativeToTurn(y, x, 0, onTurn), onTurn);
  555. }
  556.  
  557. private void add(final int y, final int x) {
  558. addOnTurn(y, x, turn);
  559. }
  560.  
  561. private void add(final int y, final int x, final boolean isPresent) {
  562. if (isPresent) {
  563. add(y, x);
  564. } else {
  565. remove(y, x);
  566. }
  567. }
  568.  
  569. private void remove(final int y, final int x) {
  570. lionIntel.remove(getCoordinateOnTurnRelativeToTurn(y, x, 0, turn));
  571. }
  572.  
  573. private int size() {
  574. return lionIntel.size();
  575. }
  576.  
  577. private double assessDangerOnTurn(final int y, final int x, final int onTurn) {
  578. return assessDangerOnTurn(y, x, onTurn, false);
  579. }
  580.  
  581. private double assessDangerOnTurnWithFuture(final int y, final int x, final int onTurn) {
  582. return assessDangerOnTurn(y, x, onTurn, true);
  583. }
  584.  
  585. private double assessDangerOnTurn(final int y, final int x, final int onTurn, final boolean withFuture) {
  586. double danger = 0;
  587.  
  588. for (Entry<Coordinate, Integer> entry : lionIntel.entrySet()) {
  589. Coordinate lion = entry.getKey();
  590. int turnLastSeen = entry.getValue();
  591. Coordinate lionWhenLastSeen = getCoordinateOnTurn(lion, turnLastSeen);
  592.  
  593. int dy = posDist(lionWhenLastSeen.getY(), y);
  594. int dx = posDist(lionWhenLastSeen.getX(), x);
  595. if ((dy == 0) && (dx == 0)) {
  596. dy = dx = MAP_SIZE;
  597. } else if ((dy == 0) && (dx == (MAP_SIZE - 1))) {
  598. dy = MAP_SIZE;
  599. } else if ((dx == 0) && (dy == (MAP_SIZE - 1))) {
  600. dx = MAP_SIZE;
  601. }
  602.  
  603. int turnsUntilClosestEncounterY = (dy * 2) - (turnLastSeen % 2);
  604. int turnsUntilClosestEncounterX = ((dx * 2) - ((turnLastSeen + 1) % 2));
  605.  
  606. int turnsUntilClosestEncounter = Math.min(turnsUntilClosestEncounterY, turnsUntilClosestEncounterX) + 1;
  607. Coordinate lionAtClosestEncounter = getCoordinateOnTurn(lion, turnLastSeen + turnsUntilClosestEncounter);
  608. int closestEncounterDist = dist(lionAtClosestEncounter.getY(), y)
  609. + dist(lionAtClosestEncounter.getX(), x);
  610.  
  611. if (((turnLastSeen + turnsUntilClosestEncounter) - onTurn) < closestEncounterDist) {
  612. turnsUntilClosestEncounter = Math.max(turnsUntilClosestEncounterY, turnsUntilClosestEncounterX);
  613. lionAtClosestEncounter = getCoordinateOnTurn(lion, turnLastSeen + turnsUntilClosestEncounter);
  614. closestEncounterDist = dist(lionAtClosestEncounter.getY(), y)
  615. + dist(lionAtClosestEncounter.getX(), x);
  616. }
  617.  
  618. if (withFuture || (((turnsUntilClosestEncounter == 1)) && (closestEncounterDist == 0))) {
  619. double lionDanger = decayProximityDanger(
  620. decayPotentialDanger(getOpponentDanger(LION), turnsUntilClosestEncounter),
  621. closestEncounterDist);
  622. danger += lionDanger;
  623. }
  624. }
  625.  
  626. return danger;
  627. }
  628.  
  629. @Override
  630. public int hashCode() {
  631. return lionIntel.hashCode();
  632. }
  633.  
  634. @Override
  635. public boolean equals(final Object obj) {
  636. if (this == obj) {
  637. return true;
  638. }
  639. if (obj == null) {
  640. return false;
  641. }
  642. if (getClass() != obj.getClass()) {
  643. return false;
  644. }
  645. LionIntel other = (LionIntel) obj;
  646. return lionIntel == other.lionIntel;
  647. }
  648.  
  649. @Override
  650. public String toString() {
  651. return LionIntel.class.getSimpleName() + "[" + lionIntel.toString() + "]";
  652. }
  653.  
  654. }
  655.  
  656. private static class WolfIntel {
  657.  
  658. private final Map<Coordinate, Integer> wolfIntel = new HashMap<Coordinate, Integer>();
  659.  
  660. WolfIntel() {}
  661.  
  662. private void addOnTurn(final int y, final int x, final int onTurn) {
  663. wolfIntel.put(new Coordinate(y, x), onTurn);
  664. }
  665.  
  666. private void add(final int y, final int x) {
  667. addOnTurn(y, x, turn);
  668. }
  669.  
  670. private void add(final int y, final int x, final boolean isPresent) {
  671. if (isPresent) {
  672. add(y, x);
  673. } else {
  674. remove(y, x);
  675. }
  676. }
  677.  
  678. private void remove(final int y, final int x) {
  679. wolfIntel.remove(new Coordinate(y, x));
  680. }
  681.  
  682. private int size() {
  683. return wolfIntel.size();
  684. }
  685.  
  686. private double assessDangerOnTurn(final int y, final int x, final int onTurn) {
  687. double danger = 0;
  688.  
  689. for (Entry<Coordinate, Integer> entry : wolfIntel.entrySet()) {
  690. Coordinate wolf = entry.getKey();
  691. int turnsStale = onTurn - entry.getValue();
  692. int dist = dist(x, wolf.getX()) + dist(y, wolf.getY());
  693.  
  694. // if (turnsStale >= dist) {
  695. // danger += decayPotentialDanger(getOpponentDanger(WOLF) * Math.pow(.75, dist - 1), turnsStale - 1);
  696. // }
  697. if ((turnsStale >= dist) && (dist <= 1)) {
  698. danger += decayPotentialDanger(getOpponentDanger(WOLF) * Math.pow(PROXIMITY_DANGER_DECAY, dist),
  699. turnsStale - 1);
  700. }
  701. }
  702.  
  703. return danger;
  704. }
  705.  
  706. @Override
  707. public int hashCode() {
  708. return wolfIntel.hashCode();
  709. }
  710.  
  711. @Override
  712. public boolean equals(final Object obj) {
  713. if (this == obj) {
  714. return true;
  715. }
  716. if (obj == null) {
  717. return false;
  718. }
  719. if (getClass() != obj.getClass()) {
  720. return false;
  721. }
  722. WolfIntel other = (WolfIntel) obj;
  723. return wolfIntel == other.wolfIntel;
  724. }
  725.  
  726. @Override
  727. public String toString() {
  728. return WolfIntel.class.getSimpleName() + "[" + wolfIntel.toString() + "]";
  729. }
  730.  
  731. }
  732.  
  733. private static class MoveIntel {
  734.  
  735. private final Map<BetterMove, Integer> moves = new HashMap<BetterMove, Integer>();
  736. private int total = 0;
  737.  
  738. MoveIntel() {}
  739.  
  740. private int get(final BetterMove move) {
  741. Integer result = moves.get(move);
  742. if (result == null) {
  743. return 0;
  744. } else {
  745. return result;
  746. }
  747. }
  748.  
  749. private void add(final BetterMove move) {
  750. moves.put(move, get(move) + 1);
  751. total++;
  752. }
  753.  
  754. private int size() {
  755. return total;
  756. }
  757.  
  758. private double percentageOf(final BetterMove move) {
  759. int moveCount = get(move);
  760. return moveCount == 0 ? 0 : ((double) moveCount) / total;
  761. }
  762.  
  763. }
  764.  
  765. private class PositionIntel {
  766.  
  767. private final LionIntel lionIntel = new LionIntel();
  768. private final WolfIntel wolfIntel = new WolfIntel();
  769.  
  770. PositionIntel() {}
  771.  
  772. private void add(final int y, final int x, final char animal) {
  773. lionIntel.add(y, x, animal == LION);
  774. wolfIntel.add(y, x, animal == WOLF);
  775. }
  776.  
  777. private double assessDangerOnTurn(final int y, final int x, final int onTurn) {
  778. LionIntel potentialLionIntel = new LionIntel();
  779. WolfIntel potentialWolfIntel = new WolfIntel();
  780.  
  781. for (BetterMove move : BetterMove.values()) {
  782. int potentialY = y + move.dy;
  783. int potentialX = x + move.dx;
  784. if (!isVisible(potentialY, potentialX)) {
  785. potentialLionIntel.addOnTurn(potentialY, potentialX, onTurn - 1);
  786. potentialWolfIntel.addOnTurn(potentialY, potentialX, onTurn - 1);
  787. }
  788. }
  789.  
  790. double potentialLionDanger = potentialLionIntel.assessDangerOnTurn(y, x, onTurn)
  791. * (Math.max(0, populationIntel.guessOnTurn(LION, onTurn - 1) - lionIntel.size()) / MAP_AREA);
  792. double potentialWolfDanger = potentialWolfIntel.assessDangerOnTurn(y, x, onTurn)
  793. * (Math.max(
  794. 0,
  795. populationIntel.guessOnTurn(WOLF, onTurn - 1)
  796. + (populationIntel.guessOnTurn(FRIENDLY_WOLF, onTurn - 1) - 1)) / MAP_AREA);
  797. double lionDanger = lionIntel.assessDangerOnTurnWithFuture(y, x, onTurn);
  798. double wolfDanger = wolfIntel.assessDangerOnTurn(y, x, onTurn);
  799.  
  800. dangerTemp.set(0, potentialLionDanger);
  801. dangerTemp.set(1, potentialWolfDanger);
  802. dangerTemp.set(2, lionDanger);
  803. dangerTemp.set(3, wolfDanger);
  804.  
  805. return potentialLionDanger + potentialWolfDanger + lionDanger + wolfDanger;
  806. }
  807.  
  808. @Override
  809. public int hashCode() {
  810. final int prime = 31;
  811. int result = 1;
  812. result = (prime * result) + lionIntel.hashCode();
  813. result = (prime * result) + wolfIntel.hashCode();
  814. return result;
  815. }
  816.  
  817. @Override
  818. public boolean equals(final Object obj) {
  819. if (this == obj) {
  820. return true;
  821. }
  822. if (obj == null) {
  823. return false;
  824. }
  825. if (getClass() != obj.getClass()) {
  826. return false;
  827. }
  828. PositionIntel other = (PositionIntel) obj;
  829. return lionIntel.equals(other.lionIntel) && wolfIntel.equals(other.wolfIntel);
  830. }
  831.  
  832. @Override
  833. public String toString() {
  834. return PositionIntel.class.getSimpleName() + "[" + lionIntel.toString() + ", " + wolfIntel.toString() + "]";
  835. }
  836. }
  837.  
  838. private static class PopulationIntel {
  839.  
  840. private final Map<Character, Integer> populations = new HashMap<Character, Integer>();
  841.  
  842. PopulationIntel() {}
  843.  
  844. private int get(final char animal) {
  845. Integer result = populations.get(animal);
  846. if (result == null) {
  847. return 0;
  848. } else {
  849. return result;
  850. }
  851. }
  852.  
  853. private int getMax(final char animal) {
  854. return get(animal);
  855. }
  856.  
  857. private void addOne(final char animal) {
  858. addMany(animal, 1);
  859. }
  860.  
  861. private void addMany(final char animal, final int n) {
  862. populations.put(animal, get(animal) + n);
  863. }
  864.  
  865. private void removeOne(final char animal) {
  866. removeMany(animal, 1);
  867. }
  868.  
  869. private void removeMany(final char animal, final int n) {
  870. populations.put(animal, get(animal) - n);
  871. }
  872.  
  873. private double guess(final char animal) {
  874. return guessOnTurn(animal, turn);
  875. }
  876.  
  877. private double guessOnTurn(final char animal, final int onTurn) {
  878. int max = get(animal);
  879.  
  880. switch (animal) {
  881. case FRIENDLY_WOLF:
  882. return max;
  883. default:
  884. return max * Math.pow(1 - Math.pow(UNSEEN_DEATH_BASE_CHANCE, (getOpponentDanger(animal) + 1)), onTurn);
  885. }
  886. }
  887.  
  888. @Override
  889. public int hashCode() {
  890. return populations.hashCode();
  891. }
  892.  
  893. @Override
  894. public boolean equals(final Object obj) {
  895. if (this == obj) {
  896. return true;
  897. }
  898. if (obj == null) {
  899. return false;
  900. }
  901. if (getClass() != obj.getClass()) {
  902. return false;
  903. }
  904. PopulationIntel other = (PopulationIntel) obj;
  905. return populations.equals(other.populations);
  906. }
  907.  
  908. @Override
  909. public String toString() {
  910. return PopulationIntel.class.getSimpleName() + "[" + populations + "]";
  911. }
  912.  
  913. }
  914.  
  915. private static enum BetterMove {
  916. UP(0, -1), RIGHT(1, 0), DOWN(0, 1), LEFT(-1, 0), HOLD(0, 0);
  917.  
  918. public final int dx;
  919. public final int dy;
  920.  
  921. BetterMove(final int dx, final int dy) {
  922. this.dx = dx;
  923. this.dy = dy;
  924. }
  925.  
  926. public Move toMove() {
  927. return toMove(this);
  928. }
  929.  
  930. public static Move toMove(final BetterMove move) {
  931. return Move.valueOf(move.name());
  932. }
  933.  
  934. public static BetterMove fromMove(final Move move) {
  935. return BetterMove.valueOf(move.name());
  936. }
  937.  
  938. public boolean hasOpposite() {
  939. return hasOpposite(this);
  940. }
  941.  
  942. public static boolean hasOpposite(final BetterMove move) {
  943. return getOpposite(move) != null;
  944. }
  945.  
  946. public BetterMove getOpposite() {
  947. return getOpposite(this);
  948. }
  949.  
  950. public static BetterMove getOpposite(final BetterMove move) {
  951. switch (move) {
  952. case UP:
  953. return DOWN;
  954. case RIGHT:
  955. return LEFT;
  956. case DOWN:
  957. return UP;
  958. case LEFT:
  959. return RIGHT;
  960. case HOLD:
  961. return null;
  962. default:
  963. throw new AssertionError();
  964. }
  965. }
  966. }
  967.  
  968. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
Main.java:12: error: cannot find symbol
/*public*/ class DeepWolf extends Animal {
                                  ^
  symbol: class Animal
Main.java:27: error: cannot find symbol
    private static final Attack[]               ATTACKS                     = { Attack.ROCK, Attack.PAPER,
                         ^
  symbol:   class Attack
  location: class DeepWolf
Main.java:84: error: cannot find symbol
    public Attack fight(final char opponent) {
           ^
  symbol:   class Attack
  location: class DeepWolf
Main.java:95: error: cannot find symbol
    private Attack doFight(final char opponent) {
            ^
  symbol:   class Attack
  location: class DeepWolf
Main.java:108: error: cannot find symbol
    public Move move() {
           ^
  symbol:   class Move
  location: class DeepWolf
Main.java:437: error: cannot find symbol
        private WinLossIntel get(final Character opponent, final Attack attack) {
                                                                 ^
  symbol:   class Attack
  location: class FightIntel
Main.java:441: error: cannot find symbol
        private int getTotal(final Character opponent, final Attack attack) {
                                                             ^
  symbol:   class Attack
  location: class FightIntel
Main.java:445: error: cannot find symbol
        private int getWins(final Character opponent, final Attack attack) {
                                                            ^
  symbol:   class Attack
  location: class FightIntel
Main.java:449: error: cannot find symbol
        private int getLosses(final Character opponent, final Attack attack) {
                                                              ^
  symbol:   class Attack
  location: class FightIntel
Main.java:453: error: cannot find symbol
        private double getWinPercentage(final Character opponent, final Attack attack) {
                                                                        ^
  symbol:   class Attack
  location: class FightIntel
Main.java:457: error: cannot find symbol
        private Attack getBest(final Character opponent) {
                ^
  symbol:   class Attack
  location: class FightIntel
Main.java:461: error: cannot find symbol
        private void registerWin(final Character opponent, final Attack attack) {
                                                                 ^
  symbol:   class Attack
  location: class FightIntel
Main.java:465: error: cannot find symbol
        private void registerLoss(final Character opponent, final Attack attack) {
                                                                  ^
  symbol:   class Attack
  location: class FightIntel
Main.java:469: error: cannot find symbol
        private void registerResult(final Character opponent, final Attack attack, final boolean won) {
                                                                    ^
  symbol:   class Attack
  location: class FightIntel
Main.java:261: error: cannot find symbol
        private final Attack    attack;
                      ^
  symbol:   class Attack
  location: class Fight
Main.java:263: error: cannot find symbol
        Fight(final char opponent, final Attack attack) {
                                         ^
  symbol:   class Attack
  location: class Fight
Main.java:272: error: cannot find symbol
        private Attack getAttack() {
                ^
  symbol:   class Attack
  location: class Fight
Main.java:926: error: cannot find symbol
        public Move toMove() {
               ^
  symbol:   class Move
  location: class BetterMove
Main.java:930: error: cannot find symbol
        public static Move toMove(final BetterMove move) {
                      ^
  symbol:   class Move
  location: class BetterMove
Main.java:934: error: cannot find symbol
        public static BetterMove fromMove(final Move move) {
                                                ^
  symbol:   class Move
  location: class BetterMove
Main.java:326: error: cannot find symbol
        private final Map<Attack, WinLossIntel> attackIntel;
                          ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:335: error: cannot find symbol
        private WinLossIntel get(final Attack attack) {
                                       ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:344: error: cannot find symbol
        private int getTotal(final Attack attack) {
                                   ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:348: error: cannot find symbol
        private int getWins(final Attack attack) {
                                  ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:352: error: cannot find symbol
        private int getLosses(final Attack attack) {
                                    ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:356: error: cannot find symbol
        private double getWinPercentage(final Attack attack) {
                                              ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:360: error: cannot find symbol
        private Attack getBest() {
                ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:391: error: cannot find symbol
        private void registerWin(final Attack attack) {
                                       ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:395: error: cannot find symbol
        private void registerLoss(final Attack attack) {
                                        ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:399: error: cannot find symbol
        private void registerResult(final Attack attack, final boolean won) {
                                          ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:15: error: cannot find symbol
                                                                                    ((double) MAP_SIZE) / 20, 2) - 3) - 3;
                                                                                              ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:27: error: cannot find symbol
    private static final Attack[]               ATTACKS                     = { Attack.ROCK, Attack.PAPER,
                                                                                ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:27: error: cannot find symbol
    private static final Attack[]               ATTACKS                     = { Attack.ROCK, Attack.PAPER,
                                                                                             ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:28: error: cannot find symbol
            Attack.SCISSORS                                             };
            ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:39: error: cannot find symbol
        FIGHT_INTEL_OVERRIDE.registerWin(STONE, Attack.PAPER);
                                                ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:40: error: cannot find symbol
        FIGHT_INTEL_OVERRIDE.registerWin(BEAR, Attack.SCISSORS);
                                               ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:41: error: cannot find symbol
        FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS);
                                               ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:42: error: cannot find symbol
        FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS);
                                               ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:43: error: cannot find symbol
        FIGHT_INTEL_OVERRIDE.registerWin(LION, Attack.SCISSORS);
                                               ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:44: error: cannot find symbol
        FIGHT_INTEL_OVERRIDE.registerLoss(LION, Attack.SCISSORS);
                                                ^
  symbol:   variable Attack
  location: class DeepWolf
Main.java:58: error: type argument DeepWolf is not within bounds of type-variable E
    private static final Collection<DeepWolf>   us                          = new ArrayList<DeepWolf>();
                                    ^
  where E is a type-variable:
    E extends Object declared in interface Collection
Main.java:58: error: type argument DeepWolf is not within bounds of type-variable E
    private static final Collection<DeepWolf>   us                          = new ArrayList<DeepWolf>();
                                                                                            ^
  where E is a type-variable:
    E extends Object declared in class ArrayList
Main.java:80: error: cannot find symbol
        MAP_AREA = MAP_SIZE * MAP_SIZE;
                   ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:80: error: cannot find symbol
        MAP_AREA = MAP_SIZE * MAP_SIZE;
                              ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:89: error: cannot find symbol
        Attack attack = doFight(opponent);
        ^
  symbol:   class Attack
  location: class DeepWolf
Main.java:83: error: method does not override or implement a method from a supertype
    @Override
    ^
Main.java:118: error: cannot find symbol
        surroundings[1][1] = EMPTY;
        ^
  symbol:   variable surroundings
  location: class DeepWolf
Main.java:122: error: cannot find symbol
                positionIntel.add(y + (row - 1), x + (col - 1), surroundings[row][col]);
                                                                ^
  symbol:   variable surroundings
  location: class DeepWolf
Main.java:107: error: method does not override or implement a method from a supertype
    @Override
    ^
Main.java:182: error: type argument DeepWolf is not within bounds of type-variable E
        Iterator<DeepWolf> wolves = us.iterator();
                 ^
  where E is a type-variable:
    E extends Object declared in interface Iterator
Main.java:190: error: cannot find symbol
                Attack attack = fight.getAttack();
                ^
  symbol:   class Attack
  location: class DeepWolf
Main.java:209: error: cannot find symbol
        return ((n % MAP_SIZE) + MAP_SIZE) % MAP_SIZE;
                     ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:209: error: cannot find symbol
        return ((n % MAP_SIZE) + MAP_SIZE) % MAP_SIZE;
                                 ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:209: error: cannot find symbol
        return ((n % MAP_SIZE) + MAP_SIZE) % MAP_SIZE;
                                             ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:218: error: cannot find symbol
        return posDist < (MAP_SIZE / 2) ? posDist : MAP_SIZE - posDist;
                          ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:218: error: cannot find symbol
        return posDist < (MAP_SIZE / 2) ? posDist : MAP_SIZE - posDist;
                                                    ^
  symbol:   variable MAP_SIZE
  location: class DeepWolf
Main.java:329: error: cannot find symbol
            attackIntel = new HashMap<Attack, WinLossIntel>();
                                      ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:330: error: cannot find symbol
            for (Attack attack : ATTACKS) {
                 ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:361: error: cannot find symbol
            Attack bestAttack = null;
            ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:363: error: cannot find symbol
            List<Attack> leastUsedAttacks = new ArrayList<Attack>(ATTACKS.length);
                 ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:363: error: cannot find symbol
            List<Attack> leastUsedAttacks = new ArrayList<Attack>(ATTACKS.length);
                                                          ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:366: error: cannot find symbol
            for (Entry<Attack, WinLossIntel> entry : attackIntel.entrySet()) {
                       ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:367: error: cannot find symbol
                Attack attack = entry.getKey();
                ^
  symbol:   class Attack
  location: class SimpleFightIntel
Main.java:596: error: cannot find symbol
                    dy = dx = MAP_SIZE;
                              ^
  symbol:   variable MAP_SIZE
  location: class LionIntel
Main.java:597: error: cannot find symbol
                } else if ((dy == 0) && (dx == (MAP_SIZE - 1))) {
                                                ^
  symbol:   variable MAP_SIZE
  location: class LionIntel
Main.java:598: error: cannot find symbol
                    dy = MAP_SIZE;
                         ^
  symbol:   variable MAP_SIZE
  location: class LionIntel
Main.java:599: error: cannot find symbol
                } else if ((dx == 0) && (dy == (MAP_SIZE - 1))) {
                                                ^
  symbol:   variable MAP_SIZE
  location: class LionIntel
Main.java:600: error: cannot find symbol
                    dx = MAP_SIZE;
                         ^
  symbol:   variable MAP_SIZE
  location: class LionIntel
Main.java:931: error: cannot find symbol
            return Move.valueOf(move.name());
                   ^
  symbol:   variable Move
  location: class BetterMove
69 errors
stdout
Standard output is empty