Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
#1

Морской бой: расставляется кораблей больше, чем положено - C++

15.08.2014, 17:02. Просмотров 521. Ответов 9
Метки нет (Все метки)

Здравствуйте! Пишу игру "Морской бой" в консоли, и попалась одна неприятная ситуация.
Есть функция заполнения поля случайными кораблями, т.е. в рандомные места (не обращайте внимание на примитивность, это в процессе отладки изменил всё):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
void PlayerTable::fillRandom()
{
    int j = 0;
    reset(); // сбросить всю таблицу
    int i1 = 0;
    int i2 = 0;
    int i3 = 0;
    int i4 = 0;
    while (i1 != 4) // 1 палубные
    {
        Ship temp(1); // создает 1 палубник с рандомными координатами
        ++j;
        if (addShip(temp)) { // если удалось добавить на карту (не пересекается ни с кем и т.д.) возвращает true, иначе false
            _ships.push_back(temp); // если удачно добавился на карту - добавляем этот корабль в вектор
            ++_goodship; // счетчик удачно добавленных кораблей
            ++i1;
        }
    }
    while (i2 != 3) // 2 палубные
    {
        ++j;
        Ship temp(2);
        if (addShip(temp)) {
            _ships.push_back(temp);
            ++_goodship;
            ++i2;
        }
    }
    while (i3 != 2) // 3 палубные
    {
        Ship temp(3);
        ++j;
        if (addShip(temp)) {
            _ships.push_back(temp);
            ++_goodship;
            ++i3;
        }
    }
    while (i4 != 1) // 4 палубные
    {
        Ship temp(4);
        ++j;
        if (addShip(temp)) {
            _ships.push_back(temp);
            ++_goodship;
            ++i4;
        }
    }
}
Так вот, почему то в ЛЮБОМ случае создаются 20 кораблей вместо десяти - 10 уникальных и по 1 дубликату на каждый. Вопрос - как такое может быть? Защита на создание дубликата есть - вокруг и на территории корабля рисуется невидимое поле, при создании на нем корабля addship возвращает false. С обычным ручным добавлением корабля все работает правильно. Помогите, в чем проблема.

И вот еще что важно - переменные i1, i2, i3, i4 в сумме дают 10, следовательно операция push_back должна тоже выполнится 10 раз.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2014, 17:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Морской бой: расставляется кораблей больше, чем положено (C++):

Расстановка кораблей (морской бой) - C++
Доброго времени суток, при расстановке 2х палубных кораблей возникает проблема... При выборе точки уже занятой, система ломается и...

Консольный морской бой. Расстановка кораблей - C++
Добрый вечер, уважаемые форумчане. Хочу написать консольный морской бой. Начал с функции автоматической расстановки кораблей. Весь...

Морской бой - программа зацикливается на расстановке кораблей - C++
Нужно написать курсовую(игру). Решила написать морской бой(пока что консольно). Написала программу для расстановки кораблей. Не могу...

Морской бой. Ф-ция автоматической рассатновки кораблей. - C++
Добрый день, ув. форумчане! Есть задание написать консольный морской бой. Есть задача расстановки кораблей компьютера случайным образом....

Проверить правильность расстановки кораблей. Морской бой - C++
Есть матрица NxM, где расставлены корабли. Корабли не стоят на краю матрицы, кол-во 4-х клеточных кораблей - 1, 3-х клет. - 2, 2-х...

Случайное распределение кораблей по полю в игре "морской бой" - C++
Привет всем кто читал мой предыдущий пост про векторы в морском боем, в той же фунции появилась новая проблема :) После починки...

9
John Prick
809 / 742 / 148
Регистрация: 27.07.2012
Сообщений: 2,122
Завершенные тесты: 3
15.08.2014, 17:06 #2
Как бы в названии темы и ответ, судя по всему. В vector<Ship> хранятся копии помещаемых в него объектов. Вам надо хранить не объекты, а указатели на них, т.е. использовать vector<Ship*>. Только придётся в коде многое поменять.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
15.08.2014, 17:12 #3
CHELOVEKPAUK, Если есть возможность использовать С++11 то можно использовать move.
C++
1
_ships.push_back(std::move(temp));
0
CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:23  [ТС] #4
John Prick, что-то я не понял - какую это роль играет? Мы же создаем копию одного обьекта ОДИН раз. А здесь создается два. Объясните пожалуйста поподробнее. И указатель не получится сделать - я же временный обьект создаю.
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:26 #5
А как именно дубликаты выглядят? Просто копия корабля с теми же самыми координатами? Как Вы понимаете, что есть дубликаты?
0
CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:28  [ТС] #6
tehnar5, абсолютная копия предыдущего предмета. Создается десять уникальных кораблей и + копия к каждому. Т.е. создается уникальный корабль, его копия, уникальный корабль, его копия и так далее.
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:31 #7
Так вопрос в том - как Вы понимаете, что есть копии? Как выглядит функция addShip?
0
CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:34  [ТС] #8
tehnar5, я смотрю по разделу, где описываются во время компиляции локальные переменные (не знаю как его назвать).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
bool PlayerTable::addShip(Ship s)
{
    if (!s) { // if something wrong with s._fails
        ++_errship;
        return false;
    }
 
    switch (s.turn())
    {
    case HORIZONT: // горизонтальный поворот корабля
        for (int i = s.begin().column; i <= s.end().column; ++i)
            if (_tablestate[s.end().row][i] == FALSE) { // check tablestate
                ++_errship;
                return false;
            }
 
        for (int i = s.begin().column; i <= s.end().column; ++i)
            _table[s.end().row][i] = SHIP; // make a ship
 
        for (int i = s.begin().column - 1; i < s.end().column + 2; ++i) {
            _tablestate[s.end().row - 1][i] = FALSE; //
            _tablestate[s.end().row][i]     = FALSE; // make a safe place around ship
            _tablestate[s.end().row + 1][i] = FALSE; //
        }
        break;
 
    case VERT: // вертикальный поворот
        for (int i = s.begin().row; i <= s.end().row; ++i) {
            if (_tablestate[i][s.end().column] == FALSE) { // check tablestate
                ++_errship;
                return false;
            }
            _table[i][s.end().column] = SHIP; // make a ship
        }
        for (int i = s.begin().row - 1; i < s.end().row + 2; ++i) {
            _tablestate[i][s.end().column - 1] = FALSE; //
            _tablestate[i][s.end().column]     = FALSE; // make a safe place around ship
            _tablestate[i][s.end().column + 1] = FALSE; //
        }
        break;
 
    default:
        return false; break;
    }
    
    _ships.push_back(s);
    _goodship++;
    return true;
}
0
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:38 #9
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Все очень просто. Посмотрите на 46 строчку функции:
C++
1
 _ships.push_back(s);
, и Вы увидите, что у вас один и тот же корабль дважды добавляется в вектор - один раз в функции добавления, и один раз в функции рандомного заполнения

Добавлено через 1 минуту
А вообще, в таких случаях помогает либо пошаговая отладка, либо какой-нибудь debug-вывод, либо же отойти от компьютера минут на 10-15, отдохнуть, а потом свежим взглядом просмотреть код, обычно помогает
2
Lynatik001
38 / 32 / 4
Регистрация: 28.09.2012
Сообщений: 620
15.08.2014, 18:33 #10
Цитата Сообщение от tehnar5 Посмотреть сообщение
пошаговая отладка
да это нечто, хорошо спасает.
0
15.08.2014, 18:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.08.2014, 18:33
Привет! Вот еще темы с ответами:

Игра "Морской бой" Рассстановка кораблей - C++
Пишу игру &quot;Морской бой&quot;. Нужно пока что только расставить корабли. На данный момент логика следующая. Все поле забито нулями (ноль - пустая...

Морской бой - C++
Всем привет. Помогите пожалуйста. Задали написать игру «Морской бой». В Borlande 3.11 используя графический режим. Но признаюсь –...

Морской Бой - C++
прошу в помощи написания этой игры ,спасибо

Морской бой С++ - C++
Помогите пожалуйста.Нужно сделать так,чтобы обрисовало выстрелами все(вокруг убитого корабля) #include &lt;iostream&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru