101 lines
3.2 KiB
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());
|
|
}
|
|
}
|