using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MineSweeper
{
public class Container
{
/// <summary>
/// 基础方格数 横向
/// </summary>
private readonly int WidthCountBase = 15;
/// <summary>
/// 基础方格数 竖向
/// </summary>
private readonly int HeightCountBase = 8;
private int _sizeLevel;
/// <summary>
/// 画布放大等级
/// </summary>
public int SizeLevel
{
get { return _sizeLevel; }
set
{
if (value <= 0 && value > 3)
{
value = 1;
}
_sizeLevel = value;
}
}
/// <summary>
/// 横向方格数
/// </summary>
public int WidthLineCount
{
get { return WidthCountBase * this.SizeLevel; }
}
/// <summary>
/// 竖向方格数
/// </summary>
public int HeightLineCount
{
get { return HeightCountBase * this.SizeLevel; }
}
private Panel _drawPanel;
/// <summary>
/// 画布
/// </summary>
public Panel DrawPanel
{
get { return _drawPanel; }
set { _drawPanel = value; }
}
private Mine[,] _mineArray;
/// <summary>
/// 地雷方格矩阵
/// </summary>
public Mine[,] MineArray
{
get { return _mineArray; }
set { _mineArray = value; }
}
private int _mineCount;
/// <summary>
/// 地雷数量
/// </summary>
public int MineCount
{
get { return _mineCount; }
}
private int _leavingMineCount;
/// <summary>
/// 剩余地雷数
/// </summary>
public int LeavingMineCount
{
get { return _leavingMineCount; }
set
{
if (value < 0 || value > MineCount)
{
//throw new ArgumentOutOfRangeException("剩余地雷数错误!");
value = 0;
}
_leavingMineCount = value;
}
}
private int _markCount;
/// <summary>
/// 被标记的个数
/// </summary>
public int MarkCount
{
get { return _markCount; }
set { _markCount = value; }
}
/// <summary>
/// 检查结束结果
/// </summary>
public class CheckResultEventArgs : EventArgs
{
public bool IsOver { get; set; }
public bool IsSuccess { get; set; }
public CheckResultEventArgs(bool isOver, bool isSuccess)
{
this.IsOver = isOver;
this.IsSuccess = isSuccess;
}
}
public event EventHandler<CheckResultEventArgs> CheckResult;
private void OnCheckResult(CheckResultEventArgs e)
{
EventHandler<CheckResultEventArgs> handler = this.CheckResult;
if (handler != null)
{
handler(this, e);
}
}
public Container(Panel p, int level, int mineCount)
{
this.SizeLevel = level;
this.DrawPanel = p;
this.DrawPanel.BorderStyle = BorderStyle.FixedSingle;
this.DrawPanel.BackColor = SystemColors.ControlDark;
this.DrawPanel.Height = Mine.HEIGHT * HeightLineCount;
this.DrawPanel.Width = Mine.WIDTH * WidthLineCount;
this.DrawPanel.Paint += new PaintEventHandler(DrawPanel_Paint);
//初始化雷矩阵
InitMineArray();
//布雷
_mineCount = mineCount;
_leavingMineCount = _mineCount;
InitMine(this.MineCount);
}
void DrawPanel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen pen = new Pen(Color.Gray, 1);
//画竖线
for (int i = 0; i <= this.WidthLineCount; i++)
{
g.DrawLine(pen, i * Mine.WIDTH, 0, i * Mine.WIDTH, this.DrawPanel.Height);
}
//画横线
for (int i = 0; i <= this.HeightLineCount; i++)
{
g.DrawLine(pen, 0, i * Mine.HEIGHT, this.DrawPanel.Width, i * Mine.HEIGHT);
}
}
/// <summary>
/// 初始化MineArray
/// </summary>
private void InitMineArray()
{
this.DrawPanel.SuspendLayout();
this.MineArray = new Mine[WidthLineCount, HeightLineCount];
for (int i = 0; i < this.MineArray.GetLength(0); i++)
{
for (int j = 0; j < this.MineArray.GetLength(1); j++)
{
MineArray[i, j] = new Mine();
MineArray[i, j].BackColor = SystemColors.Control;
MineArray[i, j].FlatStyle = FlatStyle.Popup;
//MineArray[i, j].FlatAppearance.BorderSize = 1;
//MineArray[i, j].BorderStyle = BorderStyle.FixedSingle;
MineArray[i, j].SetBounds(i * Mine.WIDTH, j * Mine.HEIGHT,
Mine.WIDTH, Mine.HEIGHT);
//记录每个Mine的id
MineArray[i, j].Tag = i + j * WidthLineCount;
MineArray[i, j].MouseDown += new MouseEventHandler(Container_MouseDown);
this.DrawPanel.Controls.Add(MineArray[i, j]);
}
}
this.DrawPanel.PerformLayout();
}
/// <summary>
/// 布雷
/// </summary>
/// <param name="mineCount"></param>
private void InitMine(int mineCount)
{
//布雷
Random random = new Random();
int paneCount = WidthLineCount * HeightLineCount;
for (int count = 0; count < mineCount; count++)
{
int temp = random.Next(0, paneCount);
int x = temp % WidthLineCount;
int y = temp / WidthLineCount;
MineArray[x, y].IsMine = true;
}
for (int i = 0; i < MineArray.GetLength(0); i++)
{
for (int j = 0; j < MineArray.GetLength(1); j++)
{
//如是是雷,跳过
if (CheckMine(i, j))
continue;
if (CheckMine(i - 1, j - 1))
MineArray[i, j].ArroundNum++;
if (CheckMine(i - 1, j))
MineArray[i, j].ArroundNum++;
if (CheckMine(i - 1, j + 1))
MineArray[i, j].ArroundNum++;
if (CheckMine(i, j - 1))
MineArray[i, j].ArroundNum++;
if (CheckMine(i, j + 1))
MineArray[i, j].ArroundNum++;
if (CheckMine(i + 1, j + 1))
MineArray[i, j].ArroundNum++;
if (CheckMine(i + 1, j - 1))
MineArray[i, j].ArroundNum++;
if (CheckMine(i + 1, j))
MineArray[i, j].ArroundNum++;
}
}
}
/// <summary>
/// 方格按下事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Container_MouseDown(object sender, MouseEventArgs e)
{
int tag = (int)((Mine)sender).Tag;
int x = tag % WidthLineCount;
int y = tag / WidthLineCount;
if (MineArray[x, y] == null)
return;
if (e.Button == MouseButtons.Left)
{
if (MineArray[x, y].State != MineState.Mark)
{
//鼠标左键
LeftMouseButtonsDown(x, y, sender);
}
}
else
{
RightMouseButtonsDown(x, y, sender);
}
this.DrawPanel.Focus();
}
private void LeftMouseButtonsDown(int x, int y, object sender)
{
//显示出来了的,被标记为地雷的 不能被按下
if (MineArray[x, y].State != MineState.Display &&
MineArray[x, y].State != MineState.Mark)
{
//如果是雷,过关失败
if (MineArray[x, y].IsMine)
{
//把雷显示出来
for (int i = 0; i < this.MineArray.GetLength(0); i++)
{
for (int j = 0; j < this.MineArray.GetLength(1); j++)
{
if (this.MineArray[i, j].IsMine &&
this.MineArray[i, j].State != MineState.Mark)
{
MineArray[i, j].BackgroundImage = Image.FromFile(@"images\11.png");
}
if (this.MineArray[i, j].State == MineState.Mark &&
!this.MineArray[i, j].IsMine)
{
MineArray[i, j].BackgroundImage = Image.FromFile(@"images\13.png");
}
}
}
//按下的那个方格特殊处理
MineArray[x, y].BackgroundImage = Image.FromFile(@"images\10.png");
//CheckOver();//不用检查,直接失败
OnCheckResult(new CheckResultEventArgs(true, false));
}
else
{
if (MineArray[x, y].ArroundNum > 0)
{
Image image = Image.FromFile(
"images\\" + MineArray[x, y].ArroundNum.ToString() + ".png");
MineArray[x, y].BackgroundImage = image;
}
else
{
isVisible(x, y);
//MineArray[x, y].Visible = false;
////MineArray[x, y].BackColor = SystemColors.ControlDark;
}
}
}
}
private void RightMouseButtonsDown(int x, int y, object sender)
{
if (MineArray[x, y].State != MineState.Display)
{
if (MineArray[x, y].State == MineState.Normal)
{
MineArray[x, y].State = MineState.Mark;
((Button)sender).BackgroundImage = Image.FromFile(@"images\12.png");
this.MarkCount++;
if (MineArray[x, y].IsMine)
this.LeavingMineCount--;
CheckOver();
}
else if (MineArray[x, y].State == MineState.Mark)
{
MineArray[x, y].State = MineState.Question;
((Button)sender).BackgroundImage = Image.FromFile(@"images\9.png");
this.MarkCount--;
if (MineArray[x, y].IsMine)
this.LeavingMineCount++;
}
else if (MineArray[x, y].State == MineState.Question)
{
MineArray[x, y].State = MineState.Normal;
((Button)sender).BackgroundImage = null;
}
}
}
/// <summary>
/// 检查出周围的方格
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
private void isVisible(int x, int y)
{
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
//防止数组出界
if (x + i >= 0 && x + i < this.MineArray.GetLength(0) &&
y + j >= 0 && y + j < this.MineArray.GetLength(1))
{
if (MineArray[x + i, y + j].ArroundNum > 0 &&
MineArray[x + i, y + j].State != MineState.Mark &&
MineArray[x + i, y + j].State != MineState.Display)
{
MineArray[x + i, y + j].Enabled = false;
Image image = Image.FromFile(
"images\\" + MineArray[x + i, y + j].ArroundNum.ToString() + ".png");
MineArray[x + i, y + j].BackgroundImage = image;
MineArray[x + i, y + j].State = MineState.Display;
}
else if (!MineArray[x + i, y + j].IsMine &&
MineArray[x + i, y + j].ArroundNum == 0 &&
MineArray[x + i, y + j].State != MineState.Mark &&
MineArray[x + i, y + j].State != MineState.Display)
{
MineArray[x + i, y + j].Enabled = false;
MineArray[x + i, y + j].Visible = false;
MineArray[x + i, y + j].State = MineState.Display;
//MineArray[x, y].BackColor = SystemColors.ControlDark;
//调用本身
isVisible(x + i, y + j);
}
}
}
}
}
private bool CheckMine(int x, int y)
{
if (x < 0 ||
y < 0 ||
x >= this.MineArray.GetLength(0) ||
y >= this.MineArray.GetLength(1))
return false;
else
{
return this.MineArray[x, y].IsMine;
}
}
private void CheckOver()
{
if (this.LeavingMineCount == 0)
{
OnCheckResult(new CheckResultEventArgs(true, true));
return;
}
}
}
}