public MainWindow() { Utility.Write("At MainWindow constructor"); InitializeComponent(); // load the images we need Hidden = Utility.BuildImageSource("facingDown.png", tileSize); Flagged = Utility.BuildImageSource("flagged.png", tileSize); FlaggedWrong = Utility.BuildImageSource("flaggedWrong.png", tileSize); Mine = Utility.BuildImageSource("mine.png", tileSize); MineWrong = Utility.BuildImageSource("exploded.png", tileSize); for (int i = 0; i < 9; i++) { MineValue[i] = Utility.BuildImageSource(i + ".png", tileSize); } for (int i = 0; i < 10; i++) { LedValue[i] = Utility.BuildImageSource("led" + i + ".png", 24, 40); } CustomWidth.Text = "100"; CustomHeight.Text = "100"; CustomMines.Text = "2000"; for (int i = 0; i < digits.Length; i++) { digits[i] = new Image() { Source = LedValue[0] }; Canvas.SetTop(digits[i], 0); Canvas.SetLeft(digits[i], i * LedValue[0].Width); MinesLeft.Children.Add(digits[i]); } // complete creating the popup popupText.Text = ""; popupText.Background = new SolidColorBrush(Color.FromArgb(128, 227, 227, 227)); popupText.Foreground = Brushes.Black; popupText.FontSize = 20; popupText.FontWeight = FontWeights.Bold; gameToolTip.Child = popupText; gameToolTip.AllowsTransparency = true; gameToolTip.Placement = PlacementMode.Relative; gameToolTip.PlacementTarget = gameCanvas; gameToolTip.IsOpen = true; gameCanvas.Children.Add(gameToolTip); // start up a game InitializeTiles1(); Utility.Write("Graphics rendering tier = " + (RenderCapability.Tier >> 16)); SolverMain.Initialise(); }
// this method runs on a different thread. gameNumber can be changed by clicking chosing a new game from the UI thread. private static GameStatus AutoPlayRunner(MinesweeperGame game) { //long start = DateTime.Now.Ticks; SolverActionHeader solverActions; GameResult result = game.ProcessActions(firstPlay); SolverInfo solverInfo = new SolverInfo(game.description); while (result.status == GameStatus.InPlay) { solverInfo.AddInformation(result); // let the solver know what has happened solverActions = SolverMain.FindActions(solverInfo); // pass the solver info into the solver and see what it comes up with if (solverActions.solverActions.Count == 0) { Write("No actions returned by the solver!!"); break; } result = game.ProcessActions(solverActions.solverActions); //Write("Game controller returned " + result.actionResults.Count + " results from this action"); //foreach (SolverAction action in solverActions) { // Write("Playing " + action.AsText() + " probability " + action.safeProbability); //} } //long end = DateTime.Now.Ticks; //Write("game took " + (end - start) + " ticks"); return(result.status); }
static void Main(string[] args) { GameDescription description = GameDescription.EXPERT_SAFE; //GameDescription description = new GameDescription(30, 24, 225, GameType.Safe); //GameDescription description = new GameDescription(100, 100, 1500, GameType.Zero); //GameDescription description = new GameDescription(50, 50, 500, GameType.Safe); //GameDescription description = new GameDescription(8, 8, 34, GameType.Safe); if (description.gameType == GameType.Zero) { firstPlay = new GameAction[] { new GameAction(3, 3, ActionType.Clear) }; } else { firstPlay = new GameAction[] { new GameAction(0, 0, ActionType.Clear) }; } int seedGen = new Random().Next(); //int seedGen = 1104105816; Random rng = new Random(seedGen); int run = 100000; int steps = 100; int won = 0; int lost = 0; int deaths = 0; SolverMain.Initialise(); Write("using generation seed " + seedGen + " to run " + run + " games of minesweeper " + description.AsText()); Write("--- Press Enter to start ---"); Console.ReadLine(); long start = DateTime.Now.Ticks; for (int i = 0; i < run; i++) { int seed = rng.Next(); MinesweeperGame game = new MinesweeperGame(description, seed, !playUntilWin); //Write("Seed " + game.seed + " starting"); GameStatus status = AutoPlayRunner(game); int died = game.GetDeaths(); if (died < deathTable.Length) { deathTable[died]++; } else { deathTable[deathTable.Length - 1]++; } deaths = deaths + died; if (status == GameStatus.Lost) { lost++; } else if (status == GameStatus.Won) { won++; if (pauseOnWin) { Write("Seed " + game.seed + " won"); Write("--- Press Enter to continue ---"); Console.ReadLine(); } } else { Write("Seed " + game.seed + " : Unexpected game status from autoplay " + status); } if ((i + 1) % steps == 0) { Write("Seed " + game.seed + " finished. Games won " + won + " out of " + (i + 1)); } } long duration = (DateTime.Now.Ticks - start) / 10000; Write("Games won " + won + ", lost " + lost + " out of " + run + " in " + duration + " milliseconds."); double winRate = (won * 10000 / run) / 100d; Write("Win rate " + winRate + "%"); Write("Deaths " + deaths + " average deaths per game " + (deaths * 1000 / run) / 1000d); for (int i = 0; i < deathTable.Length - 1; i++) { Write("Died " + i + " times in " + deathTable[i] + " games"); } Write("Died >=" + (deathTable.Length - 1) + " times in " + deathTable[deathTable.Length - 1] + " games"); Console.ReadLine(); }
// this method runs on a different thread. gameNumber is changed by clicking chosing a new game from the UI thread. private void AutoPlayRunner() { Dispatcher.Invoke(() => gameCanvas.Cursor = Cursors.Wait); logicalLock = true; int runningGameNumber = gameNumber; // remember the game number we are solving //Utility.Write("AutoRunning thread starting"); solverActions = SolverMain.FindActions(solverInfo); // pass the solver info into the solver and see what it comes up with Dispatcher.Invoke(() => RenderHints()); while (IsAutoPlayValid() && gameNumber == runningGameNumber) { long start = DateTime.Now.Ticks; GameResult result = game.ProcessActions(solverActions.solverActions); //Utility.Write("Game controller returned " + result.actionResults.Count + " results from this action"); long end1 = DateTime.Now.Ticks; // do the rendering while we are stil playing the same game if (gameNumber == runningGameNumber) { gameCanvas.Dispatcher.Invoke(() => RenderResults(result)); } else { break; } //Utility.Write("After RenderResults took " + (DateTime.Now.Ticks - start) + " ticks"); solverInfo.AddInformation(result); // let the solver know what has happened // nothing more to do if we have won or lost if (result.status == GameStatus.Lost || result.status == GameStatus.Won) { Dispatcher.Invoke(() => DisplayFinalOutcome(result)); break; } solverActions = SolverMain.FindActions(solverInfo); // pass the solver info into the solver and see what it comes up with //foreach (SolverAction action in solverActions) { // Utility.Write("Playing " + action.AsText() + " probability " + action.safeProbability); //} //long end2 = DateTime.Now.Ticks; // do the rendering while we are stil playing the same game if (gameNumber == runningGameNumber) { Dispatcher.Invoke(() => RenderHints()); } else { break; } //Utility.Write("After RenderHints took " + (DateTime.Now.Ticks - start) + " ticks"); Utility.Write("Tiles remaining " + solverInfo.GetTilesLeft()); long end = DateTime.Now.Ticks; int milliseconds = (int)((end - start) / 10000); int wait = Math.Max(0, autoPlayMinDelay - milliseconds); //Utility.Write("Autoplay processing took " + milliseconds + " milliseconds (" + (end - start) + " ticks)"); //Console.WriteLine("Autoplay processing took " + milliseconds + " milliseconds"); if (!IsAutoPlayValid()) { break; } Thread.Sleep(wait); // wait until all the time is used up } logicalLock = false; Dispatcher.Invoke(() => gameCanvas.Cursor = Cursors.Arrow); //Utility.Write("AutoRunning thread ending"); }