Начало игры
В начале игры
нужно расставить мины, затем для каждой клетки поля подсчитать, сколько мин
находится в соседних клетках. Процедура NewGame (ее текст приведен в листинге
15.3) решает эту задачу.
Листинг
15.3. Процедура NewGame
// новая игра — генерирует новое поле
procedure NewGame
();
row,col : integer; // координаты клетки (индексы массива)
n : integer; // количество поставленных мин
k : integer; // кол-во мин в соседних клетках
begin
// Очистим эл-ты массива, соответствующие клеткам
// игрового поля
for row :=1 to MR do
for col :=1 to MC
do Pole[row,col] := 0;
// расставим
мины
Randomize О; //
инициализация ГСЧ
n := 0; // кол-во
мин
repeat
row := Random(MR) + 1;
col := Random(MC) + 1;
if (Pole[row,col]
<> 9) then begin
Pole[row,col] := 9; n := n+1;
end;
until (n =
NM);
// для каждой клетки вычислим // кол-во мин в соседних клетках
for row := 1 to MR do
for col := 1 to MC
do
if (Pole[row,col] <> 9) then
begin k :=0
;
if Pole[row-l,col-l] = 9
then k = k + 1;
if Pole[row-1,col]
=' 9 then k = k + 1;
if
Pole[row-1,col+1] = 9 then k = k + 1;
if Pole[row,col-1]
= 9 then k = k + 1;
if Pole[row,col+1]
= 9 then k = k + 1;
if
Pole[row+1,col-1] = 9 then k = k + 1;
if Pole[row+1,col]
= 9 then k = k + 1;
if Pole[row+l,col+l] = 9 then k := k + 1;
Pole[row,col] := k;
end;
status := 0; // начало игры
nMin := 0; // нет обнаруженных мин
nFlag := 0; // нет поставленных флагов
end;
После того как
процедура NewGame расставит мины, процедура showPoie (ее текст приведен в
листинге 15.4) выводит изображение игрового поля.
Листинг
15.4. Процедура ShowPole
// Показывает
поле
Procedure ShowPoie(Canvas : TCanvas; status : integer);
var
row,col : integer;
begin
for row := 1 to MR do
for col := 1 to
MC do
Kletka(Canvas, row, col, status);
end;
Процедура
showPoie выводит изображение поля последовательно, клетка за клеткой. Вывод
изображения отдельной клетки выполняет процедура Kletka, ее текст приведен в
листинге 15.5. Процедура Kletka используется для вывода изображения поля в
начале игры, во время игры и в ее конце. В начале игры (значение параметра
status = 0) процедура выводит только контур клетки, во время игры — количество
мин в соседних клетках или флажок, а в конце отображает исходное состояние
клетки и действия пользователя. Информацию о фазе игры процедура Kletka получает
через параметр status.
Листинг
15.5. Процедура Kletka
// выводит на экран
изображение клетки
Procedure Kletka(Canvas : TCanvas;
row, col, status : integer);
var
x,y : integer; // координаты области вывода
begin
x := (col-1)* W + I; у :=
(row-1)* H + 1;
if status = 0
then begin
Canvas.Brush.Color :=
clLtGray;
Canvas.Rectangle(x-1,y-1,x+W,y+H);
exit;
end;
if Pole[row,col] < 100 then
begin
Canvas.Brush.Color := clLtGray; // неоткрытые — серые
Canvas.Rectangle(x-1,y-l,x+W,y+H);
// если игра завершена (status = 2), то показать мины
if (status = 2)
and (Pole[row,col] = 9)
then Mina(Canvas,
x, y) ; exit; end;
// открытая
клетка
Canvas.Brush.Color :=
clWhite; // открытые белые
Canvas.Rectangle(x-1,y-l,x+W,y+H);
if (Pole[row,col] =
100)
then exit; //
клетка открыта, но она пустая
if (Pole[row,col] >= 101)
and (Pole[row,col] <= 108)
then begin // в
соседних клетках есть мины
Canvas.Font.Size :=
14;
Canvas.Font.Color :=
clBlue;
Canvas.TextOut(x+3,y+2,IntToStr(Pole[row,col]
-100));
exit;
end;
if (Pole[row,col] >= 200)
then Flag(Canvas,
x, y);
if (Pole[row,col] = 109)
then // на этой мине подорвались!
begin
Canvas.Brush.Color := clRed;
Canvas.Rectangle(x-1,y-1,x+W,y+H);
end;
if ((Pole[row,col] mod 10) = 9)
and (status = 2)
then
Mina(Canvas, x, y);
end;