private void MineCell_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { MineCell mineCell = (MineCell)sender; if (mineCell.IsFlagged == false) { RevealMineCell((MineCell)sender); CheckIfWon(false); } } else if (e.Button == MouseButtons.Right) { MineCell mineCell = (MineCell)sender; if (mineCell.IsFlagged == false) { mineCell.BackColor = Color.Red; mineCell.IsFlagged = true; } else//if already flagged { mineCell.BackColor = SystemColors.ControlLight; mineCell.IsFlagged = false; } CheckIfWon(true); } }
/// <summary> /// Left and right mouse button simultaneously press behavior /// </summary> /// <param name="row"></param> /// <param name="col"></param> public void UncoverNearBy(int row, int col) { MineCell cell = cells[row, col]; if (cell.Status == MineCellStatus.Uncovered && cell.NearbyMines > 0) { byte minesFound = 0; for (int i = 0; i < moves.GetLength(0); i++) { int r = row + moves[i, 0]; int c = col + moves[i, 1]; if (IsValidCell(r, c) && cells[r, c].Status == MineCellStatus.MarkMine) { minesFound++; } } if (minesFound == cell.NearbyMines) { for (int i = 0; i < moves.GetLength(0); i++) { int r = row + moves[i, 0]; int c = col + moves[i, 1]; Uncover(r, c); } } } }
private void RevealMineCell(MineCell revealingMineCell) { string[] parsedCoords = revealingMineCell.Name.ToString().Split(','); int proxXCoord = Convert.ToInt32(parsedCoords[0]); int proxYCoord = Convert.ToInt32(parsedCoords[1]); string proxCellName; //the name of the proximity mine cell MineCell proxCell; //the proximity mine cell int[,] proxCoords = { { proxXCoord + 1, proxYCoord - 1 },//all 8 adjacent coordinates of `revealingMineCell` { proxXCoord + 1, proxYCoord }, { proxXCoord + 1, proxYCoord + 1 }, { proxXCoord - 1, proxYCoord - 1 }, { proxXCoord - 1, proxYCoord }, { proxXCoord - 1, proxYCoord + 1 }, { proxXCoord, proxYCoord - 1 }, { proxXCoord, proxYCoord + 1 } }; if (revealingMineCell.HasMine)//if the mine cell revealed has mine in it { MineField.Enabled = false; GameOverSign.Visible = true; RetryButton.Enabled = true; RetryButton.Visible = true; RetryButton.BringToFront(); } else if (revealingMineCell.ProxMineCount == 0)//if the mine cell revealed is empty { revealingMineCell.Enabled = false; revealingMineCell.BackColor = SystemColors.ControlDark; revealingMineCell.IsRevealed = true; for (int i = 0; i < 8; i++) { proxCellName = Convert.ToString(proxCoords[i, 0]) + "," + Convert.ToString(proxCoords[i, 1]); proxCell = (MineCell)MineField.Controls.Find(proxCellName, true).FirstOrDefault(); if (proxCell != null && proxCell.IsRevealed == false && proxCell.IsFlagged) { proxCell.IsFlagged = false; proxCell.BackColor = SystemColors.ControlDark; RevealMineCell(proxCell); } else if (proxCell != null && proxCell.IsRevealed == false) //reminder: `proxCell` is impossible to have a mine in it as `revealingMineCell` is empty in the first place { RevealMineCell(proxCell); //repeat the process until all adjacent empty mine cells are all revealed } } } else { revealingMineCell.Enabled = false; revealingMineCell.Text = Convert.ToString(revealingMineCell.ProxMineCount); revealingMineCell.BackColor = SystemColors.ControlDark; revealingMineCell.IsRevealed = true; } }
private void DrawCell(Graphics g, MineCell cell) { Rectangle rt = CellRectangle; StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; if (cell.IsMine && board.Status == GameStatus.Lose) { g.FillRectangle(Brushes.DarkGray, rt); g.DrawString("@", Font, cell.Status == MineCellStatus.Exploded ? Brushes.Red : Brushes.DarkBlue, rt, sf); } else { if (cell.Status == MineCellStatus.Covered) { g.FillRectangle(Brushes.DarkGray, rt); } else if (cell.Status == MineCellStatus.MarkMine) { g.FillRectangle(Brushes.DarkGray, rt); g.DrawString("#", Font, Brushes.DarkBlue, rt, sf); } else if (cell.Status == MineCellStatus.MarkDoubt) { g.FillRectangle(Brushes.DarkGray, rt); g.DrawString("?", Font, Brushes.DarkBlue, rt, sf); } else { if (cell.NearbyMines > 0) { g.DrawString(cell.NearbyMines.ToString(), Font, Brushes.DarkBlue, rt, sf); } } } g.DrawRectangle(Pens.Black, rt); sf.Dispose(); }
public void Uncover(int row, int col) { if (!IsValidCell(row, col)) { return; } if (status == GameStatus.NotStarted) { status = GameStatus.Playing; } MineCell cell = cells[row, col]; if (cell.Status != MineCellStatus.Covered) { return; } if (cell.IsMine) { cells[row, col].Status = MineCellStatus.Exploded; this.status = GameStatus.Lose; return; } else { cells[row, col].Status = MineCellStatus.Uncovered; } // If the surrounding mines number is 0, then turn around the 8 positions. if (!cell.IsMine && cell.NearbyMines == 0) { for (int i = 0; i < moves.GetLength(0); i++) { Uncover(row + moves[i, 0], col + moves[i, 1]); } } }
/// <summary> /// Set or cancel the flag, which is equivalent to the right mouse click behavior /// </summary> /// <param name="row"></param> /// <param name="col"></param> public void ChangeMark(int row, int col) { if (!IsValidCell(row, col)) { return; } if (status == GameStatus.NotStarted) { status = GameStatus.Playing; } MineCell cell = cells[row, col]; // Set or cancel the flag, which is equivalent to the right mouse click behavior switch (cell.Status) { case MineCellStatus.Covered: cell.Status = MineCellStatus.MarkMine; makedMines++; break; case MineCellStatus.MarkMine: cell.Status = MineCellStatus.MarkDoubt; break; case MineCellStatus.MarkDoubt: makedMines--; cell.Status = MineCellStatus.Covered; break; default: break; } cells[row, col] = cell; }
public Minesweeper() { InitializeComponent(); StartupMenu startupMenu = new StartupMenu(this); startupMenu.FormClosing += new FormClosingEventHandler(StartupMenu_Closing); if (GameInfo.FirstStarted) { startupMenu.ShowDialog();//show startup menu GameInfo.FirstStarted = false; } while (!GameInfo.GameStarted) { ; //wait until start button is pressed } //<draw mine field> int mineCellWidth = 25; int mineCellLength = 25; int mineCellDistance = 5; Random rnd = new Random(); for (int x = 0; x < GameInfo.BoardX; x++)//generate mine cells { for (int y = 0; y < GameInfo.BoardY; y++) { MineCell currentDrawing = new MineCell() { Size = new Size(mineCellWidth, mineCellLength), Location = new Point(x * mineCellWidth + mineCellDistance, y * mineCellLength + mineCellDistance), Name = Convert.ToString(x, 10) + "," + Convert.ToString(y, 10), BackColor = SystemColors.ControlLight }; MineField.Controls.Add(currentDrawing); currentDrawing.MouseDown += new MouseEventHandler(MineCell_MouseDown); } } for (; ;) //generate mines { int randomXCoord = rnd.Next(0, GameInfo.BoardX); int randomYCoord = rnd.Next(0, GameInfo.BoardY); string SelectedMineCellName = Convert.ToString(randomXCoord) + "," + Convert.ToString(randomYCoord);//the name of the mine cell selected MineCell selectedMineCell = (MineCell)MineField.Controls.Find(SelectedMineCellName, true)[0]; if (selectedMineCell.HasMine == false) { selectedMineCell.HasMine = true; GameInfo.CurrentMineCount++; } else//if the selected mine cell already has mine in it { continue; } if (GameInfo.CurrentMineCount == GameInfo.TotalMineCount)//when generation is complete { break; } } for (int x = 0; x < GameInfo.BoardX; x++)//calculate `ProxMineCount` { for (int y = 0; y < GameInfo.BoardY; y++) { string selectedMineCellName = Convert.ToString(x) + "," + Convert.ToString(y); //the name of the mine cell selected string proxCellName; //the name of the proximity mine cell int[,] proxCoords = { { x + 1, y - 1 },//all 8 adjacent coordinates of `selectedCell` { x + 1, y }, { x + 1, y + 1 }, { x - 1, y - 1 }, { x - 1, y }, { x - 1, y + 1 }, { x, y - 1 }, { x, y + 1 } }; MineCell selectedCell = (MineCell)MineField.Controls.Find(selectedMineCellName, true)[0]; MineCell proxCell; for (int i = 0; i < 8; i++)//cycle through all 8 adjacent cells { proxCellName = Convert.ToString(proxCoords[i, 0]) + "," + Convert.ToString(proxCoords[i, 1]); proxCell = (MineCell)MineField.Controls.Find(proxCellName, true).FirstOrDefault(); if (proxCell != null && proxCell.HasMine) { selectedCell.ProxMineCount++; } } } } //</draw mine field> }