| vilgos | Дата: Пн, 29 Июн 2015, 19:10 | Сообщение # 1 |
 Старший программист
Группа: Модераторы
Сообщений: 76
Статус: Offline
| Код #include "stdafx.h" #include <iostream> #include <cstdlib> #include <time.h> #include <windows.h> #include <stdio.h>
using namespace std;
//N - размер поля, M - число мин. //#define N 10 //#define M 8 const int N = 10; const int M = 10; //Поле и массив логических значений.
int matrix[N][N]; bool open[N][N];
//Проверяет ячейки на мины, выход за пределы массива возвращает значение false. bool mine(int i, int j) { if ((i >= 0) && (i<N)) { if ((j >= 0) && (j<N)) { if (matrix [i][j]== -1) return true; } } return false; }
//Проверяет ячейку на пустоту (true), выход за пределы массива возвращает false. bool empty(int i, int j) { if ((i >= 0) && (i<N)) { if ((j >= 0) && (j<N)) { if (matrix [i][j]== 0) return true; } } return false; }
//Рекурсивная функция, которая открывает поля в точке попадания. void clean(int i, int j) { //Проверка на выход за пределы массива. if ((i >= 0) && (i<N)) { if ((j >= 0) && (j<N)) { //Проверка, не было-ли открыто поле раньше. if (!open[i][j]) { //Открываем поле. open [i][j]= true; //Если поле пустое (=0), тогда пооткрываем всех его соседей. if (matrix [i][j]== 0) { clean(i - 1, j - 1); clean(i - 1, j); clean(i - 1, j + 1); clean(i, j - 1); clean(i, j + 1); clean(i + 1, j - 1); clean(i + 1, j); clean(i + 1, j + 1); } //Если не пустое (!=0) тогда открываем только пустых (=0) соседей. else { if (empty(i - 1, j - 1)) clean(i - 1, j - 1); if (empty(i - 1, j)) clean(i - 1, j); if (empty(i - 1, j + 1)) clean(i - 1, j + 1); if (empty(i, j - 1)) clean(i, j - 1); if (empty(i, j + 1)) clean(i, j + 1); if (empty(i + 1, j - 1)) clean(i + 1, j - 1); if (empty(i + 1, j)) clean(i + 1, j); if (empty(i + 1, j + 1)) clean(i + 1, j + 1); } } } } }
//Рисует "мину" - звездочку. void coutmine() { cout << "* "; }
//Рисует минное поле с учетом открытых и закрытых полей а так-же их оси. void draw_matrix() { cout << " A B C D E F G H I J\n"; for (int x = 0; x<N; x++) { cout << x << " "; for (int y = 0; y<N; y++) { if (open[x][y]) { if (matrix [x][y]== -1) coutmine(); else if (matrix [x][y]== 0) cout << ". "; else cout << matrix [x][y]<< " "; } else { cout << "# "; } } cout << "\n"; } }
//Функция завершает игру, выведя одну из двух надписей. void fin(bool loser) { COORD coord; coord.X = 33; coord.Y = 10; system("cls"); draw_matrix(); if (loser) { cout << "К сожалению, Вы проиграли!"; } else { cout << "Поздравляем! Вы победили!"; } Sleep(2000); system("cls"); cout << endl; cout << " Желаете сыграть еще раз?\n 1 - выход, другие - да." << endl; int key=_gettch(); if (key == 49) exit(0);
}
//При поражении данная функция открывает все мины на поле. void openmines() { for (int i = 0; i<N; i++) { for (int j = 0; j<N; j++) { if (matrix [i][j]== -1) open [i][j]= true; } } }
//Проверяет, все-ли поле открыто, кроме мин (для победы) bool checkwin() { for (int x = 0; x<N; x++) { for (int y = 0; y<N; y++) { if ((matrix [x][y]!= -1) && (!open[x][y])) return false; } } return true; }
void ShowMenu(int iItem) { system("cls"); printf("*** Добро пожаловать в игру Сапер! ***\n"); printf(" \n%sНачать новую игру\n", iItem == 1 ? "» " : " "); printf("%sОб игре\n", iItem == 2 ? "» " : " "); printf("%sУправление\n", iItem == 3 ? "» " : " "); printf("%sАвторы\n", iItem == 4 ? "» " : " "); printf("%sВыход из игры\n", iItem == 5 ? "» " : " "); printf("\n**************************************************\n"); } void field(){ //Все чистим. for (int c = 0; c<100; c++){ matrix[c / 10][c % 10] = 0; open[c / 10][c % 10] = false; } //Заполняем массив поля минами. int i, j, k = 0; for (int c = 0; c<M; c++) { do { i = rand() % N; j = rand() % N; } while (matrix [i][j]!= 0); matrix [i][j]= -1; } //Заполняем массив поля цифрами. for (i = 0; i<N; i++) { for (j = 0; j<N; j++) { if (matrix [i][j]!= -1) { k = 0; if (mine(i - 1, j - 1)) k++; if (mine(i - 1, j)) k++; if (mine(i - 1, j + 1)) k++; if (mine(i, j - 1)) k++; if (mine(i, j + 1)) k++; if (mine(i + 1, j - 1)) k++; if (mine(i + 1, j)) k++; if (mine(i + 1, j + 1)) k++; matrix [i][j]= k; } } } } int main() { setlocale(LC_ALL, "Rus"); int i, j, k = 0; char s[3]; srand((int)time(NULL));
field(); int iItem = 1; //Отвечает какой пункт меню активен в данный момент int nLast = 5; //Отвечает какой индекс у последнего пункта меню ShowMenu(iItem); while (TRUE) { if (GetAsyncKeyState(VK_UP)) { keybd_event(VK_UP, 0, KEYEVENTF_KEYUP, 0); //Отжимаем кнопку if (0 < iItem - 1) iItem = iItem - 1; else iItem = nLast; ShowMenu(iItem); } if (GetAsyncKeyState(VK_DOWN)) { keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0); //Отжимаем кнопку if (iItem < nLast) iItem = iItem + 1; else iItem = 1; ShowMenu(iItem); } if (GetAsyncKeyState(VK_RETURN)) { keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0); //Отжимаем кнопку ShowMenu(iItem); switch (iItem) { case 1: //Главный цикл игры. while (true) { //Чистка экрана от прошлой игры. system("cls"); //Рисует поле. draw_matrix(); cout << "\n"; //Запрашиваем координаты хода. cout << "Введите координаты. Пример - (A1): "; cin >> s; //Перевод координат в цифровой вид. if ((s[0] >= 65) && (s[0] <= 74)) j = s[0] - 65; //Буква в промежутке от A до J else if ((s[0] >= 97) && (s[0] <= 106)) j = s[0] - 97; //Буква в промежутке от a до j else continue; //Если игрок ввел неверные значения - возвращает в начало цикла. if ((s[1] >= 48) && (s[1] <= 57)) i = s[1] - 48; else continue; //Проверка всех восьми окрестных полей на пустые клетки. //и если надо показываем некий кусок поля ( много пустых клеток ). clean(i, j);
if (mine(i, j)){//Программа покидает цикл в случае проигрыша. openmines(); fin(true); field(); } if (checkwin()){ //Программа покидает цикл в случае победы. fin(false); field(); } } break; case 2: printf("\n Плоское или объёмное игровое поле разделено на смежные ячейки ( квадраты,\n шестиугольники, кубы и т.п. ), некоторые из которых «заминированы».\n Количество «заминированных» ячеек известно. Целью игры является открытие всех\n ячеек, не содержащих мины.\n\n Игрок открывает ячейки, стараясь не открыть ячейку с миной. Открыв ячейку\n с миной, он проигрывает. Мины расставляются после первого хода, поэтому\n проиграть на первом же ходу невозможно. Если под открытой ячейкой мины нет, то в ней появляется число, показывающее, сколько ячеек, соседствующих\n с только что открытой, «заминировано» (в каждом варианте игры соседство\n определяется по - своему);\n\n Используя эти числа, игрок пытается рассчитать расположение мин, однако иногда даже в середине и в конце игры некоторые ячейки всё же приходится открывать\n наугад. Если под соседними ячейками тоже нет мин, то открывается некоторая\n «не заминированная» область до ячеек, в которых есть цифры.\n «Заминированные» ячейки игрок может пометить, чтобы случайно не открыть их.\n Открыв все «не заминированные» ячейки, игрок выигрывает."); break; case 3: printf("\n Ход по координатам. Например: A1; J5; B7 и т.д\n"); break; case 4: printf("\n Разработчики: vilgos & miffa.\n"); break; case 5: exit(0); break; } } } return 0; }
|
| |
|
|