Начало игры
В начале игры надо расставить мины и для каждой клетки поля подсчитать, сколько мин находится в соседних клетках. Функция NewGame (ее текст при-, веден в листинге 10.3), решает эту задачу.
Листинг 10.3. Функция NewGame
// новая игра — генерирует новое поле
void __fastcall NewGame()
{
// Очистим элементы массива, соответствующие отображаемым
// клеткам, а в неотображаемые, по границе игрового поля,
// запишем число -3. Уникальное значение клеток границы
// используется функцией Open для завершения рекурсивного
// процесса открытия соседних пустых клеток.
int row,col;
for (row=0; row <= MR+1; row++)
for (col=0; col <= MC+1; col++)
Pole[row][col] = -3; for (row=l; row <= MR; row++)
for (col=l; col <= MC; col++) Pole[row][col] = 0;
// расставим мины
time_t t;
// используется генератором случайных чисел (ГСЧ)
srand((unsigned) time(&t)); // инициализация ГСЧ
int n = 0; // количество мин
do
{
row = rand() % MR +1; col = randO % MC +1;
if ( Pole [row] [col] ,!= 9)
{
Pole[row][col] = 9; n++; } } while ( n < 10);
// вычисление количества мин в соседних клетках
int k;
for ( row = 1; row <= MR; row++)
for ( col = 1; col <= MC; col++)
if ( Pole[row][col] != 9) { k =0;
if ( Pole[row-1][col-1] == 9) k++;
if ( Pole[row-1][col] == 9) k++;
if ( Pole[row-1][col+1] == 9) k++;
if ( Pole[row][col-1] = 9) k++;
if ( Pole[row][col+1] == 9) k++;
if ( Pole[row+1][col-1] = 9) k++;
if ( Pole[row+1][col] == 9) k++;
if ( Pole[row+1][col+1] == 9) k++;
Pole[row][col] = k;
}
status =0; // начало игры nMin =0;
// нет обнаруженных мин nFlag =0; // нет флагов }
После того как функция NewGame расставит мины, функция showpole (ее текст приведен в листинге 10.4) выводит изображение игрового поля.
Листинг 10.4. Функция ShowPole
// показывает поле
void __fastcall TForml::ShowPole( int status)
{
for ( int row =1; row <= MR; row++)
for ( int col = 1; col <= MC; col++)
Kletka(row, col, status); }
Функция ShowPole выводит изображение поля последовательно, клетка за клеткой. Вывод изображения отдельной клетки выполняет функция Kletka , ее текст приведен в листинге 10.5. Функция Kletka используется для вывода изображения поля в начале игры, во время игры и в ее конце. В начале игры (значение параметра status равно нулю) функция выводит только контур клетки, во время игры — количество мин в соседних клетках или флажок, а в конце она отображает исходное состояние клетки и действия пользователя. Информацию о фазе игры функция Kletka получает через параметр status .
Листинг 10.5. Функция KLetka
// рисует на экране клетку
void __fastcall TForml::Kletka(int row, int col, int status)
{
int x = LEFT + (col-1)* W;
int у = TOP + (row-1)* H;
if (status == 0) // начало игры (
// клетка — серый квадрат
Canvas->Brush->Color = clLtGray;
Canvas->Rectangle (х-1, у-1, x+W, у+Н) ;
return; }
// во время (status = 1)- и в
конце (status = 2) игры
if ( Pole[row][col] < 100)
{
// клетка не открыта
Canvas->Brush->Color = clLtGray;
// не открытые — серые
Canvas->Rectangle(х-1,у-1,x+W,у+Н);
if (status == 2 && Pole.frow] [col] == 9)
Mina( x, у); // игра закончена, показать мину
return; }
// клетка открыта
Canvas->Brush->Color = clWhite;
// открытые белые
Canvas->Rectangle(x-l,y-l,x+W,y+H);
if ( Pole[row][col] == 100) return; // клетка пустая
if ( Pole[row][col] >= 101 &&
Pole[row][col] <= 108) {
Canvas->Font->Size = 14;
Canvas->Font->Color = clBlue;
Canvas->TextOutA(x+3,y+2,IntToStr(Pole[row][col] -100));
return; }
if ( Pole[row][col] >= 200) Flag(x, y) ;
if (Pole[row][col] == 109)
// на этой мине подорвались!
{
Canvas->Brush->Color = clRed;
Canvas->Rectangle(x,y,x+W,y+H);
} if
(( Pole[row][col]% 10 = 9) && (status = 2))
Mina( x, y); }