예제 #1
0
  /**
   * 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;
  }
예제 #2
0
  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;
  }
예제 #3
0
  // 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;
  }
예제 #4
0
  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();
  }