@XerimHD

Входит в бесконечный цыкл,как исправить?

В функции dungeon_gen, при создании комнаты иногда она не создается, и я хотел бы сделать так (например, если room_num равно 10, а r_placed равно 6, и вы больше не можете добавить, то выходите из цикла и рисуете только 6 комнат). Я пытался сделать это, но ничего не работает.Пробовал много разных способов ну ничего не получалось,если кто-то сможет подсказать что не так буду очень благодарен вам)

#include <iostream>
#include <vector>
#include <time.h>
#include <E:\Desktop\school\ctest\lib\PDCurses-3.9\curses.h>
using namespace std;
void game_loop(bool &staircase_placed, int &c, bool &t_placed, int &r_placed, bool &p_placed, int rows, int cols, vector<vector<char>> &map);
void dungeon_graw(bool &p_placed, int rows, int cols, vector<vector<char>> &map);
void dungeon_gen(bool &staircase_placed, bool &p_placed, bool &t_placed, int &r_placed, int rows, int cols, vector<vector<char>> &map);
void movement(bool &staircase_placed, bool &t_placed, int &r_placed, bool &p_placed, int &c, vector<vector<char>> &map);
void attack(int rows, int &c, int dir_y, int dir_x, vector<vector<char>> &map);
int px, py; // координата игрока
int p_gold = 0;

class monsters
{
public:
    int y;
    int x;
    int hp;
};
class monsters monster[10];
int main()
{

    int c = 0;
    int cols, rows;
    bool t_placed = false;
    bool p_placed = false;
    int r_placed = 0;
    bool staircase_placed = false;

    initscr();
    keypad(stdscr, 1);
    noecho();
    curs_set(0);
    getmaxyx(stdscr, rows, cols);
    vector<vector<char>> map(rows, vector<char>(cols));

    do
    {

        //  erase(); // очистка екрана
        game_loop(staircase_placed, c, t_placed, r_placed, p_placed, rows, cols, map);
        refresh();                 // Обновление экрана
    } while ((c = getch()) != 27); // 27 - ESC

    getch();
    endwin();
    return 0;
}

/////////////////////

void game_loop(bool &staircase_placed, int &c, bool &t_placed, int &r_placed, bool &p_placed, int rows, int cols, vector<vector<char>> &map)
{

    movement(staircase_placed, t_placed, r_placed, p_placed, c, map);
    dungeon_gen(staircase_placed, p_placed, t_placed, r_placed, rows, cols, map);
    dungeon_graw(p_placed, rows, cols, map);

    if (c == 'a')
    {
        attack(c, py, px, rows, map);
    }
}

void dungeon_gen(bool &staircase_placed, bool &p_placed, bool &t_placed, int &r_placed, int rows, int cols, vector<vector<char>> &map)
{
    srand(time(0));
    int rx = 0, ry = 0;     // кордината комнаты
    int r_size_x, r_size_y; // размер комнаты
    bool collision = false;
    if (!r_placed)
    {

        int room_num = rand() % 1 + 3; // число комнат

        int r_old_center_y, r_old_center_x, r_center_y, r_center_x; // коридоры

        /// база даных
        for (int y = 0; y < rows; y++)
        {
            for (int x = 0; x < cols; x++)
            {

                if (y == 0 || y == rows - 2 || x == 0 || x == cols - 1)
                {
                    map[y][x] = '%'; // записываем  барьер в базу
                }
                else
                {
                    map[y][x] = '#'; // записываем  стену в базу
                }
            }
        }

        while (r_placed < room_num)
        {
            int try_counter = 0; //  изменяряет попытки генерации комнат
            do
            {
                collision = false;
                // делаем кординаты комнате
                ry = rand() % (rows - 4) + 1;
                rx = rand() % (cols - 4) + 1;
                r_size_y = rand() % 5 + 4;
                r_size_x = rand() % 10 + 8;
                for (int y = ry; y < ry + r_size_y; y++)
                {

                    for (int x = rx; x < rx + r_size_x; x++)
                    {
                        if (map[y][x] == '%' || map[y][x] == ' ' || map[y + 2][x] == ' ' || map[y - 2][x] == ' ' || map[y][x + 2] == ' ' || map[y][x - 2] == ' ')
                        {
                            collision = true;

                            break;
                        }
                    }
                    if (collision)
                    {
                        break;
                    }
                }
                try_counter++;
                if (try_counter > 100)
                {
                    rx = ry = 3;
                    r_size_y = r_size_x = 3;
                    break;
                }

            } while (collision && try_counter <= 100);

            // записывыем в базу комнаты
            for (int y = ry; y < ry + r_size_y; y++)
            {
                for (int x = rx; x < rx + r_size_x; x++)
                {
                    if (map[y][x] == '%')
                    {
                        y = ry + r_size_y;
                        break;
                    }
                    else
                    {
                        map[y][x] = ' ';
                    }
                }
            }
            r_placed++;

            if (r_placed > 1)
            {
                r_old_center_y = r_center_y;
                r_old_center_x = r_center_x;
            }
            r_center_y = ry + (r_size_y / 2);
            r_center_x = rx + (r_size_x / 2);
            if (r_placed > 1)
            {
                int path_y;
                for (path_y = r_old_center_y; path_y != r_center_y;)
                {
                    map[path_y][r_old_center_x] = ' ';
                    if (r_old_center_y < r_center_y)
                    {
                        path_y++;
                    }
                    else if (r_old_center_y > r_center_y)
                    {
                        path_y--;
                    }
                }
                for (int x = r_old_center_x; x != r_center_x;)
                {
                    map[path_y][x] = ' ';
                    if (r_old_center_x < r_center_x)
                    {
                        x++;
                    }
                    else if (r_old_center_x > r_center_x)
                    {
                        x--;
                    }
                }
            }
        }
    }
    if (!t_placed)
    {
        int monster_y, monster_x;
        for (int m = 0; m < 10; m++)
        {

            do
            {
                monster_x = rand() % cols;
                monster_y = rand() % rows;
            } while (map[monster_y][monster_x] != ' ');
            monster[m].y = monster_y;
            monster[m].x = monster_x;
            monster[m].hp = 2; // хп монстров
            map[monster[m].y][monster[m].x] = 't';
        }
        t_placed = true;
    }
    if (!p_placed)
    {

        do
        {
            px = rand() % cols;
            py = rand() % rows;
        } while (map[py][px] != ' ');
        map[py][px] = '@';
        p_placed = true;
    }
    if (!staircase_placed)
    {
        int center_y, center_x;

        do
        {

            center_y = ry + (r_size_y / 2);
            center_x = rx + (r_size_x / 2);

        } while (map[center_y][center_x] != ' ');
        map[center_y][center_x] = '>';
        staircase_placed = true;
    }
}
void dungeon_graw(bool &p_placed, int rows, int cols, vector<vector<char>> &map)
{
    srand(time(0));
    ///// рисования данжа
    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < cols; x++)
        {

            if (map[y][x] == '%')
            {
                mvaddch(y, x, '%'); // рисуем  барьер
            }
            else if (map[y][x] == '@')
            {
                mvaddch(y, x, '@');
            }
            else if (map[y][x] == 't')
            {
                mvaddch(y, x, 't');
            }
            else if (map[y][x] == ' ') // рисуем комнату
            {
                mvaddch(y, x, ' ');
            }
            else if (map[y][x] == '>')
            {
                mvaddch(y, x, '>');
            }

            else
            {
                mvaddch(y, x, '#'); // рисуем  стену
            }
        }
    }

    //////////////////////////////////////////////////////////
    // чистим последню строку для информации
    for (int x = 0; x < cols; x++)
    {
        mvaddch(rows - 1, x, ' ');
    }

    mvprintw(rows - 1, 0, "Gold %d", p_gold); // вывод золота
}
void movement(bool &staircase_placed, bool &t_placed, int &r_placed, bool &p_placed, int &c, vector<vector<char>> &map)

{
   //передвижения
}
  • Вопрос задан
  • 123 просмотра
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
После while (collision && try_counter <= 100); вставьте:
if (try_counter > 100) break;

Добавьте отладочный вывод в каждый цикл - посмотрите, а в каком же цикле оно висьнет-то.
Вам еще понадобиться try_counter в цикл по монстрам (while (map[py][px] != ' ')).

А вообще, очень странный цикл вот:
do
        {
            center_y = ry + (r_size_y / 2);
            center_x = rx + (r_size_x / 2);
        } while (map[center_y][center_x] != ' ');


Тут явно какая-то ошибка, потому что center_x и center_y на каждой итерации получатся одинаковые и цикл или сразу закончится, или повиснет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы