Шаг 123.
Microsoft Visual C++ 2010. Начала.
Игра "Сапер". Начало игры

    На этом шаге мы перечислим подготовительные действия.

    В начале игры программа должна расставить мины и для каждой клетки поля подсчитать, сколько мин находится в соседних клетках. Функция newGame решает эту задачу:

// новая игра 
void newGame() 
{ 
	int row, col; // индексы клетки 
	int n = 0; // количество поставленных мин 
	int k; // количество мин в соседних клетках 
	// очистить поле 
	for (row = 1; row <= MR; row++) 
		for (col = 1; col <= MC; col++) 
			Pole[row,col] = 0; 
	// генератор случайных чисел 
	Random^ rnd = gcnew Random(); 
	// расставим мины 
	do 
	{
		row = rnd->Next(MR) + 1; 
		col = rnd->Next(MC) + 1; 
		if (Pole[row,col] != 9) 
		{
			Pole[row,col] = 9; 
			n++; 
		}
	} 
	while (n != NM); 
	// для каждой клетки вычислим количество 
	// мин в соседних клетках 
	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; // нет поставленных флагов 
}

    Функция showPole выводит изображение поля: последовательно, одну за другой рисует клетки. Вывод изображения отдельной клетки выполняет функция Kletka. Функции showPole и Kletka приведены ниже:

// рисует поле 
void showPole(Graphics^ g, int status) 
{ 
	for (int row = 1; row <= MR; row++) 
		for (int col = 1; col <= MC; col++) 
			this->Kletka(g, row, col, status); 
} 
// рисует клетку 
void Kletka(Graphics^ g, int row, int col, int status) 
{ 
	int x, y; // координаты левого верхнего угла клетки 
	x = (col - 1) * W + 1; 
	y = (row-1)* H + 1; 
	// неоткрытые клетки - серые 
	if (Pole[row,col] < 100) 
		g->FillRectangle(SystemBrushes::ControlLight, 
			x-1, y-1, W, H); 
	// открытые или помеченные клетки 
	if (Pole[row,col] >= 100) { 
		// открываем клетку, открытые - белые 
		if (Pole[row,col] != 109) 
			g->FillRectangle(Brushes::White, x-1, y-1, W, H); 
		else 
			// на этой мине подорвались! 
			g->FillRectangle(Brushes::Red, x-1, y-1, W, H); 
		// если в соседних клетках есть мины, 
		// указываем их количество 
		if ((Pole[row,col] >= 101) && (Pole[row,col] <= 108)) 
			g->DrawString((Pole[row,col]-100).ToString(), 
				gcnew System::Drawing::Font("Tahoma", 10, 
				System::Drawing::FontStyle::Regular), 
				Brushes::Blue, (float)x+3, (float)y+2); 
	}
	// в клетке поставлен флаг 
	if (Pole[row,col] >= 200) 
		this->flag(g, x, y); 
	// рисуем границу клетки 
	g->DrawRectangle(Pens::Black, x-1, y-1, W, H); 
	// если игра завершена (status = 2), показываем мины 
	if ((status == 2) && ((Pole[row,col] % 10) == 9)) 
		this->mina(g, x, y); 
}

    Функция Kletka используется для вывода изображения поля в начале игры, во время игры и в ее конце. В начале игры (значение параметра status равно в этом случае нулю) функция выводит только контур клетки, во время игры — количество мин, находящихся в соседних клетках, или флажок (если в клетка была открыта щелчком правой кнопкой мыши), а в конце игры отображает исходное состояние клетки (если клетка не была открыта) или результат действия игрока. Информацию о фазе игры функция Kletka получает через параметр status.

    На следующем шаге мы рассмотрим действия во время игры.




Предыдущий шаг Содержание Следующий шаг