Files
BH2023-Minesweeper/info/Minesweeper/MinesweeperBulk/src/minesweeperbulk/MinesweeperBulk.java
2023-09-28 20:23:18 +08:00

196 lines
7.6 KiB
Java

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package minesweeperbulk;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import minesweeper.settings.GameSettings;
import minesweeper.settings.GameType;
import minesweeper.solver.bulk.BulkEvent;
import minesweeper.solver.bulk.BulkListener;
import minesweeper.solver.bulk.BulkPlayer;
import minesweeper.solver.bulk.GamePostListener;
import minesweeper.solver.settings.PlayStyle;
import minesweeper.solver.settings.SettingsFactory;
import minesweeper.solver.settings.SettingsFactory.Setting;
import minesweeper.solver.settings.SolverSettings;
import minesweeper.solver.utility.Timer;
import minesweeper.structure.Action;
import minesweeper.structure.Location;
/**
*
* @author David
*/
public class MinesweeperBulk {
private static final DecimalFormat MASK = new DecimalFormat("#0.000");
private static final DecimalFormat MASK5DP = new DecimalFormat("#0.000000");
public static void main(String[] args) {
// pick a random seed or override with a previously used seed to play the same sequence of games again.
long seed = (new Random()).nextInt();
seed = 1449234571;
//seed = 662429271; // expert 10,000,000 run
System.out.println("Seed is " + seed);
Random seeder = new Random(seed);
GameSettings gameSettings = GameSettings.EXPERT;
//GameSettings gameSettings = GameSettings.create(100, 100, 2400);
SolverSettings settings = SettingsFactory.GetSettings(Setting.SMALL_ANALYSIS);
settings.setSingleThread(true);
//settings.setStartLocation(new Location(15,7));
//settings.set5050Check(false);
//settings.setTieBreak(false);
//settings.setTestMode(true);
//settings.setLongTermSafety(false);
//settings.setProgressContribution(new BigDecimal("0.02"));
final long bulkSeed = seed;
BulkPlayer controller = new BulkPlayer(seeder, 100000, GameType.STANDARD, gameSettings, settings, 10, 10000);
controller.setPlayStyle(PlayStyle.NO_FLAG);
// this is executed before the game is passed to the solver
//controller.registerPreGameListener(new StartStrategyResign(middle4CornerStart(gameSettings), 5));
//controller.registerPreGameListener(new StartStrategy(fourCornerStart(gameSettings), 5));
//RandomGuesser random = new RandomGuesser(gameSettings);
//controller.registerPreGameListener(random);
//EfficiencyMonitor monitor = new EfficiencyMonitor(140);
GamePostListener monitor = new GuessMonitor();
controller.registerPostGameListener(monitor);
controller.registerEventListener(new BulkListener() {
@Override
public void intervalAction(BulkEvent event) {
//double p = (double) event.getGamesWon() / (double) event.getGamesPlayed();
double p = event.getTotalGamesValue().doubleValue() / (double) event.getGamesPlayed();
double err = Math.sqrt(p * ( 1- p) / (double) event.getGamesPlayed()) * 1.9599d;
System.out.println("Seed: " + bulkSeed + ", Played " + event.getGamesPlayed() + " of " + event.getGamesToPlay() + ", failed to start " + event.getFailedToStart() + ", won " + event.getTotalGamesValue().setScale(4, RoundingMode.HALF_UP) +
", without guessing " + event.getNoGuessWins() + ", guesses " + event.getTotalGuesses() + ", actions " + event.getTotalActions() + ", solved 3BV " + event.getTotal3BVSolved() +
", fairness " + MASK5DP.format(event.getFairness()) + ", win streak " + event.getWinStreak() + ", mastery " + event.getMastery() +
", win percentage " + MASK.format(p * 100) + " +/- " + MASK.format(err * 100) + ", Time left " + Timer.humanReadable(event.getEstimatedTimeLeft()) );
}
});
controller.run();
// 4394503940621334 3495601381446703 2878438628482118
// 3bv 5 ==> 3507948847220847 2378685257559362 732083917567661 3393825076821824 1423288336267551
{
BulkEvent event = controller.getResults();
double p = (double) event.getGamesWon() / (double) event.getGamesPlayed();
double err = Math.sqrt(p * ( 1- p) / (double) event.getGamesPlayed()) * 1.9599d;
int apw;
if (event.getGamesWon() != 0) {
apw = event.getTotalActions() / event.getGamesWon();
} else {
apw = 0;
}
double bpw;
if (event.getGamesWon() != 0) {
bpw = (double) event.getTotal3BVSolved() / (double) event.getGamesWon();
} else {
bpw = 0;
}
double average3BV = (double) event.getTotal3BV() / (double) event.getGamesPlayed();
System.out.println("Seed: " + bulkSeed + " ==> Board " + gameSettings + " ==> Played " + event.getGamesPlayed() + ", failed to start " + event.getFailedToStart() + ", won " + event.getGamesWon() +
", without guessing " + event.getNoGuessWins() + ", guesses " + event.getTotalGuesses() + ", actions " + event.getTotalActions() + ", apw " + apw +
", avg 3BV " + MASK.format(average3BV) + ", Solved 3BV/win " + MASK.format(bpw) +
", fairness " + MASK5DP.format(event.getFairness()) + ", win streak " + event.getWinStreak() + ", mastery " + event.getMastery() +
", win percentage " + MASK.format(p * 100) + " +/- " + MASK.format(err * 100) + ", Duration " + Timer.humanReadable(event.getTimeSoFar()) );
}
monitor.postResults();
//random.displayTable();
}
static private List<Action> twoCornerStart(GameSettings gameSettings) {
List<Action> preactions = new ArrayList<>();
preactions.add(new Action(0, 0, Action.CLEAR));
preactions.add(new Action(0, gameSettings.height - 1, Action.CLEAR));
//preactions.add(new Action(gameSettings.width - 1, 0, Action.CLEAR));
//preactions.add(new Action(gameSettings.width - 1, gameSettings.height - 1, Action.CLEAR));
return preactions;
}
static private List<Action> threeCornerStart(GameSettings gameSettings) {
List<Action> preactions = new ArrayList<>();
preactions.add(new Action(0, 0, Action.CLEAR));
preactions.add(new Action(0, gameSettings.height - 1, Action.CLEAR));
preactions.add(new Action(gameSettings.width - 1, 0, Action.CLEAR));
//preactions.add(new Action(gameSettings.width - 1, gameSettings.height - 1, Action.CLEAR));
return preactions;
}
static private List<Action> fourCornerStart(GameSettings gameSettings) {
List<Action> preactions = new ArrayList<>();
preactions.add(new Action(0, 0, Action.CLEAR));
preactions.add(new Action(0, gameSettings.height - 1, Action.CLEAR));
preactions.add(new Action(gameSettings.width - 1, 0, Action.CLEAR));
preactions.add(new Action(gameSettings.width - 1, gameSettings.height - 1, Action.CLEAR));
return preactions;
}
static private List<Action> middle4CornerStart(GameSettings gameSettings) {
List<Action> preactions = new ArrayList<>();
preactions.add(new Action(gameSettings.width / 2, gameSettings.height / 2, Action.CLEAR));
preactions.add(new Action(0, 0, Action.CLEAR));
preactions.add(new Action(0, gameSettings.height - 1, Action.CLEAR));
preactions.add(new Action(gameSettings.width - 1, 0, Action.CLEAR));
preactions.add(new Action(gameSettings.width - 1, gameSettings.height - 1, Action.CLEAR));
return preactions;
}
static private List<Action> flagClickChord(GameSettings gameSettings) {
List<Action> preactions = new ArrayList<>();
preactions.add(new Action(1, 3, Action.FLAG));
preactions.add(new Action(1, 2, Action.CLEAR));
preactions.add(new Action(1, 2, Action.CLEARALL));
preactions.add(new Action(1, 3, Action.FLAG));
return preactions;
}
}