예제 #1
0
파일: AI.java 프로젝트: slauson/Tactics
  /**
   * Returns random reinforcement.
   *
   * @param overworld overworld
   * @param player player
   * @param forceReinforcement true if we want to force reinforcements to happen, if possible
   * @param onlyNew true if we only want new reinforcements
   * @return random reinforcement
   */
  protected static Move getRandomReinforcement(
      Overworld overworld, Player player, boolean forceReinforcement, boolean onlyNew) {

    // player can't make any reinforcements
    if (player.reinforcements <= 0) {
      return new Move(Move.Type.END_PHASE);
    }

    List<Region> regions = PlayerUtils.getPlayerRegions(overworld, player, false);

    // choose random region to take action with
    int regionIndex = Utils.random().nextInt(regions.size());
    int regionStartIndex = regionIndex;

    // check if region can take action

    // if region can't be reinforced, check other regions if we force reinforcements
    while (forceReinforcement
        && ((onlyNew && regions.get(regionIndex).unit != null)
            || (regions.get(regionIndex).unit != null
                && regions.get(regionIndex).unit.health == Unit.MAX_HEALTH))) {
      regionIndex++;

      if (regionIndex >= regions.size()) {
        regionIndex = 0;
      }

      // exit loop if we've checked all regions
      if (regionIndex == regionStartIndex) {
        break;
      }
    }

    // reinforce new region
    if (regions.get(regionIndex).unit == null) {
      return new Move(
          Move.Type.REINFORCE,
          regions.get(regionIndex),
          Unit.Type.values()[Utils.random().nextInt(Unit.Type.values().length)]);
    }
    // reinforce existing region
    else if (!onlyNew && regions.get(regionIndex).unit.health < Unit.MAX_HEALTH) {
      return new Move(Move.Type.REINFORCE, regions.get(regionIndex));
    }

    return new Move(Move.Type.END_PHASE);
  }
예제 #2
0
파일: AI.java 프로젝트: slauson/Tactics
  /**
   * Returns random move (attack or move).
   *
   * @param overworld overworld
   * @param player player
   * @param forceAttack true if we want to force an attack if possible
   * @param forceMove true if we want to force a move if possible
   * @param types types of moves allowed (attack or move)
   * @return random move
   */
  protected static Move getRandomMove(
      Overworld overworld,
      Player player,
      boolean forceAttack,
      boolean forceMove,
      Move.Type... types) {

    List<Region> regions = PlayerUtils.getPlayerRegions(overworld, player, false);

    // check possible moves
    boolean allowAttack = false;
    boolean allowMove = false;
    for (Move.Type type : types) {
      switch (type) {
        case ATTACK:
          allowAttack = true;
          break;
        case MOVE:
          allowMove = true;
          break;
      }
    }

    // choose random region to take action with
    int regionIndex = Utils.random().nextInt(regions.size());
    int regionStartIndex = regionIndex;

    // check if region can take action

    // get regions to attack
    List<Region> attackRegions = RegionUtils.getAttacks(regions.get(regionIndex));
    List<Region> moveRegions = RegionUtils.getMoves(regions.get(regionIndex));

    // if region can't attack or move, check other regions if we force an attack or move
    while ((allowAttack && forceAttack && attackRegions.size() == 0)
        || (allowMove && forceMove && moveRegions.size() == 0)) {

      regionIndex++;

      if (regionIndex >= regions.size()) {
        regionIndex = 0;
      }

      // exit loop if we've checked all regions
      if (regionIndex == regionStartIndex) {
        break;
      }

      attackRegions = RegionUtils.getAttacks(regions.get(regionIndex));
      moveRegions = RegionUtils.getMoves(regions.get(regionIndex));
    }

    // region to attack
    if (allowAttack && attackRegions.size() > 0) {
      // choose random region to attack
      Region attackRegion = attackRegions.get(Utils.random().nextInt(attackRegions.size()));

      return new Move(Move.Type.ATTACK, regions.get(regionIndex), attackRegion);
    } else if (allowMove && moveRegions.size() > 0) {
      // choose random region to move to
      Region moveRegion = moveRegions.get(Utils.random().nextInt(moveRegions.size()));

      return new Move(Move.Type.MOVE, regions.get(regionIndex), moveRegion);
    }

    return new Move(Move.Type.END_PHASE);
  }
예제 #3
0
파일: AI.java 프로젝트: slauson/Tactics
  /**
   * Returns collection of reinforcements for given score factor, ordered by descending score.
   *
   * @param overworld
   * @param player
   * @param minScore
   * @param scoreFactor
   * @return
   */
  protected static Collection<Move> getReinforcements(
      Overworld overworld, Player player, ScoreFactor scoreThreshold, ScoreFactor scoreFactor) {

    Map<Float, Move> reinforcements = new TreeMap<Float, Move>();

    // go through each region
    for (Region region : overworld.regions) {
      if (region.player.equals(player)
          && (region.unit == null || region.unit.health < Unit.MAX_HEALTH)) {

        // get optimal reinforcement type for region
        ReinforcementType reinforcementType = getBestReinforcement(region);

        ScoreFactor score = new ScoreFactor();
        float scoreValue = 0;
        boolean aboveThreshold = true;

        // get each score type
        for (ScoreFactor.Type type : ScoreFactor.Type.values()) {
          if (scoreThreshold.usesType(type) || scoreFactor.usesType(type)) {
            switch (type) {
              case BATTLE_STRENGTH_CHANGE:
                score.addFactor(type, reinforcementType.strengthChange);
                break;
              case ISLAND_PERCENTAGE:
                score.addFactor(type, RegionUtils.getIslandPercentage(region.island, player));
                break;
              case ISLAND_STRENGTH:
                score.addFactor(type, RegionUtils.getIslandStrength(region.island, player));
                break;
              case ISLAND_STRENGTH_CHANGE:
                score.addFactor(type, getIslandStrengthChange(region, reinforcementType, player));
                break;
              case RANDOM:
                score.addFactor(type, Utils.random().nextFloat());
                break;
              case BATTLE_LIKELIHOOD:
                // ignore
                break;
            }

            // check if score meets threshold
            if (scoreThreshold.usesType(type)) {
              aboveThreshold &= score.getScore(type) >= scoreThreshold.getScore(type);
            }

            // update score value
            if (scoreFactor.usesType(type)) {
              scoreValue += score.getScore(type) * scoreFactor.getScore(type);
            }
          }
        }

        // score above threshold
        if (aboveThreshold) {
          reinforcements.put(
              scoreValue, new Move(Move.Type.REINFORCE, region, null, reinforcementType.unitType));
          System.out.println(
              String.format(
                  "\tpossible reinforcement %f: %s", scoreValue, reinforcements.get(scoreValue)));
          System.out.println("\t\t" + score);
        }
      }
    }

    return reinforcements.values();
  }
예제 #4
0
파일: AI.java 프로젝트: slauson/Tactics
  /**
   * Returns collection of moves for given score factor, ordered by descending score.
   *
   * @param overworld
   * @param player
   * @param scoreThreshold
   * @param scoreFactor
   * @return
   */
  protected static Collection<Move> getMoves(
      Overworld overworld,
      Player player,
      ScoreFactor scoreThreshold,
      ScoreFactor captureScoreThreshold,
      ScoreFactor scoreFactor) {

    Map<Float, Move> moves = new TreeMap<Float, Move>();

    // go through each region
    for (Region region : overworld.regions) {
      if (region.player.equals(player) && region.unit != null && region.unit.hasMove) {

        // go through each neighbor
        for (Neighbor neighbor : region.neighbors) {
          if (RegionUtils.canMove(region, neighbor)) {

            ScoreFactor score = new ScoreFactor();
            float scoreValue = 0;
            boolean aboveThreshold = true;

            // get each score type
            for (ScoreFactor.Type type : ScoreFactor.Type.values()) {
              if (scoreThreshold.usesType(type) || scoreFactor.usesType(type)) {
                switch (type) {
                  case BATTLE_STRENGTH_CHANGE:
                    score.addFactor(type, getBattleStrengthChange(region, neighbor, true));
                    break;
                  case ISLAND_PERCENTAGE:
                    score.addFactor(type, RegionUtils.getIslandPercentage(region.island, player));
                    break;
                  case ISLAND_STRENGTH:
                    score.addFactor(type, RegionUtils.getIslandStrength(region.island, player));
                    break;
                  case RANDOM:
                    score.addFactor(type, Utils.random().nextFloat());
                    break;
                  case BATTLE_LIKELIHOOD:
                  case ISLAND_STRENGTH_CHANGE:
                    // ignore
                    break;
                }

                // check if score meets threshold
                // capture threshold
                if (!neighbor.region.player.equals(region.player) && neighbor.region.unit == null) {
                  if (captureScoreThreshold.usesType(type)) {
                    aboveThreshold &= score.getScore(type) >= captureScoreThreshold.getScore(type);
                  }
                }
                // regular move threshold
                else {
                  if (scoreThreshold.usesType(type)) {
                    aboveThreshold &= score.getScore(type) >= scoreThreshold.getScore(type);
                  }
                }

                // update score value
                if (scoreFactor.usesType(type)) {
                  scoreValue += score.getScore(type) * scoreFactor.getScore(type);
                }
              }
            }

            // score above threshold
            if (aboveThreshold) {
              moves.put(scoreValue, new Move(Move.Type.MOVE, region, neighbor.region));
              System.out.println(
                  String.format("\tpossible move %f: %s", scoreValue, moves.get(scoreValue)));
              System.out.println("\t\t" + score);
            }
          }
        }
      }
    }

    return moves.values();
  }
예제 #5
0
파일: AI.java 프로젝트: slauson/Tactics
  /**
   * Returns collection of attacks for given score factor, ordered by descending score.
   *
   * @param overworld
   * @param player
   * @param scoreThreshold
   * @param scoreFactor
   * @return
   */
  protected static Collection<Move> getAttacks(
      Overworld overworld, Player player, ScoreFactor scoreThreshold, ScoreFactor scoreFactor) {

    Map<Float, Move> attacks = new TreeMap<Float, Move>();

    // go through each region
    for (Region region : overworld.regions) {
      if (region.player.equals(player) && region.unit != null && region.unit.hasAttack) {

        // check each neighbor
        for (Neighbor neighbor : region.neighbors) {
          if (RegionUtils.canAttack(region, neighbor)) {

            ScoreFactor score = new ScoreFactor();
            float scoreValue = 0;
            boolean aboveThreshold = true;

            // get each score type
            for (ScoreFactor.Type type : ScoreFactor.Type.values()) {
              if (scoreThreshold.usesType(type) || scoreFactor.usesType(type)) {
                switch (type) {
                  case BATTLE_STRENGTH_CHANGE:
                    if (neighbor.type != Neighbor.Type.RANGED) {
                      score.addFactor(type, getBattleStrengthChange(region, neighbor, false));
                    } else {
                      score.addFactor(type, 0.5f);
                    }
                    break;
                  case BATTLE_LIKELIHOOD:
                    score.addFactor(
                        type, BattleUtils.calculateBattleLikelihood(region, neighbor.region));
                    break;
                  case ISLAND_PERCENTAGE:
                    score.addFactor(type, RegionUtils.getIslandPercentage(region.island, player));
                    break;
                  case ISLAND_STRENGTH:
                    score.addFactor(type, RegionUtils.getIslandStrength(region.island, player));
                    break;
                  case RANDOM:
                    score.addFactor(type, Utils.random().nextFloat());
                    break;
                  case ISLAND_STRENGTH_CHANGE:
                    // ignore
                    break;
                }

                // check if score meets threshold
                if (scoreThreshold.usesType(type)) {
                  aboveThreshold &= score.getScore(type) >= scoreThreshold.getScore(type);
                }

                // update score value
                if (scoreFactor.usesType(type)) {
                  scoreValue += score.getScore(type) * scoreFactor.getScore(type);
                }
              }
            }

            // score above threshold
            if (aboveThreshold) {
              attacks.put(scoreValue, new Move(Move.Type.ATTACK, region, neighbor.region));
              System.out.println(
                  String.format("\tpossible attack %f: %s", scoreValue, attacks.get(scoreValue)));
              System.out.println("\t\t" + score);
            }
          }
        }
      }
    }

    return attacks.values();
  }