package com.cardshifter.ai;
import java.util.Collection;
import java.util.Random;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.zomis.aiscores.FieldScoreProducer;
import net.zomis.aiscores.FieldScores;
import net.zomis.aiscores.ScoreConfig;
import net.zomis.aiscores.ScoreConfigFactory;
import net.zomis.aiscores.ScoreParameters;
import net.zomis.aiscores.ScoreStrategy;
import net.zomis.aiscores.extra.ParamAndField;
import net.zomis.aiscores.extra.ScoreUtils;
import net.zomis.cardshifter.ecs.config.ConfigComponent;
import com.cardshifter.modapi.actions.ActionComponent;
import com.cardshifter.modapi.actions.ECSAction;
import com.cardshifter.modapi.ai.CardshifterAI;
import com.cardshifter.modapi.base.ECSGame;
import com.cardshifter.modapi.base.Entity;
public class ScoringAI implements CardshifterAI, ScoreStrategy<Entity, ECSAction> {
private final Random random = new Random(42);
private final ScoreConfig<Entity, ECSAction> config;
private final BiConsumer<Entity, ConfigComponent> entityConfigurer;
public ScoringAI(ScoreConfigFactory<Entity, ECSAction> config, BiConsumer<Entity, ConfigComponent> configuration) {
this.config = config.build();
this.entityConfigurer = configuration;
}
public ScoringAI(ScoreConfigFactory<Entity, ECSAction> config) {
this.config = config.build();
this.entityConfigurer = (e, comp) -> {};
}
public FieldScores<Entity, ECSAction> calculateFullScore(Entity player) {
FieldScoreProducer<Entity, ECSAction> prod = new FieldScoreProducer<Entity, ECSAction>(config, this);
prod.setDetailed(true);
return prod.analyzeAndScore(player);
}
@Override
public ECSAction getAction(Entity player) {
FieldScoreProducer<Entity, ECSAction> prod = new FieldScoreProducer<Entity, ECSAction>(config, this);
ParamAndField<Entity, ECSAction> best = ScoreUtils.pickBest(prod, player, random);
if (best != null) {
return best.getField();
}
return null;
}
@Override
public boolean canScoreField(ScoreParameters<Entity> params, ECSAction action) {
return action.isAllowed(params.getParameters());
}
@Override
public Collection<ECSAction> getFieldsToScore(Entity entity) {
return getAllActions(entity.getGame()).collect(Collectors.toList());
}
private static Stream<ECSAction> getAllActions(ECSGame game) {
return game.getEntitiesWithComponent(ActionComponent.class)
.stream()
.flatMap(entity -> entity.getComponent(ActionComponent.class)
.getECSActions().stream());
}
@Override
public void configure(Entity entity, ConfigComponent config) {
this.entityConfigurer.accept(entity, config);
}
}