с++ “морской бой”

159
14 июля 2019, 05:30

Загорелся сделать морской бой на с++ чисто для себя (с++ еще осваиваю). Сделал так чтоб программа ставила метку на нужных координатах. Вопрос такой: "Как сделать так, чтоб программа зпоминала прошлый "ход" и в следующий раз выписывала то место, где "ход" уже имел место быть".

Описание проблемы не лучшее, но я старался. Сам код (надеюсь, правильно вставил на сайт)

#include <iostream>
#include <iomanip>
using namespace std;
void tablica(int a,int b,int c,int d, int x, int y){
    for (int i=0; i<b; i++){
        for (int z=0; z<a; z++){
            if (i==0){
                if (z==0) cout <<"%" <<setw(3);
                else {
                    cout << setw(3) <<char(c);
                    c++;
                }
            }
            else if (z==0) {
                cout << d << setw(3);
                d++;    
            }
            else if (z==x && i==y) cout << setw(3) << "X";
            else cout << setw(3) <<".";
        }
        cout << endl;
    }
}
int main(int argc, char** argv) {
    int q,q1;
    do{
        cin >> q >> q1;
        if (q!=0 || q1!=0) tablica(10,10,65,1,q,q1);
    }while(q!=0 || q1!=0);
    return 0;
}

Работа программы:

Answer 1
void
tablica(const int a,const int b, char c, int d,
        const int x, const int y, const int oldX, const int oldY){
    cout << '%';
    for (int i=1; i<b; ++i) {
        cout << setw(3) << c;
        ++c;
    }
    for (int i = 1; i < b; ++i) {
        cout << endl << d;
        ++d;
        for (int z=1; z<a; z++){
            if ( (z==x && i==y) || (z == oldX && i == oldY)) cout << setw(3) << 'X';
            else
                cout << setw(3) <<'.';
        }
    }
}

int main()
{   
    int q,q1;
    const int a = 10, b = 10, d = 1;
    char c = 'A';
    while (cin >> q >> q1 && (q!=0 || q1!=0) && q < a && q1 < b) {
          static int x = q, y = q1;
          tablica(a, b, c , d, x, y, q, q1);  
    }
    return 0;
}

Во первых в аргументах функции нужно указать какие аргументы не подлежат изменению, дальше вы в циклах делаете много сравнений. Чтобы цикл работал быстрее, нужно уменьшить их количество. Первая строка и столбец у вас всегда неизменяема, поэтому эти данные нужно выводить отдельно.

Не гарантировано, что целочисленное значение символа 'A' равно 65(в других реализациях может иметь другое значение), поэтому передайте в аргумент именно символ, тем более, что так нагляднее что есть этот аргумент.

Дальше: манипулятор setw(3) выделяет поле для текущего выводимого/вводимого обьекта, а не для предыдущего, поэтому в выражение, например: cout <<"%" <<setw(3); <<setw(3) ничего не выполняет и совершенно лишнее.

В программе do/while конструкция не нужна. Без нее проще.

Ответ на ваш вопрос:

Чтобы хранить данные, введенные в функции или являющийся аргументами функции, и при этом вызывать функцию по циклу, нужно передать в аргументы функции статические обьекты такого же типа, для их инициализации старыми данными. Не гарантировано, что я хорошо обьяснил все, но программа вам поможет понять...

P.S. По хорошему, просто вам нужен двумерный массив, а функция просто по заданному координату добавит метку

Answer 2

Вам нужно хранить состояния, это можно делать с помощью внешних переменных по отношению к функции(Передавать их по ссылке или указателю). Но я бы смотрел в строну ООП. Вам нужны сущности Ход, Список Ходов, Поле, Игрок, Игра(список неполный). Ваш код громоздок и сложен для понимания. Разбив свою игру на мелкие сущности и описав взаимодействия между ними, Вы его сможете упростить. PS Имена входных параметров не очень осмысленны, что тоже усложняет понимание.

READ ALSO
Как работает этот блок кода?

Как работает этот блок кода?

Учу C++, ради эксперимента решил написать прогу, которая бежит по памяти и выводит нули и единицы

125
Проблема в поиске подстроки

Проблема в поиске подстроки

Задача: Вывести не менее 3 слов, содержащих искомую подстроку и встречающихся наиболее часто

137