/** * Somewhat multi-threaded depth-first search. Performs a DFS of the subtrees from the current * node in parallel. * * @param s The tile sequence * @param b The board to search * @param pool The thread pool in which to submit jobs to. * @return The board with the highest evaluation or null if no board can continue. */ private Board solve_pdfs(Board b, ExecutorService pool) { List<Future<Board>> rets = new ArrayList<>(BOARD_WIDTH); Board best = null; int best_score = -1; for (Direction d : directions) { Board n = new Board(b); if (n.move(tileSequence, d)) { rets.add(pool.submit(new ParallelDFS(n))); } } for (Future<Board> ret : rets) { try { Board c = ret.get(); if (c != null) { int score = evaluate(c); if (score > best_score) { best = c; best_score = score; } } } catch (InterruptedException | ExecutionException e) { System.err.println("Error: " + e.getMessage()); } } return best; }
private Board solve_dfs(Board b, int depthLimit, int depth) { if (depth >= depthLimit) { // Cutoff test return b; } Board best = null; int best_score = -1; for (int i = 0; i < BOARD_WIDTH; i++) { Board next = new Board(b); if (next.move(tileSequence, directions[i])) { Board candidate = solve_dfs(next, depthLimit, depth + 1); if (candidate == null && next.finished()) { candidate = next; } if (candidate != null) { if (candidate.finished()) { updateBest(candidate); } else { int score = evaluate(candidate); if (score > best_score) { best_score = score; best = candidate; } } } } } return best; }
// returns the single move to make given a board, depth, piecelist, heuristic // whill choose the best terminal board at the max depth, // or if none exists, the best board with no children (inevitable death) public Board.Direction nextMove(Board start, List<Integer> nextPiece) { int maxDepth = Math.min(exploreDepth, nextPiece.size()); double bestLiveScore = -1; Board.Direction bestLiveDirection = null; // cus why not? // add the first round seperately so we know which move to return for (Board.Direction d : Board.Direction.values()) { Board next = start.move(d, nextPiece.get(0)); if (next != null) { PriorityQueue<Double> pq = new PriorityQueue<Double>(); Deque<StackItem> stack = new ArrayDeque<StackItem>(); stack.push(new StackItem(next, 1, d)); // DFS while (!stack.isEmpty()) { StackItem cur = stack.pop(); // add more moves if not beyond max depth if (cur.d < maxDepth) { for (Board.Direction d2 : Board.Direction.values()) { Board next2 = cur.b.move(d2, nextPiece.get(cur.d)); if (next2 != null) { stack.push(new StackItem(next2, cur.d + 1, cur.move)); } } } // update live only at the bottom of the tree if (cur.d == maxDepth) { pq.add(heuristic.useHeuristic(cur.b)); if (pq.size() > 10) pq.poll(); } } double sum = 0; int count = 0; count = pq.size(); while (!pq.isEmpty()) sum += pq.poll(); if (count > 0 && sum / count > bestLiveScore) { bestLiveScore = sum / count; bestLiveDirection = d; } } } return bestLiveDirection; }
public void finishedSelectingUnits(TilePanel tilePanel, List<Unit> chosenUnits) { UnitActionDetector unitActionDetector = new UnitActionDetector(selectedPanel, selectedUnit, tilePanel, chosenUnits); if (unitActionDetector.isSelectingUnit()) { selectedPanel = tilePanel; selectedPanel.addTileStateFromKey(selectedStateKey); repaintPanels(selectedPanel); selectedUnit = getUnit(chosenUnits); selectValidMovements(selectedPanel.getTile(), selectedUnit); } else if (unitActionDetector.isDeselectingUnit()) { selectedPanel.removeTileStateFromKey(selectedStateKey); deselectValidMovements(selectedPanel.getTile(), selectedUnit); repaintPanels(selectedPanel); selectedPanel = null; selectedUnit = null; } else if (unitActionDetector.isMovingUnit()) { Position from = selectedPanel.getTile().getPosition(); Position to = tilePanel.getTile().getPosition(); if (movementStrategy.isValidMove(selectedUnit, from, to, unitMap)) { deselectValidMovements(selectedPanel.getTile(), selectedUnit); selectedPanel.removeTileStateFromKey(selectedStateKey); List<Unit> units = unitMap.get(to); if (units != null && !units.isEmpty()) { Unit defending = units.get(0); BattleStrategy strategy = battleStrategyConfiguration.getBattleStrategy( selectedUnit, defending, selectedPanel.getTile(), tilePanel.getTile()); Unit winner = strategy.getWinner(selectedUnit, defending); if (winner.equals(selectedUnit)) { units.remove(defending); } } board.move(selectedUnit, from, to); repaintPanels(selectedPanel); selectedPanel = null; selectedUnit = null; } } frame.setEnabled(true); resetPositions(); }