接著前一篇文章,Minesweeper: GDI+ 初步實現(xiàn),本文在代碼結(jié)構(gòu)上做一些改進(jìn),不涉及新的功能。
首先我們來看MineBoard類的Init方法:
PlaceRandomMines和UpdateNearbyMinesCount實現(xiàn)跟上一篇文章中一樣,就不給出了。
MineBoard的Init方法則重構(gòu)為:
下面的這個類可以很容易的實現(xiàn)二進(jìn)制地圖文件的讀取。文本/XML格式的地圖讀取,也可以很容易的實現(xiàn)。
首先我們來看MineBoard類的Init方法:
public void Init(int rows, int columns, int mines)
{
if (rows <= 0 || columns <= 0 || mines >= columns * rows)
{
throw new ArgumentException();
}
cells = new MineCell[rows, columns];
totalMines = mines;
makedMines = 0;
status = GameStatus.NotStarted;
PlaceRandomMines();
UpdateNearbyMinesCount();
}
{
if (rows <= 0 || columns <= 0 || mines >= columns * rows)
{
throw new ArgumentException();
}
cells = new MineCell[rows, columns];
totalMines = mines;
makedMines = 0;
status = GameStatus.NotStarted;
PlaceRandomMines();
UpdateNearbyMinesCount();
}
實際的游戲開發(fā)中,隨機(jī)布局整個游戲區(qū)域的情況并不多,更為常見的還是從地圖中讀取。同時,為了實現(xiàn)游戲過程中保存當(dāng)前的游戲進(jìn)展,然后讀取后繼續(xù),或者支持從網(wǎng)絡(luò)上下載布局,以及同其他人分享等,需要將布局的功能移到MineBoard在之外。
調(diào)整后的代碼如下:
public interface IMineBoardBuilder
{
int TotalMines { get; }
int MarkedMines { get; }
MineCell[,] BuildMineCells();
}
public class RandomBoardBuilder : IMineBoardBuilder
{
private int rows;
private int columns;
private int totalMines;
public RandomBoardBuilder(int rows, int columns, int mines)
{
if (rows <= 0 || columns <= 0 || mines >= columns * rows)
{
throw new ArgumentException();
}
this.rows = rows;
this.columns = columns;
this.totalMines = mines;
}
public int TotalMines { get { return totalMines; } }
public int MarkedMines { get { return 0; } }
public MineCell[,] BuildMineCells()
{
MineCell[,] cells = new MineCell[rows, columns];
PlaceRandomMines(cells);
UpdateNearbyMinesCount(cells);
return cells;
}
}
{
int TotalMines { get; }
int MarkedMines { get; }
MineCell[,] BuildMineCells();
}
public class RandomBoardBuilder : IMineBoardBuilder
{
private int rows;
private int columns;
private int totalMines;
public RandomBoardBuilder(int rows, int columns, int mines)
{
if (rows <= 0 || columns <= 0 || mines >= columns * rows)
{
throw new ArgumentException();
}
this.rows = rows;
this.columns = columns;
this.totalMines = mines;
}
public int TotalMines { get { return totalMines; } }
public int MarkedMines { get { return 0; } }
public MineCell[,] BuildMineCells()
{
MineCell[,] cells = new MineCell[rows, columns];
PlaceRandomMines(cells);
UpdateNearbyMinesCount(cells);
return cells;
}
}
PlaceRandomMines和UpdateNearbyMinesCount實現(xiàn)跟上一篇文章中一樣,就不給出了。
MineBoard的Init方法則重構(gòu)為:
public void Init(IMineBoardBuilder builder)
{
cells = builder.BuildMineCells();
totalMines = builder.TotalMines;
makedMines = builder.MarkedMines;
status = GameStatus.NotStarted;
}
{
cells = builder.BuildMineCells();
totalMines = builder.TotalMines;
makedMines = builder.MarkedMines;
status = GameStatus.NotStarted;
}
下面的這個類可以很容易的實現(xiàn)二進(jìn)制地圖文件的讀取。文本/XML格式的地圖讀取,也可以很容易的實現(xiàn)。
[Serializable]
public class BoardFileLoader : IMineBoardBuilder
{
private MineCell[,] cells;
private int totalMines;
private int markedMines;
public int TotalMines { get { return totalMines; } }
public int MarkedMines { get { return markedMines; } }
public MineCell[,] BuildMineCells()
{
return cells;
}
}
public class BoardFileLoader : IMineBoardBuilder
{
private MineCell[,] cells;
private int totalMines;
private int markedMines;
public int TotalMines { get { return totalMines; } }
public int MarkedMines { get { return markedMines; } }
public MineCell[,] BuildMineCells()
{
return cells;
}
}
相應(yīng)的,可以為MineBoard類添加保存游戲進(jìn)展的功能。
在交互方面,也可作如下改進(jìn):
public void WalkNearByCells(int row, int col, MineWalkCallback callback, Predicate<MineCell> match)
{
if (IsValidCell(row, col))
{
callback(ref cells[row, col]);
if (match(cells[row, col]))
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
if (i != 0 || j != 0)
{
WalkNearByCells(row + i, j + i, callback, match);
}
}
}
}
}
}
public void DoAction(IMineBoardAction action)
{
action.Run(this);
}
{
if (IsValidCell(row, col))
{
callback(ref cells[row, col]);
if (match(cells[row, col]))
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
if (i != 0 || j != 0)
{
WalkNearByCells(row + i, j + i, callback, match);
}
}
}
}
}
}
public void DoAction(IMineBoardAction action)
{
action.Run(this);
}
這兩個新增的方法可以將連續(xù)揭開一片區(qū)域、計算相鄰雷數(shù)等操作實現(xiàn)移到MineBoard類外實現(xiàn),這樣就可以進(jìn)一步引入腳本引擎,將一些邏輯實現(xiàn)在腳本中。
項目文件下載:20080319.zip
系列索引:Minesweeper: 索引
浙公網(wǎng)安備 33010602011771號