Начало игры

В начале игры нужно расставить мины, затем для каждой клетки поля подсчитать, сколько мин находится в соседних клетках. Процедура 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;

Игра

Во время игры программа воспринимает нажатия кнопок мыши и, в соответствии с правилами игры, открывает клетки или ставит в клетки флажки.

Основную работу выполняет процедура обработки события onMouseDown (ее текст приведен в листинге 15.6). Сначала процедура преобразует координаты точки, в которой игрок нажал кнопку мыши, в координаты клетки игрового поля. Затем делает необходимые изменения в массиве Pole и, если нажата правая кнопка, рисует в клетке флажок. Если нажата левая кнопка в клетке, в которой нет мины, то эта клетка открывается, на экран выводится ее содержимое. Если нажата левая кнопка в клетке, в которой есть мина, то вызывается процедура showPole, которая показывает все мины, в том числе и те, которые игрок не успел найти.

Листинг 15.6. Обработка события OnMouseDown на поверхности игрового поля

// нажатие кнопки мыши на игровом поле

procedure TForm1.Form1MouseDown(Sender: TObject;

Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

Var

row, col: integer;

Begin

if status = 2 // игра завершена

then exit;

if status = 0 then // первый щелчок

status:= 1;

// преобразуем координаты мыши в индексы

// клетки поля

row:= Trunc(y/H) + 1;

col:= Trunc(x/W) + 1;

if Button = mbLeft then

Begin

if Pole[row,col] = 9 then

begin // открыта клетка, в которой есть мина

Pole[row,col]:= Pole[row,col] + 100;

status:= 2; // игра закончена

ShowPole(Form1.Canvas, status);


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: