rename references
This commit is contained in:
955
references/Minesweeper2/MinesweeperGui/MainWindow.xaml.cs
Normal file
955
references/Minesweeper2/MinesweeperGui/MainWindow.xaml.cs
Normal file
@ -0,0 +1,955 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using MinesweeperControl;
|
||||
using MinesweeperSolver;
|
||||
using static MinesweeperControl.GameDescription;
|
||||
using static MinesweeperControl.MinesweeperGame;
|
||||
|
||||
namespace MinesweeperGui {
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
|
||||
private readonly bool verbose = true; // determines whether diagnostic info gets written to the console
|
||||
|
||||
private readonly ImageSource Hidden;
|
||||
private readonly ImageSource[] MineValue = new ImageSource[9];
|
||||
private readonly ImageSource Flagged;
|
||||
private readonly ImageSource FlaggedWrong;
|
||||
private readonly ImageSource Mine;
|
||||
private readonly ImageSource MineWrong;
|
||||
|
||||
private readonly ImageSource[] LedValue = new ImageSource[10];
|
||||
|
||||
private int tileSize = 32;
|
||||
|
||||
private GameDescription gameDescription = GameDescription.EXPERT_SAFE;
|
||||
|
||||
// details about the solver
|
||||
private SolverInfo solverInfo;
|
||||
private SolverActionHeader solverActions = new SolverActionHeader();
|
||||
|
||||
// graphical components
|
||||
private Image hintImage; // overlay of hints from the solver
|
||||
private Image totalImage; // composite image of imageDrawings
|
||||
private DrawingGroup imageDrawings; // contains all the tiles
|
||||
private ImageDrawing[,] images; // all the tiles
|
||||
private readonly Image[] digits = new Image[8];
|
||||
|
||||
// tool tip elements
|
||||
private Popup gameToolTip = new Popup();
|
||||
private readonly TextBox popupText = new TextBox();
|
||||
|
||||
// details about the visible board
|
||||
private int topX = 0;
|
||||
private int topY = 0;
|
||||
private int boardWidth = 0;
|
||||
private int boardHeight = 0;
|
||||
private ActionResult[,] tiles;
|
||||
private MinesweeperGame game;
|
||||
private int minesLeftSize = 6;
|
||||
|
||||
private bool useSolver = false;
|
||||
private bool autoRunning = false;
|
||||
private bool useGuesses = false;
|
||||
private bool logicalLock = false;
|
||||
private int gameNumber = 1;
|
||||
private int autoPlayMinDelay = 250;
|
||||
private SolverAction jumpTo;
|
||||
|
||||
public object MinesweeperMain { get; private set; }
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private void AutoPlay() {
|
||||
|
||||
Thread autoplay = new Thread(AutoPlayRunner);
|
||||
autoplay.Start();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 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");
|
||||
|
||||
}
|
||||
|
||||
// create the non-graphical parts of the game
|
||||
private void InitializeTiles1() {
|
||||
|
||||
gameNumber++;
|
||||
logicalLock = false;
|
||||
|
||||
minesLeftSize = Math.Max(3, (int) Math.Log10(gameDescription.mines) + 1);
|
||||
|
||||
MinesLeftHolder.Width = 24 * minesLeftSize + 8;
|
||||
for (int i= 0; i < digits.Length; i++) {
|
||||
if (i < minesLeftSize) {
|
||||
digits[i].Visibility = Visibility.Visible;
|
||||
} else {
|
||||
digits[i].Visibility = Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
int seed = 0;
|
||||
if (useSeed.IsChecked == true) {
|
||||
try {
|
||||
seed = int.Parse(SeedTextBox.Text);
|
||||
} catch (Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
//game = new MinesweeperGame(gameDescription, seed);
|
||||
game = new MinesweeperGame(gameDescription, seed, (hardcore.IsChecked == true));
|
||||
solverInfo = new SolverInfo(gameDescription, verbose);
|
||||
|
||||
RenderMinesLeft();
|
||||
|
||||
long start = DateTime.Now.Ticks;
|
||||
|
||||
tiles = new ActionResult[gameDescription.width, gameDescription.height];
|
||||
solverActions = new SolverActionHeader(); // remove any hints from the previous game
|
||||
|
||||
Utility.Write("Ticks to build screen " + (DateTime.Now.Ticks - start));
|
||||
|
||||
}
|
||||
|
||||
// build the graphical part of the board
|
||||
private void BuildBoard() {
|
||||
|
||||
//long start = DateTime.Now.Ticks;
|
||||
|
||||
images = new ImageDrawing[boardWidth, boardHeight];
|
||||
|
||||
// remove existing tiles from the canvas
|
||||
gameCanvas.Children.Clear(); // clear game board
|
||||
|
||||
imageDrawings = new DrawingGroup();
|
||||
|
||||
for (int y = 0; y < boardHeight; y++) {
|
||||
for (int x = 0; x < boardWidth; x++) {
|
||||
|
||||
ActionResult tile = tiles[topX + x, topY + y];
|
||||
ImageSource imageSource;
|
||||
if (tile == null) {
|
||||
imageSource = Hidden;
|
||||
|
||||
} else if (tile.resultType == ResultType.Cleared) {
|
||||
imageSource = MineValue[tile.value];
|
||||
|
||||
} else if (tile.resultType == ResultType.Flagged) {
|
||||
imageSource = Flagged;
|
||||
|
||||
} else if (tile.resultType == ResultType.Hidden) {
|
||||
imageSource = Hidden;
|
||||
|
||||
} else if (tile.resultType == ResultType.Exploded) {
|
||||
imageSource = MineWrong;
|
||||
|
||||
} else if (tile.resultType == ResultType.FlaggedWrong) {
|
||||
imageSource = FlaggedWrong;
|
||||
|
||||
} else if (tile.resultType == ResultType.Mine) {
|
||||
imageSource = Mine;
|
||||
} else {
|
||||
imageSource = Hidden;
|
||||
}
|
||||
|
||||
|
||||
ImageDrawing image = new ImageDrawing() {
|
||||
ImageSource = imageSource,
|
||||
Rect = new Rect(x * tileSize, y * tileSize, tileSize, tileSize)
|
||||
};
|
||||
|
||||
imageDrawings.Children.Add(image);
|
||||
|
||||
images[x, y] = image;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
totalImage = new Image() {
|
||||
Source = new DrawingImage(imageDrawings)
|
||||
};
|
||||
|
||||
Canvas.SetLeft(totalImage, 0);
|
||||
Canvas.SetTop(totalImage, 0);
|
||||
gameCanvas.Children.Add(totalImage);
|
||||
|
||||
// create an empty hints image which we'll use later
|
||||
hintImage = new Image();
|
||||
|
||||
Canvas.SetLeft(hintImage, 0);
|
||||
Canvas.SetTop(hintImage, 0);
|
||||
gameCanvas.Children.Add(hintImage);
|
||||
|
||||
//Utility.Write("Ticks to build screen " + (DateTime.Now.Ticks - start));
|
||||
|
||||
}
|
||||
|
||||
private void DoAction(int x, int y, ActionType action) {
|
||||
|
||||
//int index = gameDescription.width * y + x;
|
||||
|
||||
GameResult result = game.ProcessActions(new GameAction[] { new GameAction(x, y, action) });
|
||||
|
||||
Utility.Write("Game controller returned " + result.actionResults.Count + " results from this action");
|
||||
|
||||
RenderResults(result); // draw the new board
|
||||
|
||||
solverInfo.AddInformation(result); // let the solver know what has happened
|
||||
|
||||
if (result.status == GameStatus.Lost) {
|
||||
MessageLine.Content = "The game is lost!";
|
||||
} else if (result.status == GameStatus.Won) {
|
||||
if (game.GetDeaths() != 0) {
|
||||
MessageLine.Content = "The game is won with " + game.GetDeaths() + " deaths";
|
||||
} else {
|
||||
MessageLine.Content = "The game is won";
|
||||
}
|
||||
|
||||
} else {
|
||||
// if we are showing hints or auto playing then get the hints
|
||||
if (useSolver || autoRunning) {
|
||||
AutoPlay(); // let the solver playout the moves
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void DisplayFinalOutcome(GameResult result) {
|
||||
|
||||
if (result.status == GameStatus.Lost) {
|
||||
MessageLine.Content = "The game is lost!";
|
||||
} else if (result.status == GameStatus.Won) {
|
||||
if (this.game.GetDeaths() != 0) {
|
||||
MessageLine.Content = "The game is won with " + game.GetDeaths() + " deaths";
|
||||
} else {
|
||||
MessageLine.Content = "The game is won";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool IsAutoPlayValid() {
|
||||
|
||||
if (!autoRunning) {
|
||||
//Utility.Write("Autoplay not valid - AutoPlay is not checked");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we have no actions then we can't autoplay
|
||||
if (solverActions.solverActions.Count == 0) {
|
||||
//Utility.Write("Autoplay not valid - no actions found by the solver");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we are accepting guesses then everything goes
|
||||
if (useGuesses) {
|
||||
//Utility.Write("Autoplay valid - accepting guesses");
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((solverActions.solverActions[0].safeProbability > 0 && solverActions.solverActions[0].safeProbability < 1)) {
|
||||
//Utility.Write("Autoplay not valid - no certain actions found by the solver and we aren't accepting guesses");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Utility.Write("Autoplay valid - certain actions found by the solver");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// draw the outputs from the Game onto the visible board
|
||||
private void RenderResults(GameResult result) {
|
||||
|
||||
//long start = DateTime.Now.Ticks;
|
||||
|
||||
SeedTextBox.Text = game.seed.ToString();
|
||||
|
||||
hintImage.Visibility = Visibility.Hidden; // hide the previous hints
|
||||
|
||||
foreach (ActionResult ar in result.actionResults) {
|
||||
|
||||
// remember what happen here last
|
||||
tiles[ar.x, ar.y] = ar;
|
||||
|
||||
int boardX = ar.x - topX;
|
||||
int boardY = ar.y - topY;
|
||||
|
||||
// if the action is taking place in the part of the board we are looking at
|
||||
if (boardX >= 0 && boardX < boardWidth && boardY >= 0 && boardY < boardHeight) {
|
||||
|
||||
ImageDrawing image = images[boardX, boardY];
|
||||
|
||||
if (ar.resultType == ResultType.Cleared) {
|
||||
image.ImageSource = MineValue[ar.value];
|
||||
|
||||
} else if (ar.resultType == ResultType.Flagged) {
|
||||
image.ImageSource = Flagged;
|
||||
|
||||
} else if (ar.resultType == ResultType.Hidden) {
|
||||
image.ImageSource = Hidden;
|
||||
|
||||
} else if (ar.resultType == ResultType.Exploded) {
|
||||
image.ImageSource = MineWrong;
|
||||
|
||||
} else if (ar.resultType == ResultType.FlaggedWrong) {
|
||||
image.ImageSource = FlaggedWrong;
|
||||
|
||||
} else if (ar.resultType == ResultType.Mine) {
|
||||
image.ImageSource = Mine;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RenderMinesLeft();
|
||||
|
||||
//Utility.Write("Ticks to render results " + (DateTime.Now.Ticks - start));
|
||||
|
||||
}
|
||||
|
||||
// draw the outputs from the Solver onto the visible board
|
||||
private void RenderHints() {
|
||||
|
||||
//long start = DateTime.Now.Ticks;
|
||||
|
||||
DrawingGroup hintDrawings = new DrawingGroup();
|
||||
|
||||
int offSetLeft = tileSize * (boardWidth + 1);
|
||||
int offSetTop = tileSize * (boardHeight + 1);
|
||||
|
||||
jumpTo = null;
|
||||
if (this.game.GetGameStatus() == GameStatus.InPlay) {
|
||||
if (solverActions.solverActions.Count == 0) {
|
||||
MessageLine.Content = "The solver has no suggestions!";
|
||||
} else if (solverActions.solverActions.Count > 1) {
|
||||
MessageLine.Content = "The solver has found " + solverActions.solverActions.Count + " moves.";
|
||||
} else if (solverActions.solverActions[0].safeProbability > 0 && solverActions.solverActions[0].safeProbability < 1) {
|
||||
MessageLine.Content = "The solver suggests guessing " + solverActions.solverActions[0].AsText();
|
||||
jumpTo = solverActions.solverActions[0];
|
||||
} else {
|
||||
MessageLine.Content = "The solver has found 1 move.";
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SolverAction ar in solverActions.solverActions) {
|
||||
|
||||
int boardX = ar.x - topX;
|
||||
int boardY = ar.y - topY;
|
||||
|
||||
// if the action is taking place in the part of the board we are looking at
|
||||
if (boardX >= 0 && boardX < boardWidth && boardY >= 0 && boardY < boardHeight) {
|
||||
|
||||
int x = boardX * tileSize;
|
||||
int y = boardY * tileSize;
|
||||
|
||||
if (x < offSetLeft) {
|
||||
offSetLeft = x;
|
||||
}
|
||||
if (y < offSetTop) {
|
||||
offSetTop = y;
|
||||
}
|
||||
|
||||
Color fill;
|
||||
if (ar.action == ActionType.Clear) {
|
||||
if (ar.safeProbability == 1) {
|
||||
fill = Color.FromArgb(128, 0, 255, 0); // green if safe
|
||||
} else if (ar.isDead) {
|
||||
fill = Color.FromArgb(128, 0, 0, 0); // black if excluded
|
||||
} else {
|
||||
fill = Color.FromArgb(128, 255, 165, 0); // orange if not safe
|
||||
}
|
||||
|
||||
} else if (ar.action == ActionType.Flag) {
|
||||
fill = Color.FromArgb(128, 255, 0, 0); // red if a mine
|
||||
}
|
||||
|
||||
GeometryDrawing square =
|
||||
new GeometryDrawing(
|
||||
new SolidColorBrush(fill),
|
||||
new Pen(Brushes.Black, 0),
|
||||
new RectangleGeometry(new Rect(x, y, tileSize, tileSize))
|
||||
);
|
||||
|
||||
hintDrawings.Children.Add(square);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// render dead tiles
|
||||
foreach (SolverAction ar in solverActions.deadActions) {
|
||||
|
||||
int boardX = ar.x - topX;
|
||||
int boardY = ar.y - topY;
|
||||
|
||||
// if the action is taking place in the part of the board we are looking at
|
||||
if (boardX >= 0 && boardX < boardWidth && boardY >= 0 && boardY < boardHeight) {
|
||||
|
||||
int x = boardX * tileSize;
|
||||
int y = boardY * tileSize;
|
||||
|
||||
if (x < offSetLeft) {
|
||||
offSetLeft = x;
|
||||
}
|
||||
if (y < offSetTop) {
|
||||
offSetTop = y;
|
||||
}
|
||||
|
||||
Color fill = Color.FromArgb(128, 0, 0, 0); // black if dead
|
||||
|
||||
GeometryDrawing square =
|
||||
new GeometryDrawing(
|
||||
new SolidColorBrush(fill),
|
||||
new Pen(Brushes.Black, 0),
|
||||
new RectangleGeometry(new Rect(x, y, tileSize, tileSize))
|
||||
);
|
||||
|
||||
hintDrawings.Children.Add(square);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// replace the old composite hints image with the new
|
||||
hintImage.Source = new DrawingImage(hintDrawings);
|
||||
|
||||
// and place it in the write position
|
||||
Canvas.SetLeft(hintImage, offSetLeft);
|
||||
Canvas.SetTop(hintImage, offSetTop);
|
||||
hintImage.Visibility = Visibility.Visible;
|
||||
|
||||
//Utility.Write("Ticks to render hints " + (DateTime.Now.Ticks - start));
|
||||
}
|
||||
|
||||
private void RebuildBoard(int topX, int topY, int boardWidth, int boardHeight) {
|
||||
|
||||
this.topX = topX;
|
||||
this.topY = topY;
|
||||
this.boardWidth = boardWidth;
|
||||
this.boardHeight = boardHeight;
|
||||
|
||||
// make sure the top position allows enough space to fill the board
|
||||
if (this.topX + this.boardWidth > gameDescription.width) {
|
||||
this.topX = gameDescription.width - this.boardWidth;
|
||||
}
|
||||
|
||||
if (this.topY + this.boardHeight > gameDescription.height) {
|
||||
this.topY = gameDescription.height - this.boardHeight;
|
||||
}
|
||||
|
||||
|
||||
if (boardWidth > 0 && boardHeight > 0) {
|
||||
BuildBoard();
|
||||
RenderHints();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void RenderMinesLeft() {
|
||||
|
||||
int i = minesLeftSize - 1;
|
||||
int mines = game.GetMinesLeft();
|
||||
|
||||
while (i >= 0) {
|
||||
|
||||
int d0 = mines % 10;
|
||||
mines = (mines - d0) / 10;
|
||||
|
||||
digits[i].Source = LedValue[d0];
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void CanvasMouseDown(object sender, MouseButtonEventArgs e) {
|
||||
|
||||
|
||||
if (logicalLock) { // this means the solver is playing the game and the user input is ignored
|
||||
return;
|
||||
}
|
||||
|
||||
int x = (int) e.GetPosition(gameCanvas).X;
|
||||
int y = (int) e.GetPosition(gameCanvas).Y;
|
||||
|
||||
//Utility.Write("Mouse clicked at X=" + x + ", Y=" + y);
|
||||
|
||||
int col = x / tileSize;
|
||||
int row = y / tileSize;
|
||||
|
||||
if (col < 0 || col > boardWidth || row < 0 || row > boardHeight) {
|
||||
Utility.Write("Clicked outside of game boundary col=" + col + ", row=" + row);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Utility.Write("col=" + col + ", row=" + row);
|
||||
ActionType actionType;
|
||||
|
||||
ActionResult tile = tiles[col + topX, row + topY];
|
||||
|
||||
if (e.ChangedButton == MouseButton.Left) {
|
||||
if (tile == null || tile.resultType == ResultType.Hidden) {
|
||||
actionType = ActionType.Clear;
|
||||
} else if (tile.resultType == ResultType.Cleared) {
|
||||
actionType = ActionType.Chord;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (e.ChangedButton == MouseButton.Right) {
|
||||
actionType = ActionType.Flag;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
DoAction(col + topX, row + topY, actionType);
|
||||
|
||||
}
|
||||
|
||||
private void NewGame() {
|
||||
|
||||
InitializeTiles1();
|
||||
|
||||
// reposition the display to the top left
|
||||
//topX = 0;
|
||||
//topY = 0;
|
||||
|
||||
// move the scroll bars back to the start
|
||||
horizontalScrollbar.Value = 0;
|
||||
verticalScrollbar.Value = 0;
|
||||
|
||||
// work out if scroll bars are need and how big the thumb is
|
||||
//boardWidth = DoWidth(mainWindow.ActualWidth);
|
||||
//boardHeight = DoHeight(mainWindow.ActualHeight);
|
||||
|
||||
RebuildBoard(0, 0, DoWidth(mainWindow.ActualWidth), DoHeight(mainWindow.ActualHeight));
|
||||
|
||||
}
|
||||
|
||||
private void BeginnerClick(object sender, RoutedEventArgs e) {
|
||||
|
||||
if (zeroStart.IsChecked == true) {
|
||||
gameDescription = GameDescription.BEGINNER_ZERO;
|
||||
} else {
|
||||
gameDescription = GameDescription.BEGINNER_SAFE;
|
||||
}
|
||||
|
||||
NewGame();
|
||||
|
||||
}
|
||||
|
||||
private void IntermediateClick(object sender, RoutedEventArgs e) {
|
||||
|
||||
if (zeroStart.IsChecked == true) {
|
||||
gameDescription = GameDescription.INTERMEDIATE_ZERO;
|
||||
} else {
|
||||
gameDescription = GameDescription.INTERMEDIATE_SAFE;
|
||||
}
|
||||
|
||||
NewGame();
|
||||
|
||||
}
|
||||
|
||||
private void ExpertClick(object sender, RoutedEventArgs e) {
|
||||
|
||||
|
||||
if (zeroStart.IsChecked == true) {
|
||||
gameDescription = GameDescription.EXPERT_ZERO;
|
||||
} else {
|
||||
gameDescription = GameDescription.EXPERT_SAFE;
|
||||
}
|
||||
|
||||
NewGame();
|
||||
|
||||
}
|
||||
|
||||
private void CustomClick(object sender, RoutedEventArgs e) {
|
||||
|
||||
int gameWidth;
|
||||
int gameHeight;
|
||||
int gameMines;
|
||||
|
||||
try {
|
||||
gameWidth = int.Parse(CustomWidth.Text);
|
||||
} catch (System.Exception) {
|
||||
gameWidth = 30;
|
||||
CustomWidth.Text = gameWidth.ToString();
|
||||
}
|
||||
|
||||
try {
|
||||
gameHeight = int.Parse(CustomHeight.Text);
|
||||
} catch (System.Exception) {
|
||||
gameHeight = 16;
|
||||
CustomHeight.Text = gameHeight.ToString();
|
||||
}
|
||||
|
||||
try {
|
||||
gameMines = int.Parse(CustomMines.Text);
|
||||
} catch (System.Exception) {
|
||||
gameMines = gameWidth * gameHeight / 5;
|
||||
CustomMines.Text = gameMines.ToString();
|
||||
}
|
||||
|
||||
if (zeroStart.IsChecked == true) {
|
||||
gameDescription = new GameDescription(gameWidth, gameHeight, gameMines, GameType.Zero);
|
||||
} else {
|
||||
gameDescription = new GameDescription(gameWidth, gameHeight, gameMines, GameType.Safe);
|
||||
}
|
||||
|
||||
NewGame();
|
||||
|
||||
}
|
||||
|
||||
// redraws the controls based on the new width and returns the number of columns we are now able to show
|
||||
private int DoWidth(double width) {
|
||||
|
||||
MessageHolder.Width = Math.Max(0, width - 260);
|
||||
|
||||
double boardMax = gameDescription.width * tileSize + 8;
|
||||
|
||||
double actualWidth = Math.Max(8, Math.Min(boardMax, width - 260));
|
||||
|
||||
int showTilesWidth = (int)Math.Floor((actualWidth - 8) / tileSize);
|
||||
|
||||
double boardWidthPixels = showTilesWidth * tileSize + 8; // board is in Whole tiles
|
||||
|
||||
BoardHolder.Width = boardWidthPixels;
|
||||
|
||||
if (showTilesWidth == gameDescription.width) {
|
||||
horizontalScrollbar.Visibility = Visibility.Hidden;
|
||||
} else {
|
||||
horizontalScrollbar.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
horizontalScrollbar.Width = boardWidthPixels;
|
||||
horizontalScrollbar.Maximum = (gameDescription.width - showTilesWidth);
|
||||
horizontalScrollbar.ViewportSize = showTilesWidth;
|
||||
horizontalScrollbar.LargeChange = showTilesWidth; // scroll bar large scroll is a whole screen
|
||||
|
||||
return showTilesWidth;
|
||||
|
||||
}
|
||||
|
||||
// redraws the controls based on the new height and returns the number of columns we are now able to show
|
||||
private int DoHeight(double height) {
|
||||
|
||||
double boardMax = gameDescription.height * tileSize + 8;
|
||||
|
||||
double actualHeight = Math.Max(8, Math.Min(boardMax, height - 140));
|
||||
|
||||
int showTilesHeight = (int) Math.Floor((actualHeight - 8) / tileSize);
|
||||
|
||||
double boardHeightPixels = showTilesHeight * tileSize + 8; // board is in Whole tiles
|
||||
|
||||
BoardHolder.Height = boardHeightPixels;
|
||||
|
||||
if (showTilesHeight == gameDescription.height) {
|
||||
verticalScrollbar.Visibility = Visibility.Hidden;
|
||||
} else {
|
||||
verticalScrollbar.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
verticalScrollbar.Height = boardHeightPixels;
|
||||
verticalScrollbar.Maximum = (gameDescription.height - showTilesHeight);
|
||||
verticalScrollbar.ViewportSize = showTilesHeight;
|
||||
verticalScrollbar.LargeChange = showTilesHeight; // scroll bar large scroll is a whole screen
|
||||
|
||||
return showTilesHeight;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void RedrawWindow(object sender, SizeChangedEventArgs e) {
|
||||
|
||||
//Utility.Write("New width:" + e.NewSize.Width + " height:" + e.NewSize.Height);
|
||||
|
||||
int newBoardWidth = boardWidth;
|
||||
int newBoardHeight = boardHeight;
|
||||
|
||||
if (e.WidthChanged == true) {
|
||||
newBoardWidth = DoWidth(e.NewSize.Width);
|
||||
}
|
||||
|
||||
if (e.HeightChanged == true) {
|
||||
newBoardHeight = DoHeight(e.NewSize.Height);
|
||||
}
|
||||
|
||||
if (newBoardWidth != this.boardWidth || newBoardHeight != this.boardHeight) {
|
||||
RebuildBoard(topX, topY, newBoardWidth, newBoardHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void VerticalScroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e) {
|
||||
|
||||
//Utility.Write("Vertical scroll : " + e.NewValue);
|
||||
|
||||
int newTopY = (int) Math.Floor(e.NewValue + 0.5d);
|
||||
|
||||
if (newTopY != topY) {
|
||||
RebuildBoard(topX, newTopY, boardWidth, boardHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void HorizontalScroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e) {
|
||||
|
||||
//Utility.Write("Horizontal scroll : " + e.NewValue);
|
||||
|
||||
int newTopX = (int)Math.Floor(e.NewValue + 0.5d);
|
||||
|
||||
if (newTopX != topX) {
|
||||
RebuildBoard(newTopX, topY, boardWidth, boardHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void MouseMoveOnBoard(object sender, MouseEventArgs e) {
|
||||
|
||||
int x = (int)e.GetPosition(gameCanvas).X;
|
||||
int y = (int)e.GetPosition(gameCanvas).Y;
|
||||
|
||||
int col = x / tileSize;
|
||||
int row = y / tileSize;
|
||||
|
||||
if (col < 0 || col > boardWidth || row < 0 || row > boardHeight) {
|
||||
Utility.Write("Mouse outside of game boundary col=" + col + ", row=" + row);
|
||||
return;
|
||||
}
|
||||
|
||||
int realCol = col + topX;
|
||||
int realRow = row + topY;
|
||||
|
||||
double prob = solverInfo.GetProbability(realCol, realRow);
|
||||
string probText;
|
||||
if (prob == -1) {
|
||||
probText = "";
|
||||
} else if (prob == 0) {
|
||||
probText = "Mine";
|
||||
} else if (prob == 1) {
|
||||
probText = "Clear";
|
||||
} else {
|
||||
//probText = String.Format("0.00", prob) + " Safe";
|
||||
probText = (prob * 100).ToString("N2") + "% Safe";
|
||||
}
|
||||
|
||||
popupText.Text = "(" + realCol + "," + realRow + ") " + probText;
|
||||
|
||||
gameToolTip.HorizontalOffset = x;
|
||||
gameToolTip.VerticalOffset = y + 10;
|
||||
|
||||
}
|
||||
|
||||
private void MouseLeftBoard(object sender, MouseEventArgs e) {
|
||||
|
||||
gameToolTip.IsOpen = false;
|
||||
|
||||
}
|
||||
|
||||
private void MouseEnteredBoard(object sender, MouseEventArgs e) {
|
||||
|
||||
gameToolTip.IsOpen = true;
|
||||
|
||||
}
|
||||
|
||||
private void ClickMessageLine(object sender, MouseButtonEventArgs e) {
|
||||
|
||||
if (jumpTo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set the scroll bars
|
||||
verticalScrollbar.Value = jumpTo.y - this.boardHeight / 2;
|
||||
horizontalScrollbar.Value = jumpTo.x - this.boardWidth / 2;
|
||||
|
||||
// now see where the scrollbars are
|
||||
int newTopY = (int)Math.Floor(verticalScrollbar.Value + 0.5d);
|
||||
int newTopX = (int)Math.Floor(horizontalScrollbar.Value + 0.5d);
|
||||
|
||||
// redraw board if we need to
|
||||
if (newTopY != topY || newTopX != topX) {
|
||||
RebuildBoard(newTopX, newTopY, boardWidth, boardHeight);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void MouseWheelOnBoard(object sender, MouseWheelEventArgs e) {
|
||||
|
||||
// if shift is pressed scroll left and right
|
||||
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
|
||||
horizontalScrollbar.Value -= e.Delta / 40;
|
||||
|
||||
int newTopX = (int)Math.Floor(horizontalScrollbar.Value + 0.5d);
|
||||
|
||||
if (newTopX != topX) {
|
||||
RebuildBoard(newTopX, topY, boardWidth, boardHeight);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) {
|
||||
return;
|
||||
}
|
||||
|
||||
verticalScrollbar.Value -= e.Delta / 40;
|
||||
|
||||
int newTopY = (int)Math.Floor(verticalScrollbar.Value + 0.5d);
|
||||
|
||||
if (newTopY != topY) {
|
||||
RebuildBoard(topX, newTopY, boardWidth, boardHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void SetSolverDetails(object sender, RoutedEventArgs e) {
|
||||
|
||||
useSolver = (showHInts.IsChecked == true);
|
||||
autoRunning = (autoPlay.IsChecked == true);
|
||||
useGuesses = (acceptGuesses.IsChecked == true);
|
||||
|
||||
//Console.WriteLine(useSolver + " " + autoRunning + " " + useGuesses);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user