/// <summary> /// Toggles the <see cref="TileState"/> of the passed in tile /// </summary> /// <param name="tile">the tile to toggle the state of</param> private void ToggleTileState(Tile tile) { var index = AllTiles.IndexOf(tile); if (tile.State == TileState.Covered) { AllTiles[index].State = TileState.Flagged; --RemainingMines; } else if (tile.State == TileState.Flagged) { if (Settings.AllowQuestionMark) { AllTiles[index].State = TileState.QuestionMarked; } else { AllTiles[index].State = TileState.Covered; } ++RemainingMines; } else if (tile.State == TileState.QuestionMarked) { AllTiles[index].State = TileState.Covered; } }
/// <summary> /// Places the miens randomly on the board /// </summary> /// <param name="tile">the tile to not put bomb in because it is the first tile clicked</param> private void PlaceMines(Tile tile) { Progress = GameProgress.InProgress; //Place mines after the first mine has been uncovered var placedMines = 0; Random rand = new Random(); while (placedMines != TotalMines) { int xRow = rand.Next(0, Rows - 1); int xCol = rand.Next(0, Columns - 1); foreach (var t in AllTiles.Where(singleTile => singleTile.Row == xRow && singleTile.Column == xCol)) { if (t != tile && t.Type != TileType.Bomb) { AllTiles[AllTiles.IndexOf(t)].Type = TileType.Bomb; placedMines++; } } } //Storing instances of adjacentTiles in every tile and changing foreach (var singleTile in AllTiles) { singleTile.InitializeAdjacentTile(this); singleTile.ChangeContent(); } stopwatch.Start(); dispatcherTimer.Start(); }
/// <summary> /// Opens the tile that is passed in /// </summary> /// <param name="tile">the tile to open</param> private void OpenTile(Tile tile) { //Since we cannot open any tile which is flagged or question marked or uncovered, we just don't do anything and return if (tile.State != TileState.Covered) { return; } tile.State = TileState.Uncovered; //If it is a new game, set up the board and all it's tiles if (Progress == GameProgress.NewGame) { PlaceMines(tile); } //Show the dialog that the player lost since s/he clicked on a mine if (tile.Type == TileType.Bomb) { Progress = GameProgress.GameEnd; bool isWin = false; dispatcherTimer.Stop(); stopwatch.Stop(); new SoundPlayer(Properties.Resources.Lose).Play(); Service.ShowDialog("GameEnd", new DialogParameters($"isWin={isWin}"), result => GameEndCallback(result)); return; } //If the tile has a number in it, do not open any adjacent tiles if (tile.Type == TileType.Number) { return; } //Here is the logic of opening all the relevant tiles. //First when the tiles are initialized, all the tile's IsItAdjacentTile property will be false //So when the user clicks on the tile, it checks if it is false and then turns the property to true for all of it's adjacent tiles //If the adjacent tile is empty tile, it will do the same loop for them too until all of the empty tiles are opened and the tiles with numbers are left if (!tile.IsItAdjacentTile || (tile.IsItAdjacentTile && tile.Type == TileType.None)) { for (int index = 0; index < AllTiles[AllTiles.IndexOf(tile)].AdjacentTiles.Count; index++) { //Since AllTiles and the AdjacentTiles(of the Tile instance that is passed in) have the same instances of objects //We are making changes only to the instances in AllTiles to keep track of all of them AllTiles[AllTiles.IndexOf(tile)].AdjacentTiles[index].IsItAdjacentTile = true; } foreach (var adjacentTile in tile.AdjacentTiles) { OpenTile(adjacentTile); } } }