Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
CHELOVEKPAUK
 Аватар для CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:02     Морской бой: расставляется кораблей больше, чем положено #1
Здравствуйте! Пишу игру "Морской бой" в консоли, и попалась одна неприятная ситуация.
Есть функция заполнения поля случайными кораблями, т.е. в рандомные места (не обращайте внимание на примитивность, это в процессе отладки изменил всё):

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 раз.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2014, 17:02     Морской бой: расставляется кораблей больше, чем положено
Посмотрите здесь:

C++ Морской бой. Ф-ция автоматической рассатновки кораблей.
C++ Морской Бой
Игра "Морской бой" Рассстановка кораблей C++
Консольный морской бой. Расстановка кораблей C++
Расстановка кораблей (морской бой) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
15.08.2014, 17:06     Морской бой: расставляется кораблей больше, чем положено #2
Как бы в названии темы и ответ, судя по всему. В vector<Ship> хранятся копии помещаемых в него объектов. Вам надо хранить не объекты, а указатели на них, т.е. использовать vector<Ship*>. Только придётся в коде многое поменять.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.08.2014, 17:12     Морской бой: расставляется кораблей больше, чем положено #3
CHELOVEKPAUK, Если есть возможность использовать С++11 то можно использовать move.
C++
1
_ships.push_back(std::move(temp));
CHELOVEKPAUK
 Аватар для CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:23  [ТС]     Морской бой: расставляется кораблей больше, чем положено #4
John Prick, что-то я не понял - какую это роль играет? Мы же создаем копию одного обьекта ОДИН раз. А здесь создается два. Объясните пожалуйста поподробнее. И указатель не получится сделать - я же временный обьект создаю.
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:26     Морской бой: расставляется кораблей больше, чем положено #5
А как именно дубликаты выглядят? Просто копия корабля с теми же самыми координатами? Как Вы понимаете, что есть дубликаты?
CHELOVEKPAUK
 Аватар для CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:28  [ТС]     Морской бой: расставляется кораблей больше, чем положено #6
tehnar5, абсолютная копия предыдущего предмета. Создается десять уникальных кораблей и + копия к каждому. Т.е. создается уникальный корабль, его копия, уникальный корабль, его копия и так далее.
tehnar5
31 / 31 / 12
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:31     Морской бой: расставляется кораблей больше, чем положено #7
Так вопрос в том - как Вы понимаете, что есть копии? Как выглядит функция addShip?
CHELOVEKPAUK
 Аватар для 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;
}
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, отдохнуть, а потом свежим взглядом просмотреть код, обычно помогает
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.08.2014, 18:33     Морской бой: расставляется кораблей больше, чем положено
Еще ссылки по теме:

Случайное распределение кораблей по полю в игре "морской бой" C++
Морской бой - программа зацикливается на расстановке кораблей C++

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

Или воспользуйтесь поиском по форуму:
Lynatik001
 Аватар для Lynatik001
34 / 28 / 2
Регистрация: 28.09.2012
Сообщений: 560
15.08.2014, 18:33     Морской бой: расставляется кораблей больше, чем положено #10
Цитата Сообщение от tehnar5 Посмотреть сообщение
пошаговая отладка
да это нечто, хорошо спасает.
Yandex
Объявления
15.08.2014, 18:33     Морской бой: расставляется кораблей больше, чем положено
Ответ Создать тему
Опции темы

Текущее время: 12:03. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru