Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
 Аватар для CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1

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

15.08.2014, 17:02. Показов 2066. Ответов 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)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.08.2014, 17:02
Ответы с готовыми решениями:

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

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

Морской бой.Обработка массива. Расстановка кораблей
Пытаюсь написать морской бой. Свою карту я подгружаю из файла. Проблема в том, что у меня не получается корректно проверить, соприкасаются...

9
2393 / 1915 / 763
Регистрация: 27.07.2012
Сообщений: 5,560
15.08.2014, 17:06
Как бы в названии темы и ответ, судя по всему. В vector<Ship> хранятся копии помещаемых в него объектов. Вам надо хранить не объекты, а указатели на них, т.е. использовать vector<Ship*>. Только придётся в коде многое поменять.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
15.08.2014, 17:12
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  [ТС]
John Prick, что-то я не понял - какую это роль играет? Мы же создаем копию одного обьекта ОДИН раз. А здесь создается два. Объясните пожалуйста поподробнее. И указатель не получится сделать - я же временный обьект создаю.
0
31 / 31 / 19
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:26
А как именно дубликаты выглядят? Просто копия корабля с теми же самыми координатами? Как Вы понимаете, что есть дубликаты?
0
 Аватар для CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:28  [ТС]
tehnar5, абсолютная копия предыдущего предмета. Создается десять уникальных кораблей и + копия к каждому. Т.е. создается уникальный корабль, его копия, уникальный корабль, его копия и так далее.
0
31 / 31 / 19
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:31
Так вопрос в том - как Вы понимаете, что есть копии? Как выглядит функция addShip?
0
 Аватар для CHELOVEKPAUK
13 / 3 / 2
Регистрация: 01.08.2013
Сообщений: 332
Записей в блоге: 1
15.08.2014, 17:34  [ТС]
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
31 / 31 / 19
Регистрация: 03.05.2011
Сообщений: 84
15.08.2014, 17:38
Лучший ответ Сообщение было отмечено CHELOVEKPAUK как решение

Решение

Все очень просто. Посмотрите на 46 строчку функции:
C++
1
 _ships.push_back(s);
, и Вы увидите, что у вас один и тот же корабль дважды добавляется в вектор - один раз в функции добавления, и один раз в функции рандомного заполнения

Добавлено через 1 минуту
А вообще, в таких случаях помогает либо пошаговая отладка, либо какой-нибудь debug-вывод, либо же отойти от компьютера минут на 10-15, отдохнуть, а потом свежим взглядом просмотреть код, обычно помогает
2
 Аватар для Lynatik001
48 / 40 / 15
Регистрация: 28.09.2012
Сообщений: 818
15.08.2014, 18:33
Цитата Сообщение от tehnar5 Посмотреть сообщение
пошаговая отладка
да это нечто, хорошо спасает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.08.2014, 18:33
Помогаю со студенческими работами здесь

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

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

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

Создать класс, реализующий хранилище кораблей для игрока в «Морской бой»
Всем привет. Это задача по теме контейнерные классы. Не бейте только за глупый вопрос. Но в данной задаче нужно создавать сам класс? Прост...

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


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru