Esempio n. 1
0
  // Returns true if B wins
  public static boolean tryFirstMove(GridChar grid, int aKingLoc, int bKingLoc) {

    grid.setEntry(aKingLoc, '#');
    grid.setEntry(bKingLoc, 'K');

    boolean r = true;
    while (r) {
      // r = findLoserSquares(input.grid);
      r = reduceGrid(grid, bKingLoc);
    }

    for (Direction dir : Direction.values()) {
      Integer childIdx = grid.getIndex(bKingLoc, dir);
      if (childIdx == null) continue;

      char sq = grid.getEntry(childIdx);

      if (sq == 'V') {
        return true;
      }

      if (sq == '#' || sq == 'T') {
        continue;
      }

      // int size = 1 + getConnectedSquareCount(grid, childIdx);
      if (getConnectedSquareCount(grid, childIdx)) return true;
      //            if (size % 2 == 0) {
      //                return true;
      //            }

    }

    return false;
  }
Esempio n. 2
0
  public static boolean reduceGrid(GridChar grid, final int kingLoc) {
    // Create a graph corresponding to grid
    GraphInt graph = new GraphInt();

    int startingLoc = kingLoc; // getOpenNodeNextToKing(grid, kingLoc);

    Set<Integer> visitedNodes = Sets.newHashSet();

    LinkedList<Integer> toVisit = new LinkedList<>();
    toVisit.add(startingLoc);

    while (!toVisit.isEmpty()) {

      Integer loc = toVisit.poll();

      if (visitedNodes.contains(loc)) continue;

      visitedNodes.add(loc);

      for (Direction dir : Direction.values()) {
        Integer childIdx = grid.getIndex(loc, dir);
        if (childIdx == null) continue;

        char sq = grid.getEntry(childIdx);

        if (sq == '#' || sq == 'K' || sq == 'V' || sq == 'T') continue;

        if (loc == kingLoc)
          // graph.addOneWayConnection(loc,childIdx);
          graph.addConnection(loc, childIdx);
        else graph.addConnection(loc, childIdx);

        toVisit.add(childIdx);
      }
    }

    ArticulationPoint ap = new ArticulationPoint(graph);
    // Find bridges
    List<Integer> artPoints = ap.getArticulationPoints();

    for (Integer aPoint : artPoints) {

      if (aPoint == kingLoc) continue;
      Set<Integer> adjNodes = graph.getNeighbors(aPoint);

      Set<Integer> isolatedNodes = Sets.newHashSet();
      Set<Integer> nonIsolatedNodes = Sets.newHashSet();

      adjNodeLoop:
      for (Integer adjNode : adjNodes) {
        if (isolatedNodes.contains(adjNode) || nonIsolatedNodes.contains(adjNode)) continue;

        Set<Integer> nodes =
            GraphIntAlgorithms.getConnectedNodesWithoutNode(graph, adjNode, aPoint);

        // Isolated set must not contain other articulation points
        for (Integer aPointToTest : artPoints) {
          if (nodes.contains(aPointToTest)) {
            nonIsolatedNodes.addAll(nodes);
            continue adjNodeLoop;
          }
        }

        if (!nodes.contains(startingLoc)) {
          isolatedNodes = nodes;
          break;
        }
      }

      // No suitable isolated set found, continue to next articulation point
      if (isolatedNodes == null || isolatedNodes.isEmpty()) continue;

      if (isolatedNodes.size() % 2 == 0) {
        // All the isolated nodes are traps
        for (Integer isoNode : isolatedNodes) {
          grid.setEntry(isoNode, 'T');
        }
        return true;
      } else {
        // The articulation point itself is a trap, as moving to it means
        // the other player can move into an odd numbered field, which is always
        // losing
        grid.setEntry(aPoint, 'T');
        return true;
      }
    }

    return false;
  }