magarena/src/magic/ai/VegasAI.java

101 lines
3.2 KiB
Java

package magic.ai;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import magic.model.MagicGame;
import magic.model.MagicGameLog;
import magic.model.MagicPlayer;
import magic.model.event.MagicEvent;
public class VegasAI extends MagicAI {
private static final long SEC_TO_NANO=1000000000L;
private final boolean CHEAT;
VegasAI(final boolean cheat) {
CHEAT = cheat;
}
private void log(final String message) {
MagicGameLog.log(message);
}
@Override
public Object[] findNextEventChoiceResults(final MagicGame sourceGame,final MagicPlayer scorePlayer) {
final long startTime = System.currentTimeMillis();
final MagicGame choiceGame=new MagicGame(sourceGame,scorePlayer);
if (!CHEAT) {
choiceGame.hideHiddenCards();
}
final MagicEvent event=choiceGame.getNextEvent();
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(choiceGame);
// No choices
final int size=choiceResultsList.size();
if (size==0) {
throw new RuntimeException("No choice results");
}
// Single choice
if (size==1) {
return sourceGame.map(choiceResultsList.get(0));
}
// Multiple choices
final ExecutorService executor = Executors.newFixedThreadPool(getMaxThreads());
final List<VegasScore> scores= new ArrayList<>();
final int artificialLevel = scorePlayer.getAiProfile().getAiLevel();
final int rounds = (size + getMaxThreads() - 1) / getMaxThreads();
final long slice = artificialLevel * SEC_TO_NANO / rounds;
for (final Object[] choiceResults : choiceResultsList) {
final VegasScore score=new VegasScore(choiceResults);
scores.add(score);
executor.execute(new VegasWorker(
CHEAT,
choiceGame,
score,
slice
));
}
executor.shutdown();
try { //await termination
executor.awaitTermination(artificialLevel + 1,TimeUnit.SECONDS);
} catch (final InterruptedException ex) {
throw new RuntimeException(ex);
} finally {
// force termination of workers
executor.shutdownNow();
}
// Return best choice
VegasScore bestScore=scores.get(0);
for (final VegasScore score : scores) {
if (score.getScore() > bestScore.getScore()) {
bestScore = score;
}
}
// Logging.
final long timeTaken = System.currentTimeMillis() - startTime;
log("VEGAS" +
" cheat=" + CHEAT +
" index=" + scorePlayer.getIndex() +
" life=" + scorePlayer.getLife() +
" phase=" + sourceGame.getPhase().getType() +
" slice=" + (slice/1000000) +
" time=" + timeTaken
);
for (final VegasScore score : scores) {
log((score == bestScore ? "* " : " ") + score);
}
return sourceGame.map(bestScore.getChoiceResults());
}
}