Class Caspar

All Implemented Interfaces:
IClient

public class Caspar extends Princess
The CASPAR bot: the experimental successor to Princess. It shares Princess's entire network/phase/state plumbing; experimental behavior is added by overriding Princess's wiring seams (for example initializePathRankers() and initializeFireControls()) so that each divergence can be compared against Princess head-to-head.

Current divergences from Princess:

  • Mutual Support movement doctrine (MutualSupportPathRanker): supporting-range cohesion instead of center-of-mass herding, a cover bonus for advancing inside a set friend's engagement envelope, and a uniform closing tempo so slow and fast elements commit together.
  • Mutual Support deployment (MutualSupportDeployment): a force comes onto the board as a formation instead of scattering across its whole deployment zone.
  • Atmospheric aerospace doctrine (AerospacePathRanker, AerospaceFireControl, AeroGroundDoctrinePathFinder): altitude becomes something the bot chooses rather than a constant, air-to-air dead zones are respected in both movement and gunnery, and enemy fighters that have already moved are told apart from those that have not.
  • Aerospace move order: fighters whose engagement geometry is already settled move before those still waiting on an opponent, and an element's lead moves ahead of its wingmen.
  • Constructor Details

    • Caspar

      public Caspar(String name, String host, int port)
      Creates a new CASPAR bot with the given display name, configured for the given host and port.
      Parameters:
      name - The display name
      host - The host address to which to connect
      port - The port on the host where to connect
  • Method Details

    • getAIType

      public AIType getAIType()
      Description copied from class: BotClient
      Which AI implementation this bot is. Reported to the server alongside the bot's settings so a savegame remembers what kind of bot held each seat, and shown by the bot config dialog so it tells the truth about a running bot instead of assuming Princess. Subclasses that are their own AI type override this.
      Overrides:
      getAIType in class BotClient
      Returns:
      this bot's AIType
    • initializePathRankers

      public void initializePathRankers()
      Description copied from class: Princess
      Initialize the possible path rankers. Has a dependency on the fire controls being initialized.
      Overrides:
      initializePathRankers in class Princess
    • initializeFireControls

      public void initializeFireControls()
      Description copied from class: Princess
      Initialize the fire controls.
      Overrides:
      initializeFireControls in class Princess
    • aeroGroundPathFinder

      protected AeroGroundPathFinder aeroGroundPathFinder(Game game)
      CASPAR divergence: generate ground-mapsheet aerospace paths at more than one altitude, so the ranker has an altitude to choose rather than inheriting a constant.
      Overrides:
      aeroGroundPathFinder in class Princess
      Parameters:
      game - the current game
      Returns:
      the path finder to enumerate ground-mapsheet aerospace movement with
    • continueMovementFor

      protected MovePath continueMovementFor(Entity entity)
      CASPAR divergence: a grounded aerospace unit tries to get back in the air. The engine has always supported both takeoff types; no bot has ever asked for one - a crashed fighter sat as terrain for 33 rounds in the game that motivated this. Runway first when the strip is clear (nothing to roll), vertical liftoff when boxed in and the roll clears the stunt floor, ground turret otherwise. A crippled-but-flyable fighter taking off IS its forced withdrawal: once airborne, the Winchester and fallback doctrines fly it off the board.
      Overrides:
      continueMovementFor in class Princess
      Parameters:
      entity - The entity who is to move.
      Returns:
      The calculated move path.
    • calculateMoveIndex

      protected double calculateMoveIndex(Entity entity, StringBuilder msg)
      Moves the fighters whose engagement is already decided before the ones still waiting to find out.

      Aerospace units move last and in their own turn class, interleaved between players, so partway through that block some enemy fighters have committed to an altitude this turn and some have not. A fighter facing opponents who have committed can pick an altitude that guarantees an engagement; one facing opponents still to move can only guess. Spending the earlier turn slots on the decided fighters leaves the undecided ones later, by which time more of the enemy has committed.

      Within a force, the heaviest fighter goes first and its wingmen follow, so an element always keeps something back that can react to whatever its lead flushes out (the move-order habit described in the aerospace primer, chapter 10.4).

      Overrides:
      calculateMoveIndex in class Princess
      Parameters:
      entity - The unit to be indexed.
      Returns:
      The movement index of this unit. May be positive or negative. Higher index values should move first.
    • prioritizeDeploymentCoords

      protected List<Coords> prioritizeDeploymentCoords(Entity deployedUnit, List<Coords> possibleDeployCoords)
      Description copied from class: Princess
      Orders the candidate deployment hexes that Princess.rankDeploymentCoords(Entity, List) will scan.

      This matters more than it looks. The candidate list arrives shuffled, and the scan below stops after roughly twenty entries, so whatever sits at the front of this list is very nearly the whole choice. Princess returns it unchanged: each unit is placed on terrain merit alone, with no regard for where the rest of the force went.

      Overrides:
      prioritizeDeploymentCoords in class Princess
      Parameters:
      deployedUnit - the unit being placed
      possibleDeployCoords - legal deployment hexes
      Returns:
      the hexes to scan, in the order to scan them