package uulm.teamname.marvelous.gamelibrary.ai; import uulm.teamname.marvelous.gamelibrary.config.CharacterConfig; import uulm.teamname.marvelous.gamelibrary.config.PartyConfig; import uulm.teamname.marvelous.gamelibrary.config.ScenarioConfig; import uulm.teamname.marvelous.gamelibrary.entities.Character; import uulm.teamname.marvelous.gamelibrary.entities.EntityID; import uulm.teamname.marvelous.gamelibrary.entities.EntityType; import uulm.teamname.marvelous.gamelibrary.gamelogic.GameStateView; import uulm.teamname.marvelous.gamelibrary.requests.Request; import uulm.teamname.marvelous.gamelibrary.requests.RequestBuilder; import uulm.teamname.marvelous.gamelibrary.requests.RequestType; import java.util.ArrayList; /** Represents an AI instance for calculations. */ class AI { /** The {@link GameStateView} the AI is playing on. */ private final GameStateView state; /** The Player the AI is playing for. */ private final EntityType player; /** The config data. */ private final PartyConfig partyConfig; private final CharacterConfig characterConfig; private final ScenarioConfig scenarioConfig; /** Constructs a new {@link AI} playing the given player based on the given config values. */ public AI(GameStateView state, EntityType player, PartyConfig partyConfig, CharacterConfig characterConfig, ScenarioConfig scenarioConfig) { this.state = state; this.player = player; this.partyConfig = partyConfig; this.characterConfig = characterConfig; this.scenarioConfig = scenarioConfig; } /** * Calculates the appropriate actions for a turn of any of the characters the AI is playing for. * @param turn The {@link EntityID} that currently has the turn * @return A list of {@link Request Requests} with the actions the AI wants to perform */ public ArrayList performTurn(EntityID turn) { System.out.println("[AI] Handling Character " + turn + " for Player " + player + ":"); ArrayList result = new ArrayList<>(); Character character = (Character)state.getEntities().findEntity(turn); Board board = Board.generate(state, player); Action action = board.analyze(character.getPosition(), player, partyConfig, characterConfig, scenarioConfig); switch(action.type) { case None -> { System.out.println(" Result: doing nothing"); } case Move -> { System.out.println(" Result: moving to " + action.target); result.add(new RequestBuilder(RequestType.MoveRequest) .withOriginEntity(turn) .withOriginField(character.getPosition()) .withTargetField(action.target) .buildCharacterRequest()); } case MeleeAttack -> { System.out.println(" Result: melee attacking " + action.targetEntity); Character target = (Character)state.getEntities().findEntity(action.targetEntity); if(target != null) { result.add(new RequestBuilder(RequestType.MeleeAttackRequest) .withOriginEntity(turn) .withTargetEntity(action.targetEntity) .withOriginField(character.getPosition()) .withTargetField(action.target) .withValue(character.meleeDamage) .buildCharacterRequest()); } } case RangedAttack -> { System.out.println(" Result: ranged attacking " + action.targetEntity); Character target = (Character)state.getEntities().findEntity(action.targetEntity); if(target != null) { result.add(new RequestBuilder(RequestType.RangedAttackRequest) .withOriginEntity(turn) .withTargetEntity(action.targetEntity) .withOriginField(character.getPosition()) .withTargetField(action.target) .withValue(character.rangedDamage) .buildCharacterRequest()); } } case UseStone -> { switch(action.stone) { case SpaceStone -> { System.out.println(" Result: using space stone to " + action.target); result.add(new RequestBuilder(RequestType.UseInfinityStoneRequest) .withOriginEntity(turn) .withOriginField(character.getPosition()) .withTargetField(action.target) .withStoneType(action.stone) .buildCharacterRequest()); } case MindStone -> { System.out.println(" Result: using mind stone to " + action.target); result.add(new RequestBuilder(RequestType.UseInfinityStoneRequest) .withOriginEntity(turn) .withOriginField(character.getPosition()) .withTargetField(action.target) .withValue(partyConfig.mindStoneDMG) .withStoneType(action.stone) .buildCharacterRequest()); } case RealityStone -> { System.out.println(" Result: using reality stone at " + action.target); result.add(new RequestBuilder(RequestType.UseInfinityStoneRequest) .withOriginEntity(turn) .withTargetEntity(action.targetEntity) .withOriginField(character.getPosition()) .withTargetField(action.target) .withStoneType(action.stone) .buildCharacterRequest()); } case PowerStone -> { System.out.println(" Result: using power stone against " + action.targetEntity); result.add(new RequestBuilder(RequestType.UseInfinityStoneRequest) .withOriginEntity(turn) .withTargetEntity(action.targetEntity) .withOriginField(character.getPosition()) .withTargetField(action.target) .withValue(character.rangedDamage * 2) .withStoneType(action.stone) .buildCharacterRequest()); } case TimeStone -> { System.out.println(" Result: using time stone"); result.add(new RequestBuilder(RequestType.UseInfinityStoneRequest) .withOriginEntity(turn) .withOriginField(character.getPosition()) .withStoneType(action.stone) .buildCharacterRequest()); } case SoulStone -> { System.out.println(" Result: using soul stone on " + action.targetEntity); result.add(new RequestBuilder(RequestType.UseInfinityStoneRequest) .withOriginEntity(turn) .withTargetEntity(action.targetEntity) .withOriginField(character.getPosition()) .withTargetField(action.target) .withStoneType(action.stone) .buildCharacterRequest()); } } } case GiveStone -> { System.out.println(" Result: giving stone to " + action.targetEntity); Character target = (Character)state.getEntities().findEntity(action.targetEntity); if(target != null) { result.add(new RequestBuilder(RequestType.ExchangeInfinityStoneRequest) .withOriginEntity(turn) .withTargetEntity(action.targetEntity) .withOriginField(character.getPosition()) .withTargetField(action.target) .withStoneType(action.stone) .buildCharacterRequest()); } } } result.add(new RequestBuilder(RequestType.EndRoundRequest) .buildGameRequest()); return result; } }