Advertisement
nikminer4sv

Untitled

Nov 30th, 2022
722
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 49.78 KB | None | 0 0
  1. #include <iostream> //заголовочный файл с классами, функциями и переменными для организации ввода-вывода в языке программирования C++
  2. #include <time.h> //заглавный файл стандартной библиотеки языка программирования С, содержащий типы и функции для работы с датой и временем.
  3. #include <windows.h> //включает функции WinAPI sleep(), beep() и т.д
  4. #include <conio.h> //библиотека для создания текстового интерфейса пользователя
  5.  
  6. enum Color { Black, Blue, Green, Cyan, Red, Magenta, Brown, LightGray, DarkGray, LightBlue = 9, LightGreen, LightCyan, LightRed, LightMagenta, Yellow, White };
  7. // Цвета которыми можно окрашивать: цвет текста; цвет заливки текста
  8.  
  9. HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //Дескриптор активного окна
  10.  
  11.  
  12. void setColor(Color text, Color background) //функция с помощью которой происходит изменение цвета текста
  13. {
  14.     SetConsoleTextAttribute(hStdOut, (WORD)((background << 4) | text)); //установка параметров текста
  15. }
  16. using namespace std; //пространство имён
  17.  
  18. enum Napravlenie { Up = 72, Left = 75, Right = 77, Down = 80, Enter = 13, escepushka = 27, BackSpace = 8, Q = 113 };
  19. //клавиши, обратиться к которым в коде можно через их имя
  20.  
  21. void SetCursor(int x, int y) //функция для того чтобы устанавливать позицию курсора в консоли по оси Х и Y
  22. {
  23.     COORD myCoords = { x,y }; //инициализация координат
  24.     SetConsoleCursorPosition(hStdOut, myCoords); //Способ перемещения курсора на нужные координаты
  25. }
  26. struct Ships //структура характеристик кораблика
  27. {
  28.     int deck = { 0 }; //количество палуб
  29.     bool horizontal = true; //положение (изначально - горизонтальное)
  30.     bool alive = true; //проверка на то, унчитожен ли кораблик или нет
  31.     int x, y; //Позиции кораблика по "x" и "y" (первая палуба), необходима для правильного уничтожения кораблика
  32. };
  33. void explosion(Ships* characteristic, int ship_pos[12][24], int plus, int& end) //уничтожение кораблкиков и определение победителя в игре
  34. {
  35.     int A = 0; //переменная для правильной зарисовки границы вокруг взоравнного кораблика
  36.     int B = 13; //переменная, которая будет помогать указывать на нужный кораблик
  37.     int C = 0; //переменная, которая хранит количество уничтоженных корабликов (если = 10, то игра завершается)
  38.     bool alive = false; //переменная с помощью которой мы будем проверять уничтожение корабликов
  39.     for (size_t n = 13; n > 3; n--) //проверяем все номерки корабликов на наличие их в массиве
  40.     {
  41.         for (size_t i = 1; i < 11; i++) //проганяем массив по строчкам
  42.         {
  43.             for (size_t r = 2; r < 22; r++) //проганяем массив по столбцам
  44.             {
  45.                 if (ship_pos[i][r] == n) //проверяем, есть ли в массиве хоть один номерок с корабликом
  46.                 {
  47.                     alive = true; //в случае успеха - кораблик жив/ранен
  48.                     i = 11; //меняем значение чтобы перейти к следуещему номерку
  49.                     break; //выходим из цикла
  50.                 }
  51.             }
  52.         }
  53.         if (alive == false) //если номерок найден не был, то говорим, что кораблик которому был присвоен этот номер уничтожен
  54.         {
  55.             characteristic[B - n + plus].alive = false; //говорим что данный кораблик уничтожен
  56.         }
  57.         else //иначе
  58.         {
  59.             alive = false; //меняем данную переменную на "false", чтобы проверить следующий кораблик
  60.         }
  61.     }
  62.     for (size_t i = plus; i < 10 + plus; i++) //запускаем цикл, в котором будем проверять все кораблики одной команды на уничтожение
  63.     {
  64.         if (i == 0 || i == 10) //для 4-х палубных
  65.         {
  66.             A = 0; //меняем значение переменной для правильной отрисовки
  67.         }
  68.         else if (i == 1 || i == 2 || i == 11 || i == 12)  //для 3-х палубных
  69.         {
  70.             A = 1; //меняем значение переменной для правильной отрисовки
  71.         }
  72.         else if (i > 2 && i < 6 || i > 12 && i < 16)  //для 2-х палубных
  73.         {
  74.             A = 2; //меняем значение переменной для правильной отрисовки
  75.         }
  76.         else  //для 1-о палубных
  77.         {
  78.             A = 3; //меняем значение переменной для правильной отрисовки
  79.         }
  80.         if (characteristic[i].alive == false) //если данный кораблик уничтожен
  81.         {
  82.             if (characteristic[i].horizontal == true) //если он имеет горизонтальное положение
  83.             {
  84.                 for (size_t q = 0; q < 3; q++) //выполнеям нижеуказанный код 3 раза так как нам необходимо окупировать кораблик чтобы они не стояли вполтную к друг другу
  85.                 {
  86.                     for (size_t w = 0; w < characteristic[i].deck * 3 + A; w++) //выполнеям нижеуказанный код нужное количество раз (для каждого отдельно считаем), чтобы "окупировать" уничтоженный кораблик
  87.                     {
  88.                         ship_pos[characteristic[i].y - 2 + q][characteristic[i].x - 4 + w] = 2; //меняем значение "окупируемых" позиций в двумерном массиве который будем прверять на различные цифорки, на "2" (промах)
  89.                     }
  90.                 }
  91.                 for (size_t g = 0; g < 2 * characteristic[i].deck; g++) //выполнеям нижеуказанный код нужное количество раз (для каждого отдельно считаем), чтобы выделить уничтоженный кораблик
  92.                 {
  93.                     ship_pos[characteristic[i].y - 1][characteristic[i].x - 2 + g] = 3; //меняем значение "окупируемых" позиций в двумерном массиве который будем прверять на различные цифорки, на "3" (поподание)
  94.                 }
  95.             }
  96.             else if (characteristic[i].horizontal == false)  //если он имеет вертикальное положение
  97.             {
  98.                 for (size_t q = 0; q < characteristic[i].deck + 2; q++) //выполнеям нижеуказанный код 3 раза так как нам необходимо окупировать кораблик чтобы они не стояли вполтную к друг другу
  99.                 {
  100.                     for (int w = -4; w < 2; w++)  //выполнеям нижеуказанный код нужное количество раз (для каждого отдельно считаем), чтобы "окупировать" уничтоженный кораблик
  101.                     {
  102.                         ship_pos[characteristic[i].y - 2 + q][characteristic[i].x + w] = 2; //меняем значение "окупируемых" позиций в двумерном массиве который будем прверять на различные цифорки, на "2" (промах)
  103.                     }
  104.                 }
  105.                 for (int g = 0; g < characteristic[i].deck; g++) //выполнеям нижеуказанный код нужное количество раз (для каждого отдельно считаем), чтобы выделить уничтоженный кораблик
  106.                 {
  107.                     for (int n = -2; n < 0; n++) //выполняем нижеуказаныый код 2 раза так как нам нужно поменять значения в массиве для 2-ух клеточек (одной палубы)
  108.                     {
  109.                         ship_pos[characteristic[i].y - 1 + g][characteristic[i].x + n] = 3; //меняем значение "окупируемых" позиций в двумерном массиве который будем прверять на различные цифорки, на "3" (поподание)
  110.                     }
  111.                 }
  112.             }
  113.             C++; // увеличиваем значение счётчика уничтоженных корабликов на 1
  114.         }
  115.     }
  116.     if (C == 10 && plus == 0) //если все наши кораблики уничтожены
  117.     {
  118.         end = 1; //завершаем игру (поражение)
  119.     }
  120.     else if (C == 10 && plus == 10) //если все кораблики врага уничтожены
  121.     {
  122.         end = 2; //завершаем игру (победа)
  123.     }
  124.     else //иначе
  125.     {
  126.         C = 0; //онулдируем счетчик уничтоженных корабликов
  127.     }
  128. }
  129. void LoadCharactShips(Ships* characteristic) //присвоение палуб в соответствии с номером кораблика
  130. {
  131.     for (size_t i = 0; i < 20; i++) //выполнеям нижеуказанный код 20 раз так как общее количество корабликов равно 20
  132.     {
  133.         if (i == 0 || i == 10) //для 4-х палубных
  134.         {
  135.             characteristic[i].deck = 4; //делаем кораблик с 4-мя палубами
  136.         }
  137.         else if (i > 0 && i <= 2 || i > 10 && i <= 12) //для 3-х палубных
  138.         {
  139.             characteristic[i].deck = 3; //делаем кораблик с 3-мя палубами
  140.         }
  141.         else if (i > 2 && i <= 5 || i > 12 && i <= 15) //для 2-х палубных
  142.         {
  143.             characteristic[i].deck = 2; //делаем кораблик с 2-мя палубами
  144.         }
  145.         else if (i > 5 && i <= 9 || i > 15 && i <= 19) ///для 1-о палубных
  146.         {
  147.             characteristic[i].deck = 1; //делаем кораблик с 1-ой палубой
  148.         }
  149.     }
  150. }
  151. void auto_arrangement(Ships* characteristic, int ship_pos[12][24], int plus) //aвтоматическая расстановка корабликов
  152. {
  153.     int y, x, ship = plus; //переменная для координат и номера кораблика
  154.     while (ship < plus + 10) //выполняем нижеуказанный код до тех пор пока, не будут расставлены все 10 корабликов
  155.     {
  156.         characteristic[ship].horizontal = 0 + rand() % 2; //присваиваем рандомную ориентацию
  157.         y = 2 + rand() % 9, x = (1 + rand() % 9) * 2; //присваиваем рандочные координаты (в рамках игровой зоны)
  158.         if (characteristic[ship].horizontal == false && y + characteristic[ship].deck >= 13)
  159.         //проверяем заденит ли кораблик границу по вертикале при перевороте, если его не отодвинуть
  160.         {
  161.             y -= y + characteristic[ship].deck - 12; //если да, то заранее изменем его положение чтобы он не прошел сковзь границы поля по вертикали
  162.         }
  163.         else if (characteristic[ship].horizontal == true && x + characteristic[ship].deck * 2 >= 24)
  164.         //проверяем заденит ли кораблик границу по вертикале при перевороте, если его не отодвинуть
  165.         {
  166.             x -= (x + characteristic[ship].deck * 2) - 22; //если да, то заранее изменем его положение чтобы он не прошел сковзь границы поля по вертикали
  167.         }
  168.         if (characteristic[ship].horizontal == true && ship_pos[y - 1][x] == 0 && ship_pos[y - 1][x + characteristic[ship].deck * 2 - 2] == 0)
  169.         // проверемя имеет ли кораблик горизонтальное положение и нет ли ничего на позициях куда он будет устанавливаться
  170.         {
  171.             characteristic[ship].x = x + 2, characteristic[ship].y = y; //запоминаем координаты первой палубы у каждого кораблика, чтобы в дальнейшем правильно их взрывать
  172.             for (size_t q = 0; q < 3; q++) //выполнеям нижеуказанный код 3 раза так как нам необходимо "окупировать" кораблик чтобы они не стояли вполтную к друг другу
  173.             {
  174.                 for (size_t w = 1; w < characteristic[ship].deck * 3 + 1; w++)//выполнеям нижеуказанный код нужное количество раз (для каждого отдельно считаем), чтобы "окупировать" уничтоженный кораблик
  175.                 {
  176.                     ship_pos[y - 2 + q][x - 3 + w] = 1;  //меняем значение "окупируемых" позиций в двумерном массиве который будем прверять на различные цифорки, на "1" (окупируемая позиция живого кораблика)
  177.                 }
  178.             }
  179.             for (int g = 0; g < 2 * characteristic[ship].deck; g++) //выполнеям нижеуказанный код нужное количество раз (для каждого отдельно считаем), чтобы выделить уничтоженный кораблик
  180.             {
  181.                 ship_pos[y - 1][x + g] = 13 - ship + plus;  //меняем значение позиций в двумерном массиве который будем прверять на различные цифорки, на "4-13" (номера корабликов (у каждого свой))
  182.             }
  183.             ship++; //переходим к следующему кораблику
  184.         }
  185.         if (characteristic[ship].horizontal == false && ship_pos[y - 1][x] == 0 && ship_pos[y + characteristic[ship].deck - 2][x] == 0)
  186.         // проверемя имеет ли кораблик горизонтальное положение и нет ли ничего на позициях куда он будет устанавливаться
  187.         {
  188.             characteristic[ship].x = x + 2, characteristic[ship].y = y;//запоминаем координаты первой палубы у каждого кораблика, чтобы в дальнейшем правильно их взрывать
  189.             for (size_t q = 0; q < characteristic[ship].deck + 2; q++)
  190.             {
  191.                 for (size_t w = 0; w < 6; w++)
  192.                 {
  193.                     ship_pos[y - 2 + q][x - 2 + w] = 1; //меняем значение "окупируемых" позиций в двумерном массиве который будем прверять на различные цифорки, на "1" (окупируемая позиция живого кораблика)
  194.                 }
  195.             }
  196.             for (int g = 0; g < characteristic[ship].deck; g++)
  197.             {
  198.                 for (int n = 0; n < 2; n++) //выполняем нижеуказаныый код 2 раза так как нам нужно поменять занчения в массиве для 2-ух клеточек (одной палубы)
  199.                 {
  200.                     ship_pos[y - 1 + g][x + n] = 13 - ship + plus; //меняем значение позиций в двумерном массиве который будем прверять на различные цифорки, на "4-13" (номера корабликов (у каждого свой))
  201.                 }
  202.             }
  203.             ship++; //переходим к следующему кораблику
  204.         }
  205.     }
  206. }
  207. void PaintPos(int mas[12][24], int x, int num_color) //прорисовка игровой карты в соответсвии с положением поставленных корабликов
  208. {
  209.     for (size_t i = 1; i < 11; i++) //выполнеям нижеуказанный код 10 раз так как общее количество строк равно 10
  210.     {
  211.         int y = 1 + i; //уставнавливаем координаты по умолчанию 2 по Х и 2 по Y так как отрисовка поля должно начинаться там
  212.         SetCursor(x, y); //перемещаем курсор на вышеуказанные позиции
  213.  
  214.         for (size_t g = 2; g < 22; g++)  //выполнеям нижеуказанный код 20 раз так как общее количество столбцов равно 20
  215.         {
  216.             if (mas[i][g] == 2) //если в массиве на этом месте находится "2"
  217.             {
  218.                 setColor(LightGray, LightGray); //рисуем серую клеточку
  219.             }
  220.             else if (mas[i][g] == 3) //если в массиве на этом месте находится "3"
  221.             {
  222.                 setColor(LightMagenta, LightMagenta); //рисуем клеточку непонятного цвета
  223.             }
  224.             else if (mas[i][g] >= 4) //если в массиве на этом месте находится "4+"
  225.             {
  226.                 setColor(Color(num_color), Color(num_color)); //устанавливаем цвет корабликов (наши - черные / врага - белые)
  227.             }
  228.             else //в иных случаях рисуем белую клеточку
  229.             {
  230.                 setColor(White, White); //устанавливаем белый цвет так как таким цветом будет игровая локация на которой будут происходить основные действия
  231.             }
  232.             cout << "+"; //рисуем любой знак, из-за окраски он будет квадратиком
  233.         }
  234.         cout << "\n"; //переход на новую строку при отрисовки одной строки полностью
  235.     }
  236. }
  237. void Avake() //функция которая будет показана игроку самая первая
  238. {
  239.     setColor(White, LightBlue); //Устанавливаем цвет текста (белый на голубом)
  240.     SetCursor(24, 12); //устанавливаем позицию курсора (на своё усмотренние)
  241.     cout << "МОРСКОЙ БОЙ"; //выводим надпись на экран
  242. }
  243. void CreatField(int speed, int X, int num_color) //Функция благодоря которой будет отрисовываться игровое поле
  244. {
  245.     SetCursor(X, 1); //Устанавливаем курсор на нужную позицию
  246.     char mas[10] = { 'А','Б','В','Г','Д','Е','Ж','З','И','К' }; //буковки которые будут находится сверху игрового поля и ориентировать игрока куда он бьёт
  247.     setColor(White, Color(num_color)); //Смена цвета (буква - белый; заливка - красный/синий)
  248.     int A = 0, B = 0; //переменные необходимые для правильной отрисовки игрового поля
  249.     cout << "  " << mas[0]; //С помощью этого печатаем букву "А"и ставим в начале пробел чтобы было ровненько и красиво
  250.     for (size_t i = 0; i < 12; i++) //выполнеям нижеуказанный код 12 раз так как общее количество строк равно 12
  251.     {
  252.         if (B == 0) //гениальная проврека, которая сработает один раз
  253.         {
  254.             SetCursor(X + 3, 1 + i); //Устанавливаем курсор на нужную позицию
  255.             B++; //увеличиваем значение переменной
  256.         }
  257.         else //иначе
  258.         {
  259.             SetCursor(X, 1 + i);  //Устанавливаем курсор на нужную позицию
  260.         }
  261.         for (size_t g = 0; g < 23; g++) //выполнеям нижеуказанный код 23 раз так как общее количество столбцов равно 23
  262.         {
  263.             if (i == 0 && g == 22) //выполняем ниэеуказанный код, если мы на первой строке, и 22 элементе
  264.             {
  265.                 setColor(Color(num_color), Color(num_color)); //Меняем цвет текста и заливки на красный/синий (границы поля на которых нету цифр ил букв)
  266.                 Sleep(speed); //Задержка чтобы была анимация
  267.                 cout << '+'; //рисуем любой знак, из-за окраски он будет квадратиком
  268.             }
  269.             if (i == 0 && g > 0 && g < 10) //выполняем ниэеуказанный код, если мы на первой строке, и в диапозоне с 0-го по 10-ый элемент
  270.             {
  271.                 setColor(White, Color(num_color)); //Смена цвета (буква - белый; заливка - красный/синий)
  272.                 Sleep(speed); //Задержка чтобы была анимация
  273.                 cout << " " << mas[g]; //Пишем пробел, и букву которая стоит на месте элемента номер которого равен значению "g"
  274.             }
  275.             else if (i > 0 && i < 11 && g == 0) //Иначе если мы находимся с 0-ой по 11-ую строку на 0-м элементе
  276.             {
  277.                 setColor(White, Color(num_color)); //Смена цвета (буква - белый; заливка - красный/синий)
  278.                 if (i < 10) //Если мы находимся на строках не достигающих значения "10"
  279.                 {
  280.                     Sleep(speed); //Задержка чтобы была анимация
  281.                     cout << i << ' '; //Пишим цифру указывающая на номер строки которая будет помагать игроку ориентироваться куда он стреляет () для того чтобы было ровно по соотношению с двузначными цифрами
  282.                 }
  283.                 else //иначе
  284.                 {
  285.                     Sleep(speed); //Задержка чтобы была анимация
  286.                     cout << i; //Пишем цифру без пробелов так как тут они не будут нужны ведь цифра которая будет выводиться "10"
  287.                 }
  288.             }
  289.             else if (i == 11 || g > 20 && g < 23) //Иначе если мы находимся на 11-ой строке, на 21-22-ых элементах
  290.             {
  291.                 if (A == 0 && i == 11) //проверка на последней строке которая нужна чтобы выводился кубик который не выводится самостоятельно
  292.                 {
  293.                     Sleep(speed); //Задержка чтобы была анимация
  294.                     cout << "+";//рисуем любой знак, из-за окраски он будет квадратиком
  295.                     A++; //меняем значение переменной благодаря которой было можно реализовать дорисовку нужного кубика
  296.                 }
  297.                 setColor(Color(num_color), Color(num_color)); //Меняем цвет текста и заливки на красный/синий (границы поля на которых нету цифр ил букв)
  298.                 Sleep(speed); //Задержка чтобы была анимация
  299.                 cout << '+'; //рисуем любой знак, из-за окраски он будет квадратиком
  300.             }
  301.             else if (i > 0) //если мы находимся на строке номер которой не равен "0" (непосредственно игровое поле)
  302.             {
  303.                 Sleep(speed); //Задержка чтобы была анимация
  304.                 setColor(White, White); //Меняем цвет текста и заливки на белый (непосредственно игровое поле)
  305.                 cout << '+'; //рисуем любой знак, из-за окраски он будет квадратиком
  306.             }
  307.         }
  308.     }
  309.     setColor(Black, Black); //устанавливаем полностью черный цвет
  310. }
  311. void Paint(char variant[2][30], int T) //меню выбора расстановки
  312. {
  313.     system("cls"); //очищаем консоль
  314.     for (size_t i = 0; i < 2; i++) //создаём цикл для 2-ух элементов
  315.     {
  316.         SetCursor(30, 6 + i); //Устанавливаем курсор на нужную позицию
  317.         for (size_t p = 0; p < 30; p++) //создаём цикл для всех 30-ти буковок
  318.         {
  319.             if (i == T) //проверка на выбранный пункт
  320.             {
  321.                 setColor(Black, White); //выделяем выбранный пункт
  322.             }
  323.             else //иначе
  324.             {
  325.                 setColor(White, Black); //убираем выделение выбранного пункта
  326.             }
  327.             cout << variant[i][p]; //выводим пункты в виде тектса
  328.         }
  329.     }
  330.     CreatField(0, 0, 9); //создаём игровое поле занаво
  331. }
  332. void Meny(int num)
  333. {
  334.     char variant[11][40] = { "ВРАГ ДУМАЕТ КУДА УДАРИТЬ...","ВРАГ ПРОМАЗАЛ!", "ВРАГ ПОПАЛ!", "ВРАГ ПОБЕДИЛ... НЕ ГРУСТИ...", "ТВОЙ ХОД." , "ТЫ ПРОМАЗАЛ...", "ТЫ ПОПАЛ!", "ТЫ ПОБЕДИЛ, ПОЗДРАВЛЯЮ!", "+++++++++++++++++++++++++++++++++++++++", "ТЫ ПОПАЛ, ХОДИ СНОВА!", "ЮХУ, ТЫ УНИЧТОЖИЛ ВРАЖЕСКИЙ КОРАБЛИК!" };
  335.     //список вариантов реплик которые могут вывестись во время игры
  336.     SetCursor(22, 15); //Устанавливаем курсор на нужную позицию
  337.     setColor(Black, Black); //устанавливаем полностью черный цвет
  338.     for (size_t i = 0; i < 25; i++) //цикл для стирание предыдущего текста
  339.     {
  340.         cout << variant[10][i]; //выводим "+"
  341.         cout << variant[10][i]; //выводим "+"
  342.     }
  343.     SetCursor(22, 15); //Устанавливаем курсор на нужную позицию
  344.     if (num > 0 && num < 4) //проверяем, если реплики больше относятся к врагу
  345.     {
  346.         setColor(Red, Black); //Устанавливаем красный цвет текста на черном фоне
  347.     }
  348.     else //иначе реплики больше относятся ко мне
  349.     {
  350.         setColor(Green, Black); //Устанавливаем зеленый цвет текста на черном фоне
  351.     }
  352.     for (size_t i = 0; i < 30; i++) //создаём цикл для всех 30-ти буковок
  353.     {
  354.         cout << variant[num][i];  //выводим реплики в виде тектса
  355.     }
  356. }
  357. int main() //Функция из которой буду вызываться другие и осуществляться инициализация переменых и расстановка корабликов
  358. {
  359.     setlocale(LC_ALL, "Russian"); //Делаем возможным вывод в консоль на русском языке
  360.     srand(time(NULL)); //онулирование рандомного значения
  361.     char variant[2][30] = { "АВТОМАТИЧЕСКАЯ РАССТАНОВКА","РУЧНАЯ РАССТАНОВКА" };
  362.     int ship_pos[12][24] = { 0 }; //двумерный массив благодоря которому можно будет отслеживать:
  363.     int enemy_ship_pos[12][24] = { 0 }; //двумерный массив благодоря которому можно будет отслеживать:
  364.     /*
  365.     0 - свободныем места (куда можно ставить)
  366.     1 - позиции возле корабликов (куда нельзя ставить)
  367.     2 - место куда попал снаряд но где ничего не было
  368.     3 - место где был снаряд и находился кораблик
  369.     4 - 1-о палубный кораблик (1-ый)
  370.     5 - 1-о палубный кораблик (2-ой)
  371.     6 - 1-о палубный кораблик (3-ий)
  372.     7 - 1-о палубный кораблик (4-ый)
  373.     8 - 2-х палубный кораблик (1-ый)
  374.     9 - 2-х палубный кораблик (2-ой)
  375.     10 - 2-х палубный кораблик (3-ий)
  376.     11 - 3-х палубный кораблик (1-ый)
  377.     12 - 3-х палубный кораблик (2-ой)
  378.     13 - 4-х палубный кораблик (первый и единственный)
  379.     */
  380.     Ships* characteristic = new Ships[20]; //создаём 10-ть корабликов характеристики которых описаны в структуре
  381.     LoadCharactShips(characteristic); //загрука характеристик корабликов (изначальное положение и количество палуб)
  382.     int key = 1, y = 2, x = 2, num = 0, change = 1, A = 0, xx = 37, yy = 2, up = 0, down = 0, over = 0;
  383.     bool manual_placement = true, your_turn = 0 + rand() % 2, start = false; //переменные для:
  384.     /*
  385.     key - переменная для записи нажатой клавиши
  386.     start - переменная для проверки на начало боя
  387.     speed - скорость прорисовки игрового поля
  388.     А - дополнительная переменная для меню
  389.     SN - переменная для того чтобы запоминать какой кораблки мы стараемся добить.
  390.     up - переменная которая поможет правильно добивать наши кораблики
  391.     down - переменная которая поможет правильно добивать наши кораблики
  392.     xx - дополнительная перемнная для записи положения курсора на вражеском поле
  393.     yy - дополнительная перемнная для записи положения курсора на вражеском поле
  394.     y - позиция по Y
  395.     x - позиция по X
  396.     change - номер расстановки который будет использован
  397.     num - номер кораблкиа
  398.     manual_placement - тип расстановки который будет использован
  399.     */
  400.     Avake(); //Вывыдим надпись "МОРСКОЙ БОЙ" на экран
  401.     Sleep(1500); //ждём 1.5 секунды
  402.     setColor(White, Black); //Устанавливаем цвет текста (белый на голубом)
  403.     system("cls"); //очищяем консоль
  404.     CreatField(1, 0, 9); //создаём игровое поле
  405.     Paint(variant, change);
  406.     do //запускаем цикл
  407.     {
  408.         key = _getch(); //получаем номер нажатой клавиши
  409.         switch (key) //запускаем свитч
  410.         {
  411.         case Up: //если нажали "Стрелочка вверх"
  412.             if (y > 0) //если "y" больше 0
  413.             {
  414.                 y--; //вычитаем из значение по "y" 1
  415.                 change = y; //выбранный пункт
  416.                 Paint(variant, change); //вывод пунктов на экран
  417.             }
  418.             break;
  419.         case Down: //если нажали "Стрелочка вниз"
  420.             if (y < 1) //если "y" меньше 1
  421.             {
  422.                 y++; //прибавляем к значению по "y" 1
  423.                 change = y; //выбранный пункт
  424.                 Paint(variant, change); //вывод пунктов на экран
  425.             }
  426.             break;
  427.         case Enter:
  428.             do
  429.             {
  430.                 switch (change)
  431.                 {
  432.                 case 0: // ксли 0
  433.                     manual_placement = false; //автоматическая расстанвкоа
  434.                     A++; //чтобы заврешить цикл
  435.                     break;
  436.                 case 1:
  437.                     manual_placement = true; //ручная расстановка
  438.                     A++; //чтобы заврешить цикл
  439.                     y++; //прибавляем к значению по "y" 1
  440.                     break;
  441.                 }
  442.             } while (key != Enter);
  443.         }
  444.     } while (A < 1);
  445.     system("cls"); //очищяем консоль
  446.     CreatField(0, 0, 9); //создаём игровое поле
  447.     x = 2, y = 2;
  448.     if (manual_placement == false) //если выбрана автоматическая расстановка
  449.     {
  450.         auto_arrangement(characteristic, ship_pos, 0); //передаём необходимые значения для того что автоматически расставить кораблки
  451.         PaintPos(ship_pos, 2, 0); //перерисовываем игровую локации с учетём внесенных изменений (поставили кораблик
  452.         start = true; //начинаем игру
  453.     }
  454.     else if (manual_placement == true && num < 10) //ручная расстановка
  455.     {
  456.         do //запускаем цикл в котором при нажатии на ту или иную клавишу будеи делать то или иное дейстивие
  457.         {
  458.             PaintPos(ship_pos, 2, 0); //перерисовываем игровую локации с учетём внесенных изменений (поставили кораблик)
  459.             SetCursor(x, y); //ставим курсор на позицию изменяемых ниже переменных (X, Y)
  460.             setColor(Black, Black); //устанавливаем черный цвет так как таким цветом будет выводиться кораблик
  461.             if (characteristic[num].horizontal == true) //если кораблик имеет горизонтальное положение
  462.             {
  463.                 for (size_t i = 0; i < characteristic[num].deck; i++) //запускаем цикл который будет отрисовыввать кораблик с нужным колличеством палуб
  464.                 {
  465.                     cout << "++"; //2 "+" так как одна клеточка в ширину в игре равна 2-ум клеточкам в ширину в консоли
  466.                 }
  467.             }
  468.             else if (characteristic[num].horizontal == false)
  469.             {
  470.                 y += characteristic[num].deck; //изменяем позицию по "y" на то сколько палуб у кораблика
  471.                 for (size_t i = 0; i < characteristic[num].deck; i++)  //запускаем цикл который будет отрисовыввать кораблик с нужным колличеством палуб
  472.                 {
  473.                     cout << "++"; //2 "+" так как одна клеточка в ширину в игре равна 2-ум клеточкам в ширину в консоли
  474.                     y--; //спускаемся вниз на одну клеточку
  475.                     SetCursor(x, y); //устанавливаем позицию на одну клеточку ниже и на изначальное по Х
  476.                 }
  477.             }
  478.             key = _getch();//функция возвращает номер нажатой клавиши
  479.             switch (key) //Выполняем различные функции в соответствии с нажатой клавишью
  480.             {
  481.             case Left: //если нажали "Стрелочка влево"
  482.                 if (x > 3) //позиция до которой разрешено перемещение в лево
  483.                 {
  484.                     x -= 2; //меняем значение по Х на -2 так как одна клеточка в игре равна двум в консоли
  485.                 }
  486.                 break;
  487.             case Right: //если нажали "Стрелочка вправо"
  488.                 if (characteristic[num].horizontal == true) //Если кораблик имеет горизонтальное положение
  489.                 {
  490.                     if (x < 22 - characteristic[num].deck * 2) // проверяем не достиг ли он позиции до которой ему можно передвигаться(чтобы он не вышел за границы поля)
  491.                     {
  492.                         x += 2; //меняем значение переменной Х на +2 так как одна клеточка в игре равна двум в консоли
  493.                     }
  494.                 }
  495.                 else  //Если кораблик имеет вертикальное положение
  496.                 {
  497.                     if (x < 20) // проверяем не достиг ли он позиции до которой ему можно передвигаться(чтобы он не вышел за границы поля)
  498.                     {
  499.                         x += 2; //меняем значение переменной Х на +2 так как одна клеточка в игре равна двум в консоли
  500.                     }
  501.                 }
  502.                 break; //закрыли этот кейс
  503.             case Up: //если нажали "Стрелочка вверх"
  504.                 if (y > 2) //позиция до которой разрешено перемещение вверх
  505.                 {
  506.                     y--;  //меняем значение по Y на -1
  507.                 }
  508.                 break; //закрыли этот кейс
  509.             case Down: //если нажали "Стрелочка вних"
  510.                 if (characteristic[num].horizontal == false) //Если кораблик имеет вертикальное положение
  511.                 {
  512.                     if (y < 12 - characteristic[num].deck) // проверяем не достиг ли он позиции до которой ему можно передвигаться (так как он 4-х палубный, и его нужно ограничивать на 3 клеточки ранее)
  513.                     {
  514.                         y++;  //меняем значение по Y на +1
  515.                     }
  516.                 }
  517.                 else
  518.                 {
  519.                     if (y < 11) // проверяем не достиг ли он позиции до которой ему можно передвигаться(чтобы он не вышел за границы поля)
  520.                     {
  521.                         y++;  //меняем значение по Y на +1
  522.                     }
  523.                 }
  524.                 break; //закрыли этот кейс
  525.             case Q: //если нажали "Q"
  526.                 characteristic[num].horizontal = !characteristic[num].horizontal; //изменяем ориентацию кораблика на противоположную
  527.                 if (characteristic[num].horizontal == false && y + characteristic[num].deck >= 13)
  528.                     //проверяем заденит ли кораблик границу по вертикале при перевороте, если его не отодвинуть
  529.                 {
  530.                     y -= y + characteristic[num].deck - 12; //если да, то заранее изменем его положение чтобы он не прошел сковзь границы поля по вертикали
  531.                 }
  532.                 else if (characteristic[num].horizontal == true && x + characteristic[num].deck * 2 >= 24)
  533.                     //проверяем заденит ли кораблик границу по вертикале при перевороте, если его не отодвинуть
  534.                 {
  535.                     x -= (x + characteristic[num].deck * 2) - 22; //если да, то заранее изменем его положение чтобы он не прошел сковзь границы поля по вертикали
  536.                 }
  537.                 for (size_t i = 0; i < 10 - num; i++) //изменяем ориентацию так же и для последующих корабликов
  538.                 {
  539.                     characteristic[num + i].horizontal = characteristic[num].horizontal; // заранее изменяем положение следующего кораблика на то которое мы выбрали сейчас
  540.                 }
  541.                 break; //закрыли этот кейс
  542.             case Enter: //если нажали "Enter"
  543.                 if (characteristic[num].horizontal == true && ship_pos[y - 1][x] == 0 && ship_pos[y - 1][x + characteristic[num].deck * 2 - 2] == 0)
  544.                 {
  545.                     characteristic[num].x = x + 2, characteristic[num].y = y;
  546.                     for (size_t q = 0; q < 3; q++) //выполнеям нижеуказанный код 3 раза так как нам необходимо окупировать кораблик чтобы они не стояли вполтную к друг другу
  547.                     {
  548.                         for (size_t w = 1; w < characteristic[num].deck * 3 + 1; w++) //выполнеям нижеуказанный код 11 раз так как надо чтобы 4-х палубный кораблик полностью окупировался
  549.                         {
  550.                             ship_pos[y - 2 + q][x - 3 + w] = 1; //меняем значение окупируемых позиций в двумерном массиве который будем прверять на различные цифорки, на "1"
  551.                         }
  552.                     }
  553.                     for (int g = 0; g < 2 * characteristic[num].deck; g++) //выполнеям нижеуказанный код 8 раз так как кораблик 4-х палубный, а одна палуба по горизонатали 2 клеточки
  554.                     {
  555.                         ship_pos[y - 1][x + g] = 13 - num;  //меняем значение позиций в двумерном массиве который будем прверять на различные цифорки, на "2"
  556.                     }
  557.                     num++; //переходим к следующему кораблику
  558.                 }
  559.                 if (characteristic[num].horizontal == false && ship_pos[y - 1][x] == 0 && ship_pos[y + characteristic[num].deck - 2][x] == 0)
  560.                 {
  561.                     characteristic[num].x = x + 2, characteristic[num].y = y;
  562.                     for (size_t q = 0; q < characteristic[num].deck + 2; q++) //выполнеям нижеуказанный код 6 раз так как нам необходимо окупировать кораблик чтобы они не стояли вполтную к друг другу
  563.                     {
  564.                         for (size_t w = 0; w < 6; w++) //выполнеям нижеуказанный код 6 раз так как нам необходимо окупировать кораблик чтобы они не стояли вполтную к друг другу
  565.                         {
  566.                             ship_pos[y - 2 + q][x - 2 + w] = 1; //меняем значение окупируемых позиций в двумерном массиве который будем прверять на различные цифорки, на "1"
  567.                         }
  568.                     }
  569.                     for (int g = 0; g < characteristic[num].deck; g++) //выполнеям нижеуказанный код 3 раза так как кораблик 3-х палубный
  570.                     {
  571.                         for (int n = 0; n < 2; n++) //выполняем нижеуказаныый код 2 раза так как нам нужно поменять занчения в массиве для 2-ух клеточек (одной палубы)
  572.                         {
  573.                             ship_pos[y - 1 + g][x + n] = 13 - num; //меняем значение позиций в двумерном массиве который будем прверять на различные цифорки, на "2"
  574.                         }
  575.                     }
  576.                     num++; //переходим к следующему кораблику
  577.                 }
  578.             }
  579.             start = true;//запускаем игру
  580.         } while (num <= 9); //цикл работает до тех пор пока количество расставленных корабликов не равно 10
  581.     }
  582.     Sleep(20);
  583.     CreatField(1, 35, 4); //создаём игровое поле
  584.     auto_arrangement(characteristic, enemy_ship_pos, 10); //автоматическая расстанвока для вражеских корабликов
  585.     PaintPos(enemy_ship_pos, 37, 15); //отрисовка вражеских кораблей/поля
  586.     do
  587.     {
  588.         if (your_turn == true) //если моя очередь атаковать
  589.         {
  590.             do //запускаем цикл в котором при нажатии на ту или иную клавишу будеи делать то или иное дейстивие
  591.             {
  592.                 x = xx, y = yy; //переменная которая будет запоминать где находился курсор
  593.                 PaintPos(enemy_ship_pos, 37, 15); //перерисовываем игровую локации с учетём внесенных изменений (поставили кораблик)
  594.                 setColor(DarkGray, DarkGray); //устанавливаем черный цвет так как таким цветом будет выводиться кораблик
  595.                 SetCursor(x, y); //ставим курсор на позицию изменяемых ниже переменных (X, Y)
  596.                 cout << "++"; //2 "+" так как одна клеточка в ширину в игре равна 2-ум клеточкам в ширину в консоли
  597.                 key = _getch();//функция возвращает номер нажатой клавиши
  598.                 switch (key) //Выполняем различные функции в соответствии с нажатой клавишью
  599.                 {
  600.                 case Left: //если нажали "Стрелочка влево"
  601.                     if (x > 38) //позиция до которой разрешено перемещение в лево
  602.                     {
  603.                         x -= 2; //меняем значение по Х на -2 так как одна клеточка в игре равна двум в консоли
  604.                         xx = x; //запоминаем положение курсора
  605.                     }
  606.                     break;
  607.                 case Right: //если нажали "Стрелочка вправо"
  608.                     if (x < 55) // проверяем не достиг ли он позиции до которой ему можно передвигаться(чтобы он не вышел за границы поля)
  609.                     {
  610.                         x += 2; //меняем значение переменной Х на +2 так как одна клеточка в игре равна двум в консоли
  611.                         xx = x; //запоминаем положение курсора
  612.                     }
  613.                     break; //закрыли этот кейс
  614.                 case Up: //если нажали "Стрелочка вверх"
  615.                     if (y > 2) //позиция до которой разрешено перемещение вверх
  616.                     {
  617.                         y--;  //меняем значение по Y на -1
  618.                         yy = y; //запоминаем положение курсора
  619.                     }
  620.                     break; //закрыли этот кейс
  621.                 case Down: //если нажали "Стрелочка вних"
  622.                     if (y < 11) //позиция до которой разрешено перемещение вниз
  623.                     {
  624.                         y++;  //меняем значение по Y на +1
  625.                         yy = y; //запоминаем положение курсора
  626.                     }
  627.                     break;
  628.                 case Enter:
  629.                     if (enemy_ship_pos[y - 1][x - 35] >= 4) //проверяем позицию по которой мы выстрельнули на наличие корабликов
  630.                     {
  631.                         for (size_t i = 0; i < 2; i++) //если это так то мызаменяем в клеточке номерок кораблика на "3"
  632.                         {
  633.                             enemy_ship_pos[y - 1][x - 35 + i] = 3; // изменяем значение
  634.                             explosion(characteristic, enemy_ship_pos, 10, over); //проверяем на уничтожение
  635.                         }
  636.                         Meny(9); //вывод реплики на экран
  637.                         Sleep(500); //небольшая пауза
  638.                     }
  639.                     else if (enemy_ship_pos[y - 1][x - 35] < 2) //Если на позиции по которой был произведён огонь ничего нету
  640.                     {
  641.                         for (size_t i = 0; i < 2; i++) //если это так то мызаменяем в клеточке номерок кораблика на "2"
  642.                         {
  643.                             enemy_ship_pos[y - 1][x - 35 + i] = 2; // изменяем значение
  644.                         }
  645.                         Sleep(500); //небольшая пауза
  646.                         Meny(5); //вывод реплики на экран
  647.                         your_turn = false; //очередь атаки противника
  648.                     }
  649.                     break;
  650.                 }
  651.             } while (key != Enter); //выполнять код который демонстрируется в цикл до тех пор пока не нажата клавиша "Enter"
  652.         }
  653.         if (your_turn == false) //если ход противника
  654.         {
  655.             Sleep(0 + rand() % 400); //небольшая пауза
  656.             Meny(0); //вывод реплики на экран
  657.             PaintPos(ship_pos, 2, 0); //перерисовываем наше поле
  658.             Sleep(0 + rand() % 400); //небольшая пауза
  659.             x = (2 + rand() % 10) * 2, y = 2 + rand() % 10; //случайным образом выдаём кооординату по котороой будет происходить атака
  660.             if (ship_pos[y - 1][x - 1] >= 4) //проверяем позицию по которой мы выстрельнули на наличие корабликов
  661.             {
  662.                 for (size_t i = 0; i < 2; i++) //если это так то мызаменяем в клеточке номерок кораблика на "3"
  663.                 {
  664.                     ship_pos[y - 1][x - 2 + i] = 3;  // изменяем значение
  665.                     explosion(characteristic, ship_pos, 0, over); //проверяем на уничтожение
  666.                 }
  667.                 Meny(2); //вывод реплики на экран
  668.                 Sleep(0 + rand() % 750); //небольшая пауза
  669.             }
  670.             else if (ship_pos[y - 1][x - 1] <= 2) //Если на позиции по которой был произведён огонь ничего нету
  671.             {
  672.                 for (size_t i = 0; i < 2; i++) //если это так то мызаменяем в клеточке номерок кораблика на "2"
  673.                 {
  674.                     ship_pos[y - 1][x - 2 + i] = 2; //изменяем значение
  675.                 }
  676.                 Meny(1); //вывод реплики на экран
  677.                 Sleep(0 + rand() % 750); //небольшая пауза
  678.                 your_turn = true; //моя очередь атаки
  679.             }
  680.         }
  681.     } while (over == 0);
  682.     PaintPos(ship_pos, 2, 0);
  683.     PaintPos(enemy_ship_pos, 37, 15); //перерисовываем игровую локации с учетём внесенных изменений (поставили кораблик)
  684.     if (over == 2) //
  685.     {
  686.         Meny(7);
  687.     }
  688.     else
  689.     {
  690.         Meny(3);
  691.     }
  692.     Sleep(500000);
  693. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement