public ActionComponent addAction(ECSAction action) { this.actions.put(action.getName(), action); return this; }
private boolean isInterestingAction(ECSAction action) { return actionName.equals(action.getName()); }
private void targetableCheck(TargetableCheckEvent event) { if (event.getAction().getName().equals(actionName)) { this.checkTargetable(event); } }
@Override public ECSAction getAction(Entity player) { Stream<ECSAction> actions = Actions.getPossibleActionsFor(player).stream(); Stream<ECSAction> allActions = actions .filter(action -> setTargetIfPossible(action)); List<ECSAction> list = allActions.collect(Collectors.toList()); logger.info(player + " allowed actions: " + list); //return nothing if no actions are available if (list.isEmpty()) { return null; } //Do not scrap if it is the only thing you can do if (list.size() == 1) { for (ECSAction action : list) { if(action.getName().equals("Scrap")) { return null; } } } //parse the actions and return an appropriate one based on the actions available //For example, if there are less than 3 creatures on the board, do not scrap any //If any attacks are available, do those //return a random action from the list return list.get(random.nextInt(list.size())); }
public static ScoreConfigFactory<Entity, ECSAction> loser() { ScoreConfigFactory<Entity, ECSAction> config = new ScoreConfigFactory<>(); config.withScorer(new PredicateScorer<>(action -> action.getName().equals(CyborgChroniclesGame.END_TURN_ACTION))); return config; }
private void allowCheck(ActionAllowedCheckEvent event) { if (!action.equals(event.getAction().getName())) { return; } if (names.contains(name.getOrDefault(event.getEntity(), ""))) { event.setAllowed(false); } }
private ReplayAction(ActionPerformEvent event) { this.entity = event.getEntity().getId(); this.performer = event.getPerformer().getId(); this.actionName = event.getAction().getName(); this.targets = event.getAction().getTargetSets().stream() .map(targetSet -> targetSet.getChosenTargets().stream() .map(e -> e.getId()).collect(Collectors.toList())) .collect(Collectors.toList()); }
public static ScoreConfigFactory<Entity, ECSAction> medium() { ScoreConfigFactory<Entity, ECSAction> config = new ScoreConfigFactory<>(); config.withScorer(new PredicateScorer<>(action -> action.getName().equals(CyborgChroniclesGame.USE_ACTION)), -10); config.withScorer(new PredicateScorer<>(action -> action.getName().equals(CyborgChroniclesGame.PLAY_ACTION)), 10); config.withScorer(new PredicateScorer<>(action -> action.getName().equals(CyborgChroniclesGame.ENCHANT_ACTION)), -10); // this AI does not enchant config.withScorer(new SimpleScorer<Entity, ECSAction>(AttackAnalyze::scrapScore)); config.withScorer(new SimpleScorer<Entity, ECSAction>(AttackAnalyze::attackScore)); return config; }
public static double attackScore(ECSAction action, ScoreParameters<Entity> params) { if (!action.getName().equals(CyborgChroniclesGame.ATTACK_ACTION)) { return 0; } TargetSet targets = action.getTargetSets().get(0); targets.clearTargets(); List<Entity> possibleTargets = targets.findPossibleTargets(); Optional<Entity> player = possibleTargets.stream().filter(e -> e.hasComponent(PlayerComponent.class)).findAny(); if (player.isPresent()) { // attacking a player is really the best option there is targets.addTarget(player.get()); return 100; } if (possibleTargets.isEmpty()) { throw new RuntimeException("Attack action has no targets: " + action); } possibleTargets.sort(Comparator.comparingInt(e -> attackVS(action.getOwner(), e))); Entity chosenTarget = possibleTargets.get(possibleTargets.size() - 1); targets.addTarget(chosenTarget); return attackVS(action.getOwner(), chosenTarget); }
public static double scrapNeeded(ECSAction action, ScoreParameters<Entity> params) { if (!action.getName().equals(CyborgChroniclesGame.SCRAP_ACTION)) { return 0; } Entity entity = action.getOwner(); ComponentRetriever<CardComponent> card = Retrievers.component(CardComponent.class); Entity owner = card.get(entity).getOwner(); HandComponent hand = owner.getComponent(HandComponent.class); return hand.stream().mapToInt(e -> scrapCost.getOrDefault(e, 0)).sum(); }
private void actionAllowed(ActionAllowedCheckEvent event) { if (!event.getAction().getName().equals(ACTION_NAME)) { return; } if (event.getEntity() != event.getPerformer()) { event.setAllowed(false); } if (!PHASE_NAME.equals(phases.getCurrentPhase().getName())) { event.setAllowed(false); } }
public static double scrapScore(ECSAction action, ScoreParameters<Entity> params) { if (!action.getName().equals(CyborgChroniclesGame.SCRAP_ACTION)) { return 0; } Entity entity = action.getOwner(); ComponentRetriever<CardComponent> card = Retrievers.component(CardComponent.class); ZoneComponent battlefield = card.get(entity).getCurrentZone(); List<Entity> creatures = battlefield.getCards(); if (creatures.size() <= 3) { return -health.getFor(entity); } creatures.sort(Comparator.comparingInt(e -> health.getFor(e) + attack.getFor(e))); if (entity == creatures.get(0)) { // Only consider scrapping the creature with lowest health return 4 - health.getFor(entity); } return -1; }
public static double enchantScore(ECSAction action, ScoreParameters<Entity> params) { if (!action.getName().equals(CyborgChroniclesGame.ENCHANT_ACTION)) { return 0; } TargetSet targets = action.getTargetSets().get(0); targets.clearTargets(); List<Entity> possibleTargets = targets.findPossibleTargets(); if (possibleTargets.isEmpty()) { return -1; } Entity enchantment = action.getOwner(); int attackBonus = attack.getFor(enchantment); int healthBonus = health.getFor(enchantment); possibleTargets.sort(Comparator.comparingDouble(e -> enchantScore(e, attackBonus, healthBonus))); Entity chosenTarget = possibleTargets.get(possibleTargets.size() - 1); targets.addTarget(chosenTarget); return enchantScore(chosenTarget, attackBonus, healthBonus); }
public static double scrapIfCanGetKilled(ECSAction action, ScoreParameters<Entity> params) { if (!action.getName().equals(CyborgChroniclesGame.SCRAP_ACTION)) { return 0;
/** * Looks at all Clients, resets their actions, then gets all actions for each and sends them. */ private void sendAvailableActions() { for (ClientIO io : this.getPlayers()) { io.sendToClient(new ResetAvailableActionsMessage()); if (game.isGameOver()) { continue; } Entity player = playerFor(io); getAllActions(game).filter(action -> action.isAllowed(player)) .forEach(action -> io.sendToClient(new UsableActionMessage(action.getOwner().getId(), action.getName(), !action.getTargetSets().isEmpty()))); } }
public static ScoreConfigFactory<Entity, ECSAction> fighter() { ScoreConfigFactory<Entity, ECSAction> config = new ScoreConfigFactory<>(); config.withScorer(Scorers.multiplication(playActionScorer, new SimpleScorer<Entity, ECSAction>(AttackAnalyze::health)), 10); config.withScorer(Scorers.multiplication(playActionScorer, new SimpleScorer<Entity, ECSAction>(AttackAnalyze::attack)), 2); config.withScorer(new PredicateScorer<>(action -> action.getName().equals(CyborgChroniclesGame.USE_ACTION)), -10); config.withScorer(new PredicateScorer<>(action -> action.getName().equals(CyborgChroniclesGame.SCRAP_ACTION)), -1); config.withScorer(Scorers.multiplication(new SimpleScorer<Entity, ECSAction>(AttackAnalyze::scrapNeeded), new SimpleScorer<Entity, ECSAction>(AttackAnalyze::scrapIfCanGetKilled))); // config.withScorer(new SimpleScorer<>(AttackAnalyze::scrapScore)); config.withScorer(new SimpleScorer<Entity, ECSAction>(AttackAnalyze::attackScore)); config.withScorer(new SimpleScorer<Entity, ECSAction>(AttackAnalyze::enchantScore)); return config; }
private void onCardPlayed(ActionPerformEvent event) { if (event.getAction().getName().equals(actionName)) { return; } this.cardsPlayedThisTurn++; if (this.cardsPlayedThisTurn >= limit) { if (actionName == null) { PhaseController phases = Retrievers.singleton(event.getEntity().getGame(), PhaseController.class); phases.nextPhase(); } else { ECSAction action = Actions.getAction(event.getPerformer(), actionName); action.perform(event.getPerformer()); } cardsPlayedThisTurn = 0; } }
@Override public void startGame(ECSGame game) { game.getEvents().registerHandlerBefore(TCGGame.this, ActionPerformEvent.class, action -> { UseAbilityMessage useAbilityMessage = new UseAbilityMessage(getId(), action.getEntity().getId(), action.getAction().getName(), action.getAction().getAllTargets().mapToInt(e -> e.getId()).toArray()); send(useAbilityMessage.withPerformer(action.getPerformer().getId())); }); } });
private void targetAllowed(TargetableCheckEvent event) { if (!event.getAction().getName().equals(ACTION_NAME)) { return; } if (!event.getTarget().hasComponent(CardComponent.class)) { event.setAllowed(false); return; } if (!Cards.isOnZone(event.getTarget(), HandComponent.class)) { event.setAllowed(false); } if (!Cards.isOwnedBy(event.getTarget(), event.getAction().getOwner())) { event.setAllowed(false); } }