Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <windows.h>
- #include <time.h>
- #include <string>
- #include <fstream>
- using namespace std;
- ofstream fout;
- ifstream fin;
- const int fieldsize = 11;
- struct gamefield {
- char symbol{};
- int number{};
- };
- struct GameState {
- gamefield field[fieldsize][fieldsize]{};
- bool a1{};
- bool a2{};
- bool a3{};
- bool isShot[fieldsize][fieldsize]{};
- int lastHitX{};
- int lastHitY{};
- };
- void savegame(const GameState& state, const string& filename) {
- fout.open(filename);
- if (!fout.is_open()) {
- cout << "Невозможно сохранить игру, попробуйте перенести файл игры в другую папку." << endl;
- return;
- }
- fout << boolalpha << state.a1 << "\n";
- fout << boolalpha << state.a2 << "\n";
- fout << boolalpha << state.a3 << "\n";
- for (int i = 1; i < fieldsize; i++) {
- for (int j = 1; j < fieldsize; j++) {
- fout << state.field[i][j].symbol << " ";
- }
- fout << "\n";
- }
- fout.close();
- }
- GameState loadGame(const string& filename) {
- GameState state;
- ifstream fin(filename);
- if (!fin.is_open()) {
- cout << "Отсутствует файл сохранения игры, или файл находится вне папки игры." << endl;
- return state;
- }
- fin >> boolalpha >> state.a1;
- fin >> boolalpha >> state.a2;
- fin >> boolalpha >> state.a3;
- string line;
- getline(fin, line);
- for (int i = 1; i < fieldsize; i++) {
- getline(fin, line);
- if (line.empty()) break;
- int j = 1;
- for (size_t k = 0; k < line.size() && j < fieldsize; k++) {
- state.field[i][j].symbol = line[k];
- j++;
- }
- }
- fin.close();
- return state;
- }
- void vivod(gamefield(&field)[fieldsize][fieldsize]) {
- for (int i = 0; i < fieldsize; i++) {
- field[0][i + 1].number = i;
- field[i + 1][0].symbol = i + 'А';
- }
- for (int i = 0; i < fieldsize; i++) {
- cout << "|";
- for (int j = 0; j < fieldsize; j++) {
- if (i == 0 && j != 0) {
- cout << field[i][j].number << "\t";
- }
- else if (j == 0 && i != 0) {
- cout << field[i][j].symbol << "\t";
- }
- else if (i != 0 && j != 0) {
- cout << field[i][j].symbol << "\t";
- }
- else {
- cout << " " << "\t";
- }
- if (j <= fieldsize - 1) {
- cout << "|";
- }
- }
- cout << endl;
- cout << "---------------------------------------------------------------------------------------------------" << endl;
- }
- cout << endl;
- }
- bool canPlaceShip(gamefield(&field)[fieldsize][fieldsize], int x, int y, int size, bool horizontal) {
- if (horizontal) {
- if (x + size > fieldsize) return false;
- for (int i = x; i < x + size; i++) {
- if (field[i][y].symbol == 'X') return false;
- }
- for (int i = x - 1; i <= x + size; i++) {
- for (int j = y - 1; j <= y + 1; j++) {
- if (i >= 0 && i < fieldsize && j >= 0 && j < fieldsize && field[i][j].symbol == 'X') return false;
- }
- }
- }
- else {
- if (y + size > fieldsize) return false;
- for (int i = y; i < y + size; i++) {
- if (field[x][i].symbol == 'X') return false;
- }
- for (int i = x - 1; i <= x + 1; i++) {
- for (int j = y - 1; j <= y + size; j++) {
- if (i >= 0 && i < fieldsize && j >= 0 && j < fieldsize && field[i][j].symbol == 'X') return false;
- }
- }
- }
- return true;
- }
- void autofill(gamefield(&field)[fieldsize][fieldsize]) {
- int shipSizes[10] = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
- int shipCount = sizeof(shipSizes) / sizeof(shipSizes[0]);
- for (int i = 0; i < shipCount; i++) {
- while (true) {
- int x = 1 + rand() % (fieldsize - 1);
- int y = 1 + rand() % (fieldsize - 1);
- bool horizontal = rand() % 2 == 0;
- if (canPlaceShip(field, x, y, shipSizes[i], horizontal)) {
- if (horizontal) {
- for (int j = x; j < x + shipSizes[i]; j++) {
- field[j][y].symbol = 'X';
- }
- }
- else {
- for (int j = y; j < y + shipSizes[i]; j++) {
- field[x][j].symbol = 'X';
- }
- }
- break;
- }
- }
- }
- }
- void manualfill(gamefield(&field)[fieldsize][fieldsize]) {
- int shipSizes[10] = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
- int shipCount = sizeof(shipSizes) / sizeof(shipSizes[0]);
- for (int i = 0; i < shipCount; i++) {
- while (true) {
- vivod(field);
- int cifra;
- char bukva;
- bool horizontal;
- cout << "Введите координату для корабля типа ";
- if (shipSizes[i] == 4) {
- cout << "Линкор (X1)" << endl;
- }
- else if (shipSizes[i] == 3) {
- cout << "Крейсер (X2)" << endl;
- }
- else if (shipSizes[i] == 2) {
- cout << "Эсминец (X3)" << endl;
- }
- else if (shipSizes[i] == 1) {
- cout << "Торпедный катер (X4)" << endl;
- }
- cout << "Введите сначала буквенную часть координаты, затем числовую (Например А3): ";
- cin >> bukva >> cifra;
- while (cifra < 0 || cifra > 9) {
- cout << "Некорректный ввод числовой части координаты. Попробуйте снова." << endl;
- cin >> cifra;
- }
- int bukva1;
- if (bukva >= 'А' && bukva <= 'Й') {
- bukva1 = bukva - 'А';
- }
- else {
- while (bukva < 'А' || bukva > 'Й') {
- cout << "Некорректный ввод буквенной части координаты, попробуйте снова" << endl;
- cin >> bukva;
- }
- }
- int x = 1 + bukva1;
- int y = 1 + cifra;
- cout << "Введите 1 для размещения корабля в вертикальном положении, 0 для размещения корабля в горизонтальном положении: " << endl;
- cin >> horizontal;
- if (canPlaceShip(field, x, y, shipSizes[i], horizontal)) {
- if (horizontal) {
- for (int j = x; j < x + shipSizes[i]; j++) {
- field[j][y].symbol = 'X';
- }
- }
- else {
- for (int j = y; j < y + shipSizes[i]; j++) {
- field[x][j].symbol = 'X';
- }
- }
- break;
- }
- else {
- cout << "Невозможно разместить корабль в указанных координатах. Попробуйте еще раз." << endl;
- }
- }
- }
- }
- void playerTurn(gamefield(&field)[fieldsize][fieldsize], gamefield(&enemyField)[fieldsize][fieldsize]) {
- int cifra;
- char bukva;
- cout << "Ваш ход. Введите координаты выстрела: " << endl;
- cout << "Введите сначала буквенную часть координаты, затем числовую (Например А3): ";
- cin >> bukva >> cifra;
- while (cifra < 0 || cifra > 9) {
- cout << "Некорректный ввод числовой части координаты. Попробуйте снова." << endl;
- cin >> cifra;
- }
- int bukva1;
- if (bukva >= 'А' && bukva <= 'Й') {
- bukva1 = bukva - 'А';
- }
- else {
- while (bukva < 'А' || bukva > 'Й') {
- cout << "Некорректный ввод буквенной части координаты, попробуйте снова" << endl;
- cin >> bukva;
- }
- }
- int x = 1 + bukva1;
- int y = 1 + cifra;
- if (enemyField[x][y].symbol == 'X') {
- cout << "Вы попали!" << endl;
- enemyField[x][y].symbol = 'H';
- }
- else if (enemyField[x][y].symbol == ' ') {
- cout << "Вы промахнулись!" << endl;
- enemyField[x][y].symbol = 'M';
- }
- else {
- cout << "Вы уже стреляли в эту клетку. Попробуйте снова." << endl;
- return;
- }
- }
- void computerTurn(gamefield(&field)[fieldsize][fieldsize], gamefield(&enemyField)[fieldsize][fieldsize], bool(&isShot)[fieldsize][fieldsize], int& lastHitX, int& lastHitY, bool useAI) {
- int x, y;
- if (useAI && lastHitX != 0 && lastHitY != 0) {
- if (lastHitX - 1 >= 1 && field[lastHitX - 1][lastHitY].symbol != 'M' && !isShot[lastHitX - 1][lastHitY]) {
- x = lastHitX - 1;
- y = lastHitY;
- }
- else if (lastHitX + 1 < fieldsize && field[lastHitX + 1][lastHitY].symbol != 'M' && !isShot[lastHitX + 1][lastHitY]) {
- x = lastHitX + 1;
- y = lastHitY;
- }
- else if (lastHitY - 1 >= 1 && field[lastHitX][lastHitY - 1].symbol != 'M' && !isShot[lastHitX][lastHitY - 1]) {
- x = lastHitX;
- y = lastHitY - 1;
- }
- else if (lastHitY + 1 < fieldsize && field[lastHitX][lastHitY + 1].symbol != 'M' && !isShot[lastHitX][lastHitY + 1]) {
- x = lastHitX;
- y = lastHitY + 1;
- }
- else {
- lastHitX = 0;
- lastHitY = 0;
- do {
- x = 1 + rand() % (fieldsize - 1);
- y = 1 + rand() % (fieldsize - 1);
- } while (field[x][y].symbol != ' ' || isShot[x][y]);
- }
- }
- else {
- do {
- x = 1 + rand() % (fieldsize - 1);
- y = 1 + rand() % (fieldsize - 1);
- } while (field[x][y].symbol != ' ' || isShot[x][y]);
- }
- isShot[x][y] = true;
- if (field[x][y].symbol == 'X') {
- cout << "Компьютер попал!" << endl;
- field[x][y].symbol = 'H';
- lastHitX = x;
- lastHitY = y;
- }
- else {
- cout << "Компьютер промахнулся!" << endl;
- field[x][y].symbol = 'M';
- }
- }
- bool checkWin(gamefield(&field)[fieldsize][fieldsize]) {
- for (int i = 1; i < fieldsize; i++) {
- for (int j = 1; j < fieldsize; j++) {
- if (field[i][j].symbol == 'X') {
- return false;
- }
- }
- }
- return true;
- }
- int main() {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- srand(time(NULL));
- GameState currentState;
- bool save, load;
- bool a1, a2, a3;
- int a4, end1;
- for (int i = 0; i < fieldsize; i++) {
- for (int j = 0; j < fieldsize; j++) {
- currentState.field[i][j].symbol = ' ';
- currentState.field[i][j].number = 0;
- currentState.isShot[i][j] = false;
- }
- }
- vivod(currentState.field);
- cout << "Хотите-ли вы загрузить сохранённую игру?" << endl;
- cout << "Введите 0 если нет, введите 1 если да." << endl;
- cin >> load;
- if (load) {
- a2 = 0;
- a3 = 0;
- currentState = loadGame("savefile.txt");
- vivod(currentState.field);
- a2 = currentState.a2;
- a3 = currentState.a3;
- }
- if (load != 1) {
- cout << "Выберите режим расстановки кораблей, введите 0 для автоматической расстановки, введите 1 для ручной расстановки: ";
- cin >> a1;
- if (a1 == 0) {
- autofill(currentState.field);
- cout << "Корабли успешно расставлены!" << endl << endl;
- vivod(currentState.field);
- }
- else if (a1 == 1) {
- manualfill(currentState.field);
- cout << "Корабли успешно расставлены!" << endl << endl;
- vivod(currentState.field);
- }
- while (a1 < 0 || a1 > 1) {
- cout << "Некорретный выбор. Попробуйте ввести другое число." << endl;
- cin >> a1;
- }
- cout << endl << "Выберите режим игры, введите 0 для игры человек-компьютер, введите 1 для игры компьютер-компьютер: ";
- cin >> a2;
- while (a2 < 0 || a2 > 1) {
- cout << "Некорретный выбор. Попробуйте ввести другое число." << endl;
- cin >> a2;
- }
- cout << endl << "Выберите режим работы компьютера в игре, введите 0 для отключения искусственного интеллекта (Случайный выстрел), введите 1 для его включения: ";
- cin >> a3;
- while (a3 < 0 || a3 > 1) {
- cout << "Некорретный выбор. Попробуйте ввести другое число." << endl;
- cin >> a3;
- }
- cout << "Хотите-ли вы сохранить текущие настройки и состояние игры?" << endl;
- cout << "Введите 1 если да, введите 0, если нет." << endl;
- cin >> save;
- if (save) {
- savegame(currentState, "savefile.txt");
- }
- }
- cout << "Что-бы начать игру введите любое число: ";
- cin >> a4;
- if (a2 == 0) {
- gamefield enemyField[fieldsize][fieldsize]{};
- for (int i = 0; i < fieldsize; i++) {
- for (int j = 0; j < fieldsize; j++) {
- enemyField[i][j].symbol = ' ';
- enemyField[i][j].number = 0;
- }
- }
- autofill(enemyField);
- while (true) {
- vivod(currentState.field);
- playerTurn(currentState.field, enemyField);
- if (checkWin(enemyField)) {
- cout << "Вы победили!" << endl;
- break;
- }
- if (a3 == 0) {
- computerTurn(currentState.field, enemyField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, false);
- }
- else {
- computerTurn(currentState.field, enemyField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, true);
- }
- if (checkWin(currentState.field)) {
- cout << "Компьютер победил!" << endl;
- break;
- }
- bool save1;
- cout << endl << "Хотите-ли вы сохранить текущее состояние игры?" << endl;
- cout << "Введите 1 если да, введите 0, если нет." << endl;
- cin >> save1;
- if (save1) {
- savegame(currentState, "savefile.txt");
- }
- }
- }
- else if (a2 == 1) {
- //ГЛЮЧИТ
- gamefield playerField[fieldsize][fieldsize]{};
- gamefield enemyField[fieldsize][fieldsize]{};
- for (int i = 0; i < fieldsize; i++) {
- for (int j = 0; j < fieldsize; j++) {
- playerField[i][j].symbol = ' ';
- playerField[i][j].number = 0;
- enemyField[i][j].symbol = ' ';
- enemyField[i][j].number = 0;
- }
- }
- autofill(playerField);
- autofill(enemyField);
- while (true) {
- vivod(playerField);
- computerTurn(playerField, enemyField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, currentState.a3);
- if (checkWin(enemyField)) {
- cout << "Первый компьютер победил!" << endl;
- break;
- }
- vivod(enemyField);
- computerTurn(enemyField, playerField, currentState.isShot, currentState.lastHitX, currentState.lastHitY, currentState.a3);
- if (checkWin(playerField)) {
- cout << "Второй компьютер победил!" << endl;
- break;
- }
- Sleep(250);
- }
- }
- cout << "Что-бы закрыть программу введите любое число: ";
- cin >> end1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement