[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
saper
vilgosДата: Пн, 29 Июн 2015, 19:10 | Сообщение # 1
Старший программист
Группа: Модераторы
Сообщений: 76
Репутация: 0
Статус: 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;
}
 
  • Страница 1 из 1
  • 1
Поиск: