先贴一点上来。随后我会抽时间做一些设计模式的分析:)

/**/////////////////////////////////////////////////////////////////////
//
// Project: 扫雷
// Author: Chen Rong
// History:
// v1.0 2004,3,7 基本实现扫雷逻辑
// v1.1 2005,7,7 重构
//

/**/////////////////////////////////////////////////////////////////////
using System;


namespace ChenRong.WinMine
{

/**//// <summary>
/// 扫雷游戏对象
/// </summary>

public class MineGame
{

public MineCell[,] Board
{

get
{ return _board; }
}

MineCell[,] _board;

int _rows, _cols, _mines;
GameResult _gameResult = GameResult.None;


public int Rows
{

get
{ return _rows; }
}


public int Cols
{

get
{ return _cols; }
}


public int Mines
{

get
{ return _mines; }
}


public GameResult Result
{

get
{ return _gameResult; }
}


/**//// <summary>
/// 初始化雷区, 随机摆放地雷
/// </summary>
/// <param name="rows"></param>
/// <param name="cols"></param>
/// <param name="mines"></param>

public void Reset(int rows, int cols, int mines)
{
if (rows <= 0 || cols <= 0)
throw new Exception("雷区的长,宽必须为正整数。");
if (mines >= rows * cols)
throw new Exception("您设定的雷数目太多!");

_gameResult = GameResult.None;
_mines = mines;
_rows = rows;
_cols = cols;
_board = new MineCell[rows, cols];

InitializeCells();
PlaceRandomMines();
UpdateNearbyMinesCount();
}


/**//// <summary>
/// 更新每个位置周围地雷的统计数字
/// </summary>

private void UpdateNearbyMinesCount()
{

for (int i = 0; i < _rows; i++)
{

for (int j = 0; j < _cols; j++)
{
_board[i, j].NearbyMines = GetNearbyMines(i, j);
}
}
}


/**//// <summary>
/// 摆放随机地雷
/// </summary>

private void PlaceRandomMines()
{
int count = 0;
Random r = new Random((int)DateTime.Now.Ticks);


while (count < _mines)
{
int row = r.Next(0, _rows);
int col = r.Next(0, _cols);


if (!_board[row, col].IsMine)
{
_board[row, col].IsMine = true;
count++;
}
}
}


/**//// <summary>
/// 判断一个点是否为有效位置
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>

private bool IsValidCell(int row, int col)
{
return (row >= 0 && col >= 0 && row < _rows && col < _cols);
}


/**//// <summary>
/// 从一个格子出发向四周的可能的位移
/// </summary>

private int[,] moves = new int[8, 2]
{
{-1, -1},
{-1, 0},
{-1, 1},
{0, -1},
{0, 1},
{1, -1},
{1, 0},
{1, 1}};


/**//// <summary>
/// 得到某个位置周围的地雷数
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>

private int GetNearbyMines(int row, int col)
{
int 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) && _board[r, c].IsMine)
minesFound++;
}
return minesFound;
}

/**//// <summary>
/// 揭开某个点, 相当于鼠标左键单击触发的行为
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>

public void Uncover(int row, int col)
{
if (! IsValidCell(row, col))
return;

MineCell cell = _board[row, col];

if (cell.Uncovered)
return;
cell.Uncovered = true;
// 如果周围雷数是 0, 那么顺便把周围的 8 个位置都翻开

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>
/// 设定或取消标志, 相当于鼠标右键单击的行为
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>

public void ChangeMark(int row, int col)
{
MineCell cell = _board[row, col];
if (cell.Uncovered)
return;
// 轮换几种标志
if (cell.Mark == Mark.None)
cell.Mark = Mark.Mine;
else if (cell.Mark == Mark.Mine)
cell.Mark = Mark.Question;
else if (cell.Mark == Mark.Question)
cell.Mark = Mark.None;
}

/**//// <summary>
/// 检验游戏结果
/// </summary>

public void CheckGameResult()
{
int iUncovered = 0;
int iMarkedAsMine = 0;

// 先检测是否已经标出全部地雷

for (int i = 0; i < _rows; i++)
{

for (int j = 0; j < _cols; j++)
{
MineCell cell = _board[i, j];


if (cell.Uncovered)
{
iUncovered++;
continue;
}

if (cell.Mark == Mark.Mine)
{
iMarkedAsMine++;


if (!cell.IsMine)
{
_gameResult = GameResult.Lose;
return;
}
}
}
}
// 所有的点都已经探测到,而且标注没有失误, 就是赢了
if ((iUncovered + iMarkedAsMine) == _rows * _cols)
_gameResult = GameResult.Win;
}


/**//// <summary>
/// 初始化每个单元格对象
/// </summary>

private void InitializeCells()
{

for (int i = 0; i < _rows; i++)
{

for (int j = 0; j < _cols; j++)
{
_board[i, j] = new MineCell();
}
}
}
}
}
