Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2024
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <time.h>
  4. #include <string>
  5. #include <fstream>
  6. using namespace std;
  7. ofstream fout;
  8. ifstream fin;
  9. const int fieldsize = 11;
  10. struct gamefield {
  11.     char symbol{};
  12.     int number{};
  13. };
  14. struct GameState {
  15.     gamefield field[fieldsize][fieldsize]{};
  16.     bool a1{};
  17.     bool a2{};
  18.     bool a3{};
  19.     bool isShot[fieldsize][fieldsize]{};
  20.     int lastHitX{};
  21.     int lastHitY{};
  22. };
  23. void savegame(const GameState& state, const string& filename) {
  24.     fout.open(filename);
  25.     if (!fout.is_open()) {
  26.         cout << "Невозможно сохранить игру, попробуйте перенести файл игры в другую папку." << endl;
  27.         return;
  28.     }
  29.     fout << boolalpha << state.a1 << "\n";
  30.     fout << boolalpha << state.a2 << "\n";
  31.     fout << boolalpha << state.a3 << "\n";
  32.     for (int i = 1; i < fieldsize; i++) {
  33.         for (int j = 1; j < fieldsize; j++) {
  34.             fout << state.field[i][j].symbol << " ";
  35.         }
  36.         fout << "\n";
  37.     }
  38.     fout.close();
  39. }
  40. GameState loadGame(const string& filename) {
  41.     GameState state;
  42.     ifstream fin(filename);
  43.     if (!fin.is_open()) {
  44.         cout << "Отсутствует файл сохранения игры, или файл находится вне папки игры." << endl;
  45.         return state;
  46.     }
  47.     fin >> boolalpha >> state.a1;
  48.     fin >> boolalpha >> state.a2;
  49.     fin >> boolalpha >> state.a3;
  50.     string line;
  51.     getline(fin, line);
  52.     for (int i = 1; i < fieldsize; i++) {
  53.         getline(fin, line);
  54.         if (line.empty()) break;
  55.         int j = 1;
  56.         for (size_t k = 0; k < line.size() && j < fieldsize; k++) {
  57.             state.field[i][j].symbol = line[k];
  58.             j++;
  59.         }
  60.     }
  61.     fin.close();
  62.     return state;
  63. }
  64. void vivod(gamefield(&field)[fieldsize][fieldsize]) {
  65.     for (int i = 0; i < fieldsize; i++) {
  66.         field[0][i + 1].number = i;
  67.         field[i + 1][0].symbol = i + 'А';
  68.     }
  69.     for (int i = 0; i < fieldsize; i++) {
  70.         cout << "|";
  71.         for (int j = 0; j < fieldsize; j++) {
  72.             if (i == 0 && j != 0) {
  73.                 cout << field[i][j].number << "\t";
  74.             }
  75.             else if (j == 0 && i != 0) {
  76.                 cout << field[i][j].symbol << "\t";
  77.             }
  78.             else if (i != 0 && j != 0) {
  79.                 cout << field[i][j].symbol << "\t";
  80.             }
  81.             else {
  82.                 cout << " " << "\t";
  83.             }
  84.             if (j <= fieldsize - 1) {
  85.                 cout << "|";
  86.             }
  87.         }
  88.         cout << endl;
  89.         cout << "---------------------------------------------------------------------------------------------------" << endl;
  90.     }
  91.     cout << endl;
  92. }
  93. bool canPlaceShip(gamefield(&field)[fieldsize][fieldsize], int x, int y, int size, bool horizontal) {
  94.     if (horizontal) {
  95.         if (x + size > fieldsize) return false;
  96.         for (int i = x; i < x + size; i++) {
  97.             if (field[i][y].symbol == 'X') return false;
  98.         }
  99.         for (int i = x - 1; i <= x + size; i++) {
  100.             for (int j = y - 1; j <= y + 1; j++) {
  101.                 if (i >= 0 && i < fieldsize && j >= 0 && j < fieldsize && field[i][j].symbol == 'X') return false;
  102.             }
  103.         }
  104.     }
  105.     else {
  106.         if (y + size > fieldsize) return false;
  107.         for (int i = y; i < y + size; i++) {
  108.             if (field[x][i].symbol == 'X') return false;
  109.         }
  110.         for (int i = x - 1; i <= x + 1; i++) {
  111.             for (int j = y - 1; j <= y + size; j++) {
  112.                 if (i >= 0 && i < fieldsize && j >= 0 && j < fieldsize && field[i][j].symbol == 'X') return false;
  113.             }
  114.         }
  115.     }
  116.     return true;
  117. }
  118. void autofill(gamefield(&field)[fieldsize][fieldsize]) {
  119.     int shipSizes[10] = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
  120.     int shipCount = sizeof(shipSizes) / sizeof(shipSizes[0]);
  121.     for (int i = 0; i < shipCount; i++) {
  122.         while (true) {
  123.             int x = 1 + rand() % (fieldsize - 1);
  124.             int y = 1 + rand() % (fieldsize - 1);
  125.             bool horizontal = rand() % 2 == 0;
  126.             if (canPlaceShip(field, x, y, shipSizes[i], horizontal)) {
  127.                 if (horizontal) {
  128.                     for (int j = x; j < x + shipSizes[i]; j++) {
  129.                         field[j][y].symbol = 'X';
  130.                     }
  131.                 }
  132.                 else {
  133.                     for (int j = y; j < y + shipSizes[i]; j++) {
  134.                         field[x][j].symbol = 'X';
  135.                     }
  136.                 }
  137.                 break;
  138.             }
  139.         }
  140.     }
  141. }
  142. void manualfill(gamefield(&field)[fieldsize][fieldsize]) {
  143.     int shipSizes[10] = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
  144.     int shipCount = sizeof(shipSizes) / sizeof(shipSizes[0]);
  145.     for (int i = 0; i < shipCount; i++) {
  146.         while (true) {
  147.             vivod(field);
  148.             int cifra;
  149.             char bukva;
  150.             bool horizontal;
  151.             cout << "Введите координату для корабля типа ";
  152.             if (shipSizes[i] == 4) {
  153.                 cout << "Линкор (X1)" << endl;
  154.             }
  155.             else if (shipSizes[i] == 3) {
  156.                 cout << "Крейсер (X2)" << endl;
  157.             }
  158.             else if (shipSizes[i] == 2) {
  159.                 cout << "Эсминец (X3)" << endl;
  160.             }
  161.             else if (shipSizes[i] == 1) {
  162.                 cout << "Торпедный катер (X4)" << endl;
  163.             }
  164.             cout << "Введите сначала буквенную часть координаты, затем числовую (Например А3): ";
  165.             cin >> bukva >> cifra;
  166.             while (cifra < 0 || cifra > 9) {
  167.                 cout << "Некорректный ввод числовой части координаты. Попробуйте снова." << endl;
  168.                 cin >> cifra;
  169.             }
  170.             int bukva1;
  171.             if (bukva >= 'А' && bukva <= 'Й') {
  172.                 bukva1 = bukva - 'А';
  173.             }
  174.             else {
  175.                 while (bukva < 'А' || bukva > 'Й') {
  176.                     cout << "Некорректный ввод буквенной части координаты, попробуйте снова" << endl;
  177.                     cin >> bukva;
  178.                 }
  179.             }
  180.             int x = 1 + bukva1;
  181.             int y = 1 + cifra;
  182.             cout << "Введите 1 для размещения корабля в вертикальном положении, 0 для размещения корабля в горизонтальном положении: " << endl;
  183.             cin >> horizontal;
  184.             if (canPlaceShip(field, x, y, shipSizes[i], horizontal)) {
  185.                 if (horizontal) {
  186.                     for (int j = x; j < x + shipSizes[i]; j++) {
  187.                         field[j][y].symbol = 'X';
  188.                     }
  189.                 }
  190.                 else {
  191.                     for (int j = y; j < y + shipSizes[i]; j++) {
  192.                         field[x][j].symbol = 'X';
  193.                     }
  194.                 }
  195.                 break;
  196.             }
  197.             else {
  198.                 cout << "Невозможно разместить корабль в указанных координатах. Попробуйте еще раз." << endl;
  199.             }
  200.         }
  201.     }
  202. }
  203. void playerTurn(gamefield(&field)[fieldsize][fieldsize], gamefield(&enemyField)[fieldsize][fieldsize]) {
  204.     int cifra;
  205.     char bukva;
  206.     cout << "Ваш ход. Введите координаты выстрела: " << endl;
  207.     cout << "Введите сначала буквенную часть координаты, затем числовую (Например А3): ";
  208.     cin >> bukva >> cifra;
  209.     while (cifra < 0 || cifra > 9) {
  210.         cout << "Некорректный ввод числовой части координаты. Попробуйте снова." << endl;
  211.         cin >> cifra;
  212.     }
  213.     int bukva1;
  214.     if (bukva >= 'А' && bukva <= 'Й') {
  215.         bukva1 = bukva - 'А';
  216.     }
  217.     else {
  218.         while (bukva < 'А' || bukva > 'Й') {
  219.             cout << "Некорректный ввод буквенной части координаты, попробуйте снова" << endl;
  220.             cin >> bukva;
  221.         }
  222.     }
  223.     int x = 1 + bukva1;
  224.     int y = 1 + cifra;
  225.     if (enemyField[x][y].symbol == 'X') {
  226.         cout << "Вы попали!" << endl;
  227.         enemyField[x][y].symbol = 'H';
  228.     }
  229.     else if (enemyField[x][y].symbol == ' ') {
  230.         cout << "Вы промахнулись!" << endl;
  231.         enemyField[x][y].symbol = 'M';
  232.     }
  233.     else {
  234.         cout << "Вы уже стреляли в эту клетку. Попробуйте снова." << endl;
  235.         return;
  236.     }
  237. }
  238. void computerTurn(gamefield(&field)[fieldsize][fieldsize], gamefield(&enemyField)[fieldsize][fieldsize], bool(&isShot)[fieldsize][fieldsize], int& lastHitX, int& lastHitY, bool useAI) {
  239.     int x, y;
  240.     if (useAI && lastHitX != 0 && lastHitY != 0) {
  241.         if (lastHitX - 1 >= 1 && field[lastHitX - 1][lastHitY].symbol != 'M' && !isShot[lastHitX - 1][lastHitY]) {
  242.             x = lastHitX - 1;
  243.             y = lastHitY;
  244.         }
  245.         else if (lastHitX + 1 < fieldsize && field[lastHitX + 1][lastHitY].symbol != 'M' && !isShot[lastHitX + 1][lastHitY]) {
  246.             x = lastHitX + 1;
  247.             y = lastHitY;
  248.         }
  249.         else if (lastHitY - 1 >= 1 && field[lastHitX][lastHitY - 1].symbol != 'M' && !isShot[lastHitX][lastHitY - 1]) {
  250.             x = lastHitX;
  251.             y = lastHitY - 1;
  252.         }
  253.         else if (lastHitY + 1 < fieldsize && field[lastHitX][lastHitY + 1].symbol != 'M' && !isShot[lastHitX][lastHitY + 1]) {
  254.             x = lastHitX;
  255.             y = lastHitY + 1;
  256.         }
  257.         else {
  258.             lastHitX = 0;
  259.             lastHitY = 0;
  260.             do {
  261.                 x = 1 + rand() % (fieldsize - 1);
  262.                 y = 1 + rand() % (fieldsize - 1);
  263.             } while (field[x][y].symbol != ' ' || isShot[x][y]);
  264.         }
  265.     }
  266.     else {
  267.         do {
  268.             x = 1 + rand() % (fieldsize - 1);
  269.             y = 1 + rand() % (fieldsize - 1);
  270.         } while (field[x][y].symbol != ' ' || isShot[x][y]);
  271.     }
  272.     isShot[x][y] = true;
  273.     if (field[x][y].symbol == 'X') {
  274.         cout << "Компьютер попал!" << endl;
  275.         field[x][y].symbol = 'H';
  276.         lastHitX = x;
  277.         lastHitY = y;
  278.     }
  279.     else {
  280.         cout << "Компьютер промахнулся!" << endl;
  281.         field[x][y].symbol = 'M';
  282.     }
  283. }
  284. bool checkWin(gamefield(&field)[fieldsize][fieldsize]) {
  285.     for (int i = 1; i < fieldsize; i++) {
  286.         for (int j = 1; j < fieldsize; j++) {
  287.             if (field[i][j].symbol == 'X') {
  288.                 return false;
  289.             }
  290.         }
  291.     }
  292.     return true;
  293. }
  294. int main() {
  295.     SetConsoleCP(1251);
  296.     SetConsoleOutputCP(1251);
  297.     srand(time(NULL));
  298.     GameState currentState;
  299.     bool save, load;
  300.     bool a1, a2, a3;
  301.     int a4, end1;
  302.     for (int i = 0; i < fieldsize; i++) {
  303.         for (int j = 0; j < fieldsize; j++) {
  304.             currentState.field[i][j].symbol = ' ';
  305.             currentState.field[i][j].number = 0;
  306.             currentState.isShot[i][j] = false;
  307.         }
  308.     }
  309.     vivod(currentState.field);
  310.     cout << "Хотите-ли вы загрузить сохранённую игру?" << endl;
  311.     cout << "Введите 0 если нет, введите 1 если да." << endl;
  312.     cin >> load;
  313.     if (load) {
  314.         a2 = 0;
  315.         a3 = 0;
  316.         currentState = loadGame("savefile.txt");
  317.         vivod(currentState.field);
  318.         a2 = currentState.a2;
  319.         a3 = currentState.a3;
  320.     }
  321.     if (load != 1) {
  322.         cout << "Выберите режим расстановки кораблей, введите 0 для автоматической расстановки, введите 1 для ручной расстановки: ";
  323.         cin >> a1;
  324.         if (a1 == 0) {
  325.             autofill(currentState.field);
  326.             cout << "Корабли успешно расставлены!" << endl << endl;
  327.             vivod(currentState.field);
  328.         }
  329.         else if (a1 == 1) {
  330.             manualfill(currentState.field);
  331.             cout << "Корабли успешно расставлены!" << endl << endl;
  332.             vivod(currentState.field);
  333.         }
  334.         while (a1 < 0 || a1 > 1) {
  335.             cout << "Некорретный выбор. Попробуйте ввести другое число." << endl;
  336.             cin >> a1;
  337.         }
  338.         cout << endl << "Выберите режим игры, введите 0 для игры человек-компьютер, введите 1 для игры компьютер-компьютер: ";
  339.         cin >> a2;
  340.         while (a2 < 0 || a2 > 1) {
  341.             cout << "Некорретный выбор. Попробуйте ввести другое число." << endl;
  342.             cin >> a2;
  343.         }
  344.         cout << endl << "Выберите режим работы компьютера в игре, введите 0 для отключения искусственного интеллекта (Случайный выстрел), введите 1 для его включения: ";
  345.         cin >> a3;
  346.         while (a3 < 0 || a3 > 1) {
  347.             cout << "Некорретный выбор. Попробуйте ввести другое число." << endl;
  348.             cin >> a3;
  349.         }
  350.         cout << "Хотите-ли вы сохранить текущие настройки и состояние игры?" << endl;
  351.         cout << "Введите 1 если да, введите 0, если нет." << endl;
  352.         cin >> save;
  353.         if (save) {
  354.             savegame(currentState, "savefile.txt");
  355.         }
  356.     }
  357.     cout << "Что-бы начать игру введите любое число: ";
  358.     cin >> a4;
  359.     if (a2 == 0) {
  360.         gamefield enemyField[fieldsize][fieldsize]{};
  361.         for (int i = 0; i < fieldsize; i++) {
  362.             for (int j = 0; j < fieldsize; j++) {
  363.                 enemyField[i][j].symbol = ' ';
  364.                 enemyField[i][j].number = 0;
  365.             }
  366.         }
  367.         autofill(enemyField);
  368.         while (true) {
  369.             vivod(currentState.field);
  370.             playerTurn(currentState.field, enemyField);
  371.             if (checkWin(enemyField)) {
  372.                 cout << "Вы победили!" << endl;
  373.                 break;
  374.             }
  375.             if (a3 == 0) {
  376.                 computerTurn(currentState.field, enemyField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, false);
  377.             }
  378.             else {
  379.                 computerTurn(currentState.field, enemyField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, true);
  380.             }
  381.             if (checkWin(currentState.field)) {
  382.                 cout << "Компьютер победил!" << endl;
  383.                 break;
  384.             }
  385.             bool save1;
  386.             cout << endl << "Хотите-ли вы сохранить текущее состояние игры?" << endl;
  387.             cout << "Введите 1 если да, введите 0, если нет." << endl;
  388.             cin >> save1;
  389.             if (save1) {
  390.                 savegame(currentState, "savefile.txt");
  391.             }
  392.         }
  393.     }
  394.     else if (a2 == 1) {
  395.         //ГЛЮЧИТ
  396.         gamefield playerField[fieldsize][fieldsize]{};
  397.         gamefield enemyField[fieldsize][fieldsize]{};
  398.         for (int i = 0; i < fieldsize; i++) {
  399.             for (int j = 0; j < fieldsize; j++) {
  400.                 playerField[i][j].symbol = ' ';
  401.                 playerField[i][j].number = 0;
  402.                 enemyField[i][j].symbol = ' ';
  403.                 enemyField[i][j].number = 0;
  404.             }
  405.         }
  406.         autofill(playerField);
  407.         autofill(enemyField);
  408.         while (true) {
  409.             vivod(playerField);
  410.             computerTurn(playerField, enemyField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, currentState.a3);
  411.             if (checkWin(enemyField)) {
  412.                 cout << "Первый компьютер победил!" << endl;
  413.                 break;
  414.             }
  415.             vivod(enemyField);
  416.             computerTurn(enemyField, playerField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, currentState.a3);
  417.             if (checkWin(playerField)) {
  418.                 cout << "Второй компьютер победил!" << endl;
  419.                 break;
  420.             }
  421.             Sleep(250);
  422.         }
  423.     }
  424.     cout << "Что-бы закрыть программу введите любое число: ";
  425.     cin >> end1;
  426. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement