rename references
This commit is contained in:
7
references/Minesweeper/MinesweeperBulk/.classpath
Normal file
7
references/Minesweeper/MinesweeperBulk/.classpath
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/MineSweeperSolver"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
1
references/Minesweeper/MinesweeperBulk/.gitignore
vendored
Normal file
1
references/Minesweeper/MinesweeperBulk/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/bin/
|
23
references/Minesweeper/MinesweeperBulk/.project
Normal file
23
references/Minesweeper/MinesweeperBulk/.project
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>MinesweeperBulk</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
@ -0,0 +1,79 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.solver.bulk.BulkRequest;
|
||||
import minesweeper.solver.bulk.GamePostListener;
|
||||
|
||||
public class EfficiencyMonitor extends GamePostListener {
|
||||
|
||||
private final Map<Integer, Integer> table = new HashMap<>();
|
||||
private int eff100 = 0;
|
||||
private int wins = 0;
|
||||
private int played = 0;
|
||||
private int announcementCount = 0;
|
||||
private int clicks = 0;
|
||||
|
||||
private final double reportThreshold;
|
||||
|
||||
public EfficiencyMonitor(double reportThreshold) {
|
||||
this.reportThreshold = reportThreshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postAction(BulkRequest request) {
|
||||
|
||||
GameStateModel game = request.getGame();
|
||||
|
||||
played++;
|
||||
clicks = clicks + game.getActionCount();
|
||||
|
||||
if (game.getGameState() == GameStateModel.WON) {
|
||||
wins++;
|
||||
double efficiency = 100 * ((double) game.getTotal3BV() / (double) game.getActionCount());
|
||||
if (efficiency >= reportThreshold) {
|
||||
announcementCount++;
|
||||
System.out.println(announcementCount + ") " + game.getSeed() + " has 3BV " + game.getTotal3BV() + " efficiency " + efficiency);
|
||||
}
|
||||
|
||||
int inteff = (int) Math.floor(efficiency);
|
||||
if (inteff >= 100) {
|
||||
eff100++;
|
||||
}
|
||||
|
||||
if (inteff >= 0) {
|
||||
if (table.containsKey(inteff)) {
|
||||
int tally = table.get(inteff);
|
||||
tally++;
|
||||
table.put(inteff, tally);
|
||||
} else {
|
||||
table.put(inteff, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void postResults() {
|
||||
|
||||
int clicksPerEff100 = 0;
|
||||
if (eff100 > 0) {
|
||||
clicksPerEff100 = clicks / eff100;
|
||||
}
|
||||
|
||||
System.out.println("Efficiency >= 100% : " + eff100 + " from " + wins + " wins out of " + played + " played, clicks " + clicks + ", clicks/eff100 " + clicksPerEff100);
|
||||
|
||||
List<Integer> results = new ArrayList<>(table.keySet());
|
||||
results.sort(null);
|
||||
|
||||
for (int key: results) {
|
||||
System.out.println("Efficiency " + key + " occurs " + table.get(key));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.solver.bulk.BulkRequest;
|
||||
import minesweeper.solver.bulk.GamePostListener;
|
||||
|
||||
public class GuessMonitor extends GamePostListener {
|
||||
|
||||
private static final DecimalFormat MASK = new DecimalFormat("#0.000");
|
||||
|
||||
private class GuessData {
|
||||
private int total;
|
||||
private int sum3BV;
|
||||
private int[] values = new int[9];
|
||||
}
|
||||
|
||||
private final Map<Integer, GuessData> winTable = new HashMap<>();
|
||||
private final Map<Integer, GuessData> loseTable = new HashMap<>();
|
||||
private int wins = 0;
|
||||
private int played = 0;
|
||||
private int eights = 0;
|
||||
private int ng8 = 0;
|
||||
|
||||
@Override
|
||||
public void postAction(BulkRequest request) {
|
||||
|
||||
GameStateModel game = request.getGame();
|
||||
|
||||
played++;
|
||||
|
||||
Map<Integer, GuessData> table;
|
||||
|
||||
if (game.getGameState() == GameStateModel.WON) {
|
||||
table = winTable;
|
||||
wins++;
|
||||
} else {
|
||||
table = loseTable;
|
||||
}
|
||||
|
||||
int guesses = request.getGuesses();
|
||||
|
||||
eights = eights + request.getGame().getValueCount(8);
|
||||
if (request.getGame().getGameState() == GameStateModel.WON && request.getGuesses() == 0) {
|
||||
ng8 = ng8 + + request.getGame().getValueCount(8);
|
||||
}
|
||||
|
||||
if (table.containsKey(guesses)) {
|
||||
GuessData gd = table.get(guesses);
|
||||
gd.total++;
|
||||
gd.sum3BV = gd.sum3BV + request.getGame().getTotal3BV();
|
||||
|
||||
for (int i=0; i < gd.values.length; i++) {
|
||||
gd.values[i] += request.getGame().getValueCount(i);
|
||||
}
|
||||
|
||||
table.put(guesses, gd);
|
||||
} else {
|
||||
GuessData gd = new GuessData();
|
||||
gd.total = 1;
|
||||
gd.sum3BV = request.getGame().getTotal3BV();
|
||||
table.put(guesses, gd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postResults() {
|
||||
|
||||
System.out.println(wins + " wins out of " + played + " played");
|
||||
System.out.println(eights + " Eights, of which " + ng8 + " in no-guess games");
|
||||
|
||||
List<Integer> winResults = new ArrayList<>(winTable.keySet());
|
||||
winResults.sort(null);
|
||||
|
||||
int winWeight = 0;
|
||||
|
||||
System.out.println("Histogram of guesses to win");
|
||||
for (int key: winResults) {
|
||||
GuessData gd = winTable.get(key);
|
||||
double avg3BV = (double) gd.sum3BV / (double) gd.total;
|
||||
|
||||
System.out.println("guesses " + key + " occurs " + gd.total + " average 3bv " + MASK.format(avg3BV) + " number of 8's " + gd.values[8]);
|
||||
|
||||
winWeight = winWeight + gd.total * key;
|
||||
}
|
||||
if (wins != 0) {
|
||||
double avgGuessesToWin = (double) winWeight / (double) wins;
|
||||
System.out.println("Average guesses to win " + MASK.format(avgGuessesToWin));
|
||||
}
|
||||
|
||||
|
||||
List<Integer> loseResults = new ArrayList<>(loseTable.keySet());
|
||||
loseResults.sort(null);
|
||||
|
||||
int loseWeight = 0;
|
||||
|
||||
System.out.println("Histogram of guesses to lose");
|
||||
for (int key: loseResults) {
|
||||
GuessData gd = loseTable.get(key);
|
||||
double avg3BV = (double) gd.sum3BV / (double) gd.total;
|
||||
|
||||
System.out.println("guesses " + key + " occurs " + gd.total + " average 3bv " + MASK.format(avg3BV) + " number of 8's " + gd.values[8]);
|
||||
|
||||
loseWeight = loseWeight + gd.total * key;
|
||||
}
|
||||
if (wins != 0) {
|
||||
double avgGuessesToLose = (double) loseWeight / (double) (played - wins) ;
|
||||
System.out.println("Average guesses to lose " + MASK.format(avgGuessesToLose));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.solver.bulk.GamePreListener;
|
||||
import minesweeper.structure.Action;
|
||||
|
||||
public class PreActions extends GamePreListener {
|
||||
|
||||
private List<Action> preActions;
|
||||
|
||||
public PreActions(List<Action> preActions) {
|
||||
this.preActions = preActions;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void preAction(GameStateModel game) {
|
||||
|
||||
for (Action a: preActions) {
|
||||
game.doAction(a);
|
||||
if (game.getGameState() == GameStateModel.LOST || game.getGameState() == GameStateModel.WON) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.settings.GameSettings;
|
||||
import minesweeper.solver.bulk.GamePreListener;
|
||||
import minesweeper.structure.Action;
|
||||
|
||||
public class RandomGuesser extends GamePreListener {
|
||||
|
||||
final private GameSettings settings;
|
||||
final private int border = 1;
|
||||
|
||||
final List<Action> interior = new ArrayList<>();
|
||||
final Action[][] board;
|
||||
|
||||
private int eights = 0;
|
||||
private int clicks = 0;
|
||||
private int played = 0;
|
||||
|
||||
public RandomGuesser(GameSettings settings) {
|
||||
|
||||
this.settings = settings;
|
||||
|
||||
board = new Action[settings.width][settings.height];
|
||||
|
||||
for (int i=border; i < settings.width - border; i++) {
|
||||
for (int j=border; j < settings.height - border; j++) {
|
||||
Action a = new Action(i,j, Action.CLEAR);
|
||||
interior.add(a);
|
||||
board[i][j] = a;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void preAction(GameStateModel game) {
|
||||
|
||||
played++;
|
||||
|
||||
// tiles we can guess shuffled
|
||||
List<Action> available = new ArrayList<>(interior);
|
||||
Collections.shuffle(available);
|
||||
|
||||
boolean[][] processed = new boolean[settings.width][settings.height];
|
||||
|
||||
// first guess
|
||||
Action guess = available.get(0);
|
||||
|
||||
// while we have moves and the game hasn't blasted
|
||||
while (true) {
|
||||
|
||||
clicks++;
|
||||
game.doAction(guess);
|
||||
|
||||
// if we've lost stop
|
||||
if (game.getGameState() == GameStateModel.LOST) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (game.query(guess) == 8) {
|
||||
eights++;
|
||||
}
|
||||
|
||||
// remove guesses near cleared tiles
|
||||
for (int i=border; i < settings.width - border; i++) {
|
||||
for (int j=border; j < settings.height - border; j++) {
|
||||
if (!processed[i][j]) {
|
||||
if (game.query(board[i][j]) != GameStateModel.HIDDEN) {
|
||||
|
||||
//System.out.println(i + " " + j + " is not hidden");
|
||||
|
||||
processed[i][j] = true;
|
||||
|
||||
int offset;
|
||||
if (game.query(guess) < 3) {
|
||||
offset = 2;
|
||||
} else {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
// remove tiles adjacent to an open area
|
||||
Iterator<Action> iterator = available.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Action a = iterator.next();
|
||||
if (distance(a.x, a.y, i, j) <= offset) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (available.isEmpty()) {
|
||||
//System.out.println("No guesses left");
|
||||
break;
|
||||
}
|
||||
|
||||
// next guess
|
||||
guess = available.get(0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int distance(int x1, int y1, int x2, int y2) {
|
||||
|
||||
int dx = Math.abs(x1 - x2);
|
||||
int dy = Math.abs(y1 - y2);
|
||||
|
||||
return Math.max(dx, dy);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void displayTable() {
|
||||
|
||||
System.out.println(eights + " eights out of " + played + " played and " + clicks + " clicks");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.solver.bulk.BulkRequest;
|
||||
import minesweeper.solver.bulk.GamePostListener;
|
||||
|
||||
public class RemainingMonitor extends GamePostListener {
|
||||
|
||||
private final Map<Integer, Integer> table = new HashMap<>();
|
||||
private int wins = 0;
|
||||
private int played = 0;
|
||||
|
||||
@Override
|
||||
public void postAction(BulkRequest request) {
|
||||
|
||||
GameStateModel game = request.getGame();
|
||||
|
||||
played++;
|
||||
|
||||
if (game.getGameState() == GameStateModel.WON) {
|
||||
wins++;
|
||||
}
|
||||
|
||||
int bbvLeft = game.getTotal3BV() - game.getCleared3BV();
|
||||
int tilesLeft = game.getHidden() - game.getMines();
|
||||
|
||||
if (table.containsKey(tilesLeft)) {
|
||||
int tally = table.get(tilesLeft);
|
||||
tally++;
|
||||
table.put(tilesLeft, tally);
|
||||
} else {
|
||||
table.put(tilesLeft, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void postResults() {
|
||||
|
||||
System.out.println(wins + " wins out of " + played + " played");
|
||||
|
||||
List<Integer> results = new ArrayList<>(table.keySet());
|
||||
results.sort(null);
|
||||
|
||||
for (int key: results) {
|
||||
System.out.println("Tiles left to clear " + key + " occurs " + table.get(key));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.solver.bulk.GamePreListener;
|
||||
import minesweeper.structure.Action;
|
||||
|
||||
public class StartStrategy extends GamePreListener {
|
||||
|
||||
private List<Action> preActions;
|
||||
private int requiredZeros;
|
||||
|
||||
/**
|
||||
* Play the strategy until the required number of zeros has been found
|
||||
*/
|
||||
public StartStrategy(List<Action> preActions, int requiredZeros) {
|
||||
this.preActions = preActions;
|
||||
this.requiredZeros = requiredZeros;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void preAction(GameStateModel game) {
|
||||
|
||||
int zeros = 0;
|
||||
int actionCount = 0;
|
||||
|
||||
for (Action a: preActions) {
|
||||
game.doAction(a);
|
||||
actionCount++;
|
||||
|
||||
if (game.getGameState() == GameStateModel.LOST || game.getGameState() == GameStateModel.WON) {
|
||||
break;
|
||||
}
|
||||
if (game.query(a) == 0) {
|
||||
zeros++;
|
||||
if (zeros >= requiredZeros) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package minesweeperbulk;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import minesweeper.gamestate.GameStateModel;
|
||||
import minesweeper.solver.bulk.GamePreListener;
|
||||
import minesweeper.structure.Action;
|
||||
|
||||
public class StartStrategyResign extends GamePreListener {
|
||||
|
||||
private List<Action> preActions;
|
||||
private int requiredZeros;
|
||||
|
||||
/**
|
||||
* Play the strategy until the required number of zeros has been found. If first guess isn't a zero then resign
|
||||
*/
|
||||
public StartStrategyResign(List<Action> preActions, int requiredZeros) {
|
||||
this.preActions = preActions;
|
||||
this.requiredZeros = requiredZeros;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void preAction(GameStateModel game) {
|
||||
|
||||
int zeros = 0;
|
||||
int actionCount = 0;
|
||||
|
||||
for (Action a: preActions) {
|
||||
game.doAction(a);
|
||||
actionCount++;
|
||||
|
||||
if (game.getGameState() == GameStateModel.LOST || game.getGameState() == GameStateModel.WON) {
|
||||
break;
|
||||
}
|
||||
if (actionCount == 1 && game.query(a) != 0) {
|
||||
game.resign();
|
||||
break;
|
||||
}
|
||||
if (game.query(a) == 0) {
|
||||
zeros++;
|
||||
if (zeros >= requiredZeros) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user