1.1 --- a/icfp-model/src/main/java/ru/bosony/model/game/Game.java Mon Jul 16 13:19:10 2012 +0400
1.2 +++ b/icfp-model/src/main/java/ru/bosony/model/game/Game.java Wed Jul 18 09:42:52 2012 +0400
1.3 @@ -12,7 +12,9 @@
1.4 import static ru.bosony.model.cellscontents.CellContent.WadlersBeard;
1.5
1.6 import java.util.ArrayList;
1.7 +import java.util.HashMap;
1.8 import java.util.List;
1.9 +import java.util.Map;
1.10
1.11 import ru.bosony.model.cellscontents.CellContent;
1.12 import ru.bosony.model.mine.Cell;
1.13 @@ -32,6 +34,7 @@
1.14 protected int lastScoreChange = 0;
1.15 protected GameState state = GameState.Game;
1.16 protected int lambdaCollectedCount = 0;
1.17 + protected List<Mine> history = new ArrayList<Mine>();
1.18 protected List<Movement> route = new ArrayList<Movement>();
1.19 protected int underwater = 0;
1.20
1.21 @@ -69,6 +72,7 @@
1.22
1.23 // Moving and scoring
1.24 route.add(mov);
1.25 + history.add(mine.clone());
1.26 Cell robotCell = mine.getRobotCell();
1.27 Coordinate robotCoord = robotCell.getCoordinate();
1.28 Coordinate nextRobotCoord = null;
1.29 @@ -349,4 +353,24 @@
1.30 public int getUnderwater() {
1.31 return underwater;
1.32 }
1.33 +
1.34 + public boolean hasViciousCircle() {
1.35 + if (route.size() != history.size())
1.36 + throw new RuntimeException("Desynchronized history");
1.37 + Map<Mine, Movement> state = new HashMap<Mine, Movement>();
1.38 + for (int i = route.size() - 1; i >= 0; i--) {
1.39 + Mine mine = history.get(i);
1.40 + Movement mov = route.get(i);
1.41 + if (state.get(mine) == mov)
1.42 + return true;
1.43 + state.put(mine, mov);
1.44 + }
1.45 + return false;
1.46 + }
1.47 +
1.48 + @Override
1.49 + public String toString() {
1.50 + return state.toString() + ", score = " + score + ", " + route.size() + " steps: "
1.51 + + (route.size() > 100 ? getStringRoute().substring(0, 100) + "..." : getStringRoute()) + "\n\n" + mine;
1.52 + }
1.53 }
2.1 --- a/icfp-model/src/main/java/ru/bosony/model/mine/Cell.java Mon Jul 16 13:19:10 2012 +0400
2.2 +++ b/icfp-model/src/main/java/ru/bosony/model/mine/Cell.java Wed Jul 18 09:42:52 2012 +0400
2.3 @@ -36,4 +36,9 @@
2.4 return clone;
2.5 }
2.6
2.7 + @Override
2.8 + public String toString() {
2.9 + return "Cell [coordinate=" + coordinate + ", content=" + content + "]";
2.10 + }
2.11 +
2.12 }
3.1 --- a/icfp-model/src/main/java/ru/bosony/model/mine/Mine.java Mon Jul 16 13:19:10 2012 +0400
3.2 +++ b/icfp-model/src/main/java/ru/bosony/model/mine/Mine.java Wed Jul 18 09:42:52 2012 +0400
3.3 @@ -8,6 +8,7 @@
3.4 import static ru.bosony.model.cellscontents.CellContent.OpenLambdaLift;
3.5 import static ru.bosony.model.cellscontents.CellContent.Rock;
3.6
3.7 +import java.util.Collection;
3.8 import java.util.HashSet;
3.9 import java.util.Set;
3.10 import java.util.regex.Matcher;
3.11 @@ -23,7 +24,7 @@
3.12 * 14.07.2012 2:02:18
3.13 *
3.14 */
3.15 -public class Mine implements TextRepresentable {
3.16 +public class Mine implements TextRepresentable, Cloneable {
3.17
3.18 protected Cell[][] cells;
3.19 protected int sizeX;
3.20 @@ -48,13 +49,17 @@
3.21 protected static String firstTrampolineRegexp = "(?s).*?Trampoline ([A-I]) targets ([1-9])";
3.22
3.23 public Mine(String text) {
3.24 - fromText(text);
3.25 + this(text, null);
3.26 if (findCells(OpenLambdaLift).size() != 0)
3.27 throw new RuntimeException("Detected OpenLambdaLift in new map!");
3.28 if (findCells(MiningRobot).size() != 1)
3.29 throw new RuntimeException("New map does not contain a robot!");
3.30 if (findCells(ClosedLambdaLift).size() != 1)
3.31 throw new RuntimeException("New map does not contain a ClosedLambdaLift!");
3.32 + }
3.33 +
3.34 + protected Mine(String text, Object obj) {
3.35 + fromText(text);
3.36 lambdasAndHighOrderRocksStartCount = findCells(Lambda).size() + findCells(CellContent.HighOrderRock).size();
3.37 }
3.38
3.39 @@ -74,6 +79,10 @@
3.40 return text;
3.41 }
3.42
3.43 + public String toTextWithoutRobot() {
3.44 + return toText().replaceAll(CellContent.MiningRobot.toText(), CellContent.Empty.toText());
3.45 + }
3.46 +
3.47 protected void fromText(String str) {
3.48 Matcher matcher = minePattern.matcher(str);
3.49 if (!matcher.matches())
3.50 @@ -174,6 +183,18 @@
3.51 return cells[x - 1][sizeY - y];
3.52 }
3.53
3.54 + public Set<Cell> getCells(Collection<Coordinate> coordinates) {
3.55 + Set<Cell> cells = new HashSet<Cell>();
3.56 + if (coordinates == null)
3.57 + return cells;
3.58 + for (Coordinate coordinate : coordinates) {
3.59 + Cell cell = getCell(coordinate);
3.60 + if (cell != null)
3.61 + cells.add(cell);
3.62 + }
3.63 + return cells;
3.64 + }
3.65 +
3.66 @Override
3.67 public String toString() {
3.68 return toText();
3.69 @@ -215,15 +236,21 @@
3.70
3.71 public Set<Cell> getNeighboringCells(Cell cell) {
3.72 Set<Cell> cells = new HashSet<Cell>();
3.73 - for (Coordinate coordinate : cell.getCoordinate().getNeighboringCoordinates())
3.74 - cells.add(getCell(coordinate));
3.75 + for (Coordinate coordinate : cell.getCoordinate().getNeighboringCoordinates()) {
3.76 + Cell nextCell = getCell(coordinate);
3.77 + if (nextCell != null)
3.78 + cells.add(nextCell);
3.79 + }
3.80 return cells;
3.81 }
3.82
3.83 public Set<Cell> getAdjacentCells(Cell cell) {
3.84 Set<Cell> cells = new HashSet<Cell>();
3.85 - for (Coordinate coordinate : cell.getCoordinate().getAdjacentCoordinates())
3.86 - cells.add(getCell(coordinate));
3.87 + for (Coordinate coordinate : cell.getCoordinate().getAdjacentCoordinates()) {
3.88 + Cell nextCell = getCell(coordinate);
3.89 + if (nextCell != null)
3.90 + cells.add(nextCell);
3.91 + }
3.92 return cells;
3.93 }
3.94
3.95 @@ -309,4 +336,9 @@
3.96 return toText().hashCode();
3.97 }
3.98
3.99 + @Override
3.100 + public Mine clone() {
3.101 + return new Mine(toText(), null);
3.102 + }
3.103 +
3.104 }
4.1 --- a/icfp-model/src/main/java/ru/bosony/model/moving/Coordinate.java Mon Jul 16 13:19:10 2012 +0400
4.2 +++ b/icfp-model/src/main/java/ru/bosony/model/moving/Coordinate.java Wed Jul 18 09:42:52 2012 +0400
4.3 @@ -96,4 +96,9 @@
4.4 return super.equals(obj);
4.5 }
4.6
4.7 + @Override
4.8 + public String toString() {
4.9 + return "Coordinate [x=" + x + ", y=" + y + "]";
4.10 + }
4.11 +
4.12 }
5.1 --- a/icfp-model/src/main/java/ru/bosony/model/moving/Movement.java Mon Jul 16 13:19:10 2012 +0400
5.2 +++ b/icfp-model/src/main/java/ru/bosony/model/moving/Movement.java Wed Jul 18 09:42:52 2012 +0400
5.3 @@ -9,13 +9,13 @@
5.4 */
5.5 public enum Movement implements TextRepresentable {
5.6
5.7 + WAIT("W"),
5.8 + RAZOR("S"),
5.9 LEFT("L"),
5.10 + UP("U"),
5.11 RIGHT("R"),
5.12 - UP("U"),
5.13 DOWN("D"),
5.14 - WAIT("W"),
5.15 - ABORT("A"),
5.16 - RAZOR("S");
5.17 + ABORT("A");
5.18
5.19 private String text;
5.20
6.1 --- a/icfp-solver/src/main/java/ru/bosony/graph/CellsLink.java Mon Jul 16 13:19:10 2012 +0400
6.2 +++ b/icfp-solver/src/main/java/ru/bosony/graph/CellsLink.java Wed Jul 18 09:42:52 2012 +0400
6.3 @@ -56,4 +56,9 @@
6.4 return super.equals(obj);
6.5 }
6.6
6.7 + @Override
6.8 + public String toString() {
6.9 + return "CellsLink [source=" + source + ", target=" + target + ", weight=" + weight + "]";
6.10 + }
6.11 +
6.12 }
7.1 --- a/icfp-solver/src/main/java/ru/bosony/solvers/AbstractSolver.java Mon Jul 16 13:19:10 2012 +0400
7.2 +++ b/icfp-solver/src/main/java/ru/bosony/solvers/AbstractSolver.java Wed Jul 18 09:42:52 2012 +0400
7.3 @@ -1,8 +1,10 @@
7.4 package ru.bosony.solvers;
7.5
7.6 -import java.util.HashMap;
7.7 -import java.util.Map;
7.8 +import java.text.DecimalFormat;
7.9 +import java.util.HashSet;
7.10 +import java.util.Set;
7.11
7.12 +import ru.bosony.model.game.Game;
7.13 import ru.bosony.model.mine.Mine;
7.14
7.15 /**
7.16 @@ -12,32 +14,39 @@
7.17 */
7.18 public abstract class AbstractSolver {
7.19
7.20 - protected Mine mine = null;
7.21 - protected SolverListener listener = null;
7.22 - protected Map<String, Integer> routesWithScore = new HashMap<String, Integer>();
7.23 - protected long attemptsCount = 0;
7.24 + protected Mine initialMine = null;
7.25 + protected SolverListener listener = null;
7.26 + protected Set<Game> games = new HashSet<Game>();
7.27 + protected long attemptsCount = 0;
7.28 + protected long startTime = System.currentTimeMillis();
7.29
7.30 public AbstractSolver(Mine mine, SolverListener listener) {
7.31 - this.mine = mine;
7.32 + this.initialMine = mine;
7.33 this.listener = listener;
7.34 - solve();
7.35 }
7.36
7.37 - protected void addNewRoute(String route, int score) {
7.38 - if (!routesWithScore.containsKey(route) && score > getMaxFoundScore()) {
7.39 - routesWithScore.put(route, score);
7.40 - listener.foundNextRoute(route);
7.41 + protected void addNewRoute(Game game) {
7.42 + Game maxScoreGame = getMaxFoundScoreGame();
7.43 + if (maxScoreGame == null || game.getScore() > maxScoreGame.getScore()
7.44 + || game.getScore() == maxScoreGame.getScore()
7.45 + && game.getRoute().size() < maxScoreGame.getRoute().size()) {
7.46 + listener.foundNextRoute(game.getStringRoute());
7.47 + // TODO delete
7.48 + System.out.println(new DecimalFormat("0.00").format((((System.currentTimeMillis() - startTime) / 1000d)))
7.49 + + " seconds, State = " + game.getState() + ", Score = " + game.getScore() + ", Route("
7.50 + + game.getRoute().size() + ") = " + game.getStringRoute());
7.51 }
7.52 + games.add(game);
7.53 }
7.54
7.55 - protected int getMaxFoundScore() {
7.56 - int maxScore = 0;
7.57 - for (int foundScore : routesWithScore.values()) {
7.58 - if (foundScore > maxScore)
7.59 - maxScore = foundScore;
7.60 + protected Game getMaxFoundScoreGame() {
7.61 + Game game = null;
7.62 + for (Game foundGame : games) {
7.63 + if (game == null || foundGame.getScore() > game.getScore())
7.64 + game = foundGame;
7.65 }
7.66 - return maxScore;
7.67 + return game;
7.68 }
7.69
7.70 - protected abstract void solve();
7.71 + public abstract void solve();
7.72 }
8.1 --- a/icfp-solver/src/main/java/ru/bosony/solvers/DijkstraSolver.java Mon Jul 16 13:19:10 2012 +0400
8.2 +++ b/icfp-solver/src/main/java/ru/bosony/solvers/DijkstraSolver.java Wed Jul 18 09:42:52 2012 +0400
8.3 @@ -1,8 +1,10 @@
8.4 package ru.bosony.solvers;
8.5
8.6 import java.util.ArrayList;
8.7 +import java.util.HashMap;
8.8 import java.util.HashSet;
8.9 import java.util.List;
8.10 +import java.util.Map;
8.11 import java.util.Set;
8.12
8.13 import ru.bosony.graph.CellsLink;
8.14 @@ -12,6 +14,7 @@
8.15 import ru.bosony.model.game.GameState;
8.16 import ru.bosony.model.mine.Cell;
8.17 import ru.bosony.model.mine.Mine;
8.18 +import ru.bosony.model.moving.Coordinate;
8.19 import ru.bosony.model.moving.Movement;
8.20 import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
8.21 import edu.uci.ics.jung.graph.DirectedSparseGraph;
8.22 @@ -24,77 +27,197 @@
8.23 */
8.24 public class DijkstraSolver extends AbstractSolver {
8.25
8.26 + protected Map<String, Set<Movement>> loseMovs = new HashMap<String, Set<Movement>>();
8.27 + protected Map<String, Set<CellsLink>> loseLinks = new HashMap<String, Set<CellsLink>>();
8.28 + protected Map<String, Set<Coordinate>> attendedWalkingAroundCoordinates = new HashMap<String, Set<Coordinate>>();
8.29 + protected Map<String, Set<Coordinate>> noWay = new HashMap<String, Set<Coordinate>>();
8.30 +
8.31 public DijkstraSolver(Mine mine, SolverListener listener) {
8.32 super(mine, listener);
8.33 }
8.34
8.35 @Override
8.36 - protected void solve() {
8.37 + public void solve() {
8.38 while (true) {
8.39 + Mine mine = null;
8.40 + mine = initialMine.clone();
8.41 Game game = new Game(mine);
8.42
8.43 while (game.getState() == GameState.Game) {
8.44 - try {
8.45 - Set<Cell> targets = mine.findCells(CellContent.Lambda);
8.46 + Cell robotCell = mine.getRobotCell();
8.47 + String map = mine.toText();
8.48 + String mapWithoutRobot = mine.toTextWithoutRobot();
8.49 + if (!loseMovs.containsKey(map)) {
8.50 + loseMovs.put(map, new HashSet<Movement>());
8.51 + }
8.52 + if (!loseLinks.containsKey(map)) {
8.53 + loseLinks.put(map, new HashSet<CellsLink>());
8.54 + }
8.55 + if (!noWay.containsKey(map)) {
8.56 + noWay.put(map, new HashSet<Coordinate>());
8.57 + }
8.58 + if (!attendedWalkingAroundCoordinates.containsKey(mapWithoutRobot)) {
8.59 + attendedWalkingAroundCoordinates.put(mapWithoutRobot, new HashSet<Coordinate>());
8.60 + }
8.61 + attendedWalkingAroundCoordinates.get(mapWithoutRobot).add(robotCell.getCoordinate());
8.62 + Set<Cell> targets = new HashSet<Cell>();
8.63 + boolean isFreeWay = false;
8.64 + for (Cell cell : mine.getAdjacentCells(robotCell)) {
8.65 + Movement mov = robotCell.getCoordinate().getNecessaryMovement(cell.getCoordinate());
8.66 + isFreeWay |= !attendedWalkingAroundCoordinates.get(mapWithoutRobot).contains(cell.getCoordinate())
8.67 + && !loseMovs.get(map).contains(mov);
8.68 + }
8.69 + if (isFreeWay) {
8.70 + targets.addAll(mine.findCells(CellContent.Lambda));
8.71 targets.addAll(mine.findCells(CellContent.HighOrderRock));
8.72 if (targets.size() == 0)
8.73 - targets = mine.findCells(CellContent.OpenLambdaLift);
8.74 - if (targets.size() == 0)
8.75 - break;
8.76 - Graph<Cell, CellsLink> graph = getDirectedGraph();
8.77 - DijkstraShortestPath<Cell, CellsLink> alg = new DijkstraShortestPath<Cell, CellsLink>(graph,
8.78 - new CellsLinkTransformer<CellsLink, Double>());
8.79 - Cell nextTarget = null;
8.80 - List<CellsLink> routeToNextTarget = null;
8.81 - double shortestDist = Double.MAX_VALUE;
8.82 - for (Cell target : targets) {
8.83 - List<CellsLink> route = alg.getPath(mine.getRobotCell(), target);
8.84 - Number dist = alg.getDistance(mine.getRobotCell(), target);
8.85 - if (dist != null && dist.doubleValue() < shortestDist) {
8.86 + targets.addAll(mine.findCells(CellContent.OpenLambdaLift));
8.87 + targets.removeAll(mine.getCells(noWay.get(map)));
8.88 + } else {
8.89 + targets.addAll(mine.findCells(CellContent.Empty));
8.90 + targets.addAll(mine.findCells(CellContent.Earth));
8.91 + targets.addAll(mine.findCells(CellContent.HuttonsRazor));
8.92 + for (CellContent content : CellContent.getTrampolines()) {
8.93 + targets.addAll(mine.findCells(content));
8.94 + }
8.95 + targets.removeAll(mine.getCells(attendedWalkingAroundCoordinates.get(mapWithoutRobot)));
8.96 + targets.removeAll(mine.getCells(noWay.get(map)));
8.97 + if (targets.size() == 0) {
8.98 + game.move(Movement.ABORT);
8.99 + continue;
8.100 + }
8.101 + }
8.102 + Graph<Cell, CellsLink> graph = getDirectedGraph(mine);
8.103 + DijkstraShortestPath<Cell, CellsLink> alg = new DijkstraShortestPath<Cell, CellsLink>(graph,
8.104 + new CellsLinkTransformer<CellsLink, Double>());
8.105 + Cell nextTarget = null;
8.106 + List<CellsLink> routeToNextTarget = null;
8.107 + double shortestDist = Double.MAX_VALUE;
8.108 + for (Cell target : targets) {
8.109 + List<CellsLink> route = null;
8.110 + Number dist = null;
8.111 + try {
8.112 + route = alg.getPath(mine.getRobotCell(), target);
8.113 + dist = alg.getDistance(mine.getRobotCell(), target);
8.114 + } catch (IllegalArgumentException e) {
8.115 + noWay.get(map).add(target.getCoordinate());
8.116 + continue;
8.117 + }
8.118 + if (dist != null && route != null && route.size() > 0 && dist.doubleValue() < shortestDist) {
8.119 + CellsLink firstLink = route.get(0);
8.120 + Movement mov = firstLink.getSource().getCoordinate()
8.121 + .getNecessaryMovement(firstLink.getTarget().getCoordinate());
8.122 + if (!loseMovs.get(map).contains(mov)
8.123 + && !attendedWalkingAroundCoordinates.get(mapWithoutRobot).contains(
8.124 + target.getCoordinate())) {
8.125 shortestDist = dist.doubleValue();
8.126 nextTarget = target;
8.127 routeToNextTarget = route;
8.128 }
8.129 }
8.130 - if (nextTarget != null) {
8.131 - for (CellsLink link : routeToNextTarget) {
8.132 - Movement mov = link.getSource().getCoordinate()
8.133 - .getNecessaryMovement(link.getTarget().getCoordinate());
8.134 - game.move(mov);
8.135 - break;
8.136 + }
8.137 + if (nextTarget != null) {
8.138 + for (CellsLink link : routeToNextTarget) {
8.139 + Cell source = link.getSource();
8.140 + Cell target = link.getTarget();
8.141 + if (isSafeMovement(mine, source, target)) {
8.142 + Movement mov = source.getCoordinate().getNecessaryMovement(target.getCoordinate());
8.143 + GameState state = game.move(mov);
8.144 + if (state == GameState.Lose || state == GameState.Abort) {
8.145 + loseMovs.get(map).add(mov);
8.146 + loseLinks.get(map).add(link);
8.147 + }
8.148 + }
8.149 + break;
8.150 + }
8.151 + } else {
8.152 + // Walking around
8.153 + for (Movement mov : Movement.values()) {
8.154 + if (!loseMovs.get(map).contains(mov)) {
8.155 + if (mov == Movement.RAZOR && mine.getRazorsCount() > 0) {
8.156 + boolean isRazorApplied = false;
8.157 + for (Cell cell : mine.getNeighboringCells(robotCell)) {
8.158 + isRazorApplied |= cell.getContent() == CellContent.WadlersBeard;
8.159 + }
8.160 + if (!isRazorApplied)
8.161 + continue;
8.162 + }
8.163 + Cell movCell = null;
8.164 + for (Cell cell : mine.getAdjacentCells(robotCell)) {
8.165 + if (robotCell.getCoordinate().getNecessaryMovement(cell.getCoordinate()) == mov) {
8.166 + if (!attendedWalkingAroundCoordinates.get(mapWithoutRobot).contains(
8.167 + cell.getCoordinate())) {
8.168 + movCell = cell;
8.169 + break;
8.170 + }
8.171 + }
8.172 +
8.173 + }
8.174 + if (mov == Movement.WAIT
8.175 + || mov == Movement.RAZOR
8.176 + || movCell != null
8.177 + && !attendedWalkingAroundCoordinates.get(mapWithoutRobot).contains(
8.178 + movCell.getCoordinate())) {
8.179 + GameState state = game.move(mov);
8.180 + if (movCell != null && mapWithoutRobot.equals(mine.toTextWithoutRobot()))
8.181 + attendedWalkingAroundCoordinates.get(mapWithoutRobot).add(movCell.getCoordinate());
8.182 + if (state == GameState.Game && map.equals(mine.toText())) {
8.183 + loseMovs.get(map).add(mov);
8.184 + }
8.185 + break;
8.186 + }
8.187 }
8.188 }
8.189 - } catch (IllegalArgumentException e) {
8.190 - // hmmm...
8.191 }
8.192 }
8.193 - if (game.getState() == GameState.Win) {
8.194 - addNewRoute(game.getStringRoute(), game.getScore());
8.195 - }
8.196 + addNewRoute(game);
8.197 attemptsCount++;
8.198 }
8.199 }
8.200
8.201 - protected Graph<Cell, CellsLink> getDirectedGraph() {
8.202 + protected boolean isSafeMovement(Mine mine, Cell source, Cell target) {
8.203 + if (source == null || target == null)
8.204 + return false;
8.205 + if (source.getContent().getTrampolineTarget() == target.getContent())
8.206 + return true;
8.207 + Cell upCell = mine.getCell(target.getCoordinate().up());
8.208 + if (upCell == null)
8.209 + return true;
8.210 + Cell upUpCell = mine.getCell(target.getCoordinate().up().up());
8.211 + Cell upUpLeftCell = mine.getCell(target.getCoordinate().up().up().left());
8.212 + Cell upUpRightCell = mine.getCell(target.getCoordinate().up().up().right());
8.213 + if (upCell.getContent() == CellContent.Empty
8.214 + && (upUpCell != null
8.215 + && (upUpCell.getContent() == CellContent.Rock || upUpCell.getContent() == CellContent.HighOrderRock)
8.216 + || upUpLeftCell != null
8.217 + && (upUpLeftCell.getContent() == CellContent.Rock || upUpLeftCell.getContent() == CellContent.HighOrderRock) || upUpRightCell != null
8.218 + && (upUpRightCell.getContent() == CellContent.Rock || upUpRightCell.getContent() == CellContent.HighOrderRock))) {
8.219 + return false;
8.220 + }
8.221 + return true;
8.222 + }
8.223 +
8.224 + protected Graph<Cell, CellsLink> getDirectedGraph(Mine mine) {
8.225 Graph<Cell, CellsLink> graph = new DirectedSparseGraph<Cell, CellsLink>();
8.226 - for (CellsLink link : getCellLinks()) {
8.227 + for (CellsLink link : getCellLinks(mine)) {
8.228 graph.addEdge(link, link.getSource(), link.getTarget());
8.229 }
8.230 return graph;
8.231 }
8.232
8.233 - protected List<CellsLink> getCellLinks() {
8.234 + protected List<CellsLink> getCellLinks(Mine mine) {
8.235 List<CellsLink> links = new ArrayList<CellsLink>();
8.236 Cell robotCell = mine.getRobotCell();
8.237 - findAllCellLinks(robotCell, links, new HashSet<Cell>());
8.238 + findAllCellLinks(mine, robotCell, links, new HashSet<Cell>());
8.239 return links;
8.240 }
8.241
8.242 - protected void findAllCellLinks(Cell cell, List<CellsLink> links, Set<Cell> processedCells) {
8.243 + protected void findAllCellLinks(Mine mine, Cell cell, List<CellsLink> links, Set<Cell> processedCells) {
8.244 if (processedCells.contains(cell))
8.245 return;
8.246 else
8.247 processedCells.add(cell);
8.248 + String map = mine.toText();
8.249 for (Cell neighboringCell : mine.getAdjacentCells(cell)) {
8.250 if (neighboringCell == null)
8.251 continue;
8.252 @@ -102,21 +225,29 @@
8.253 if (neighboringContent == CellContent.Earth || neighboringContent == CellContent.Empty
8.254 || neighboringContent == CellContent.HuttonsRazor || neighboringContent == CellContent.Lambda
8.255 || neighboringContent == CellContent.OpenLambdaLift) {
8.256 - CellsLink link = new CellsLink(mine, cell, neighboringCell);
8.257 - links.add(link);
8.258 - findAllCellLinks(neighboringCell, links, processedCells);
8.259 + if (isSafeMovement(mine, cell, neighboringCell)) {
8.260 + CellsLink link = new CellsLink(mine, cell, neighboringCell);
8.261 + if (!loseLinks.get(map).contains(link)) {
8.262 + links.add(link);
8.263 + findAllCellLinks(mine, neighboringCell, links, processedCells);
8.264 + }
8.265 + }
8.266 } else if (!CellContent.getTargets().contains(cell.getContent())
8.267 && CellContent.getTargets().contains(neighboringContent)) {
8.268 - findAllCellLinks(neighboringCell, links, processedCells);
8.269 + findAllCellLinks(mine, neighboringCell, links, processedCells);
8.270 }
8.271 }
8.272 if (CellContent.getTrampolines().contains(cell.getContent())) {
8.273 for (Cell target : mine.findCells(cell.getContent().getTrampolineTarget())) {
8.274 if (target == null)
8.275 continue;
8.276 - CellsLink link = new CellsLink(mine, cell, target);
8.277 - links.add(link);
8.278 - findAllCellLinks(target, links, processedCells);
8.279 + if (isSafeMovement(mine, cell, target)) {
8.280 + CellsLink link = new CellsLink(mine, cell, target);
8.281 + if (!loseLinks.get(map).contains(link)) {
8.282 + links.add(link);
8.283 + findAllCellLinks(mine, target, links, processedCells);
8.284 + }
8.285 + }
8.286 }
8.287 }
8.288 }
9.1 --- a/icfp-solver/src/main/java/ru/bosony/solvers/SimpleSolver.java Mon Jul 16 13:19:10 2012 +0400
9.2 +++ b/icfp-solver/src/main/java/ru/bosony/solvers/SimpleSolver.java Wed Jul 18 09:42:52 2012 +0400
9.3 @@ -14,7 +14,7 @@
9.4 }
9.5
9.6 @Override
9.7 - protected void solve() {
9.8 + public void solve() {
9.9 String route = "";
9.10 while (true) {
9.11 try {
10.1 --- a/icfp-solver/src/main/java/ru/bosony/solvers/Solver.java Mon Jul 16 13:19:10 2012 +0400
10.2 +++ b/icfp-solver/src/main/java/ru/bosony/solvers/Solver.java Wed Jul 18 09:42:52 2012 +0400
10.3 @@ -32,6 +32,7 @@
10.4 route = newRoute;
10.5 }
10.6 });
10.7 + solver.solve();
10.8 }
10.9
10.10 public static void main(String[] args) throws IOException, InterruptedException {
11.1 --- a/icfp-submit/pom.xml Mon Jul 16 13:19:10 2012 +0400
11.2 +++ b/icfp-submit/pom.xml Wed Jul 18 09:42:52 2012 +0400
11.3 @@ -19,7 +19,7 @@
11.4 <descriptors>
11.5 <descriptor>src/main/assembly/assembly.xml</descriptor>
11.6 </descriptors>
11.7 - <finalName>icfp-xxxxxxxx</finalName>
11.8 + <finalName>icfp-96518158</finalName>
11.9 </configuration>
11.10 <executions>
11.11 <execution>