Лабиринт поколения в кокосах 2dx cpp - PullRequest
1 голос
/ 22 февраля 2020

Я пытаюсь создать генератор-лабиринт в рамках cocos2dx cpp. Используя рекурсивный алгоритм обратного отслеживания, чтобы сделать это. Я вроде сделал это, но не уверен, где я пропустил это. Лабиринт, который я получаю, не лабиринт, это просто закрытая клетка. Не могли бы вы сказать мне, где я пропускаю, Ниже мой код

GameScene. cpp

    #include "GameScene.h"
    #include "SimpleAudioEngine.h"
    #include "Globals.h"

    USING_NS_CC;

    std::vector<Cell> Globals::grid;
    // std::stack<Cell> Globals::mainStack;

    Scene* GameScene::createScene()
    {
        return GameScene::create();
    }

    // Print useful error message instead of segfaulting when files are not there.
    static void problemLoading(const char* filename)
    {
        printf("Error while loading: %s\n", filename);
        printf("Depending on how you compiled you might have to add 'Resources/' in front of 
     filenames in GameSceneScene.cpp\n");
    }

    bool GameScene::init()
    {
        if ( !Scene::init() )
        {
            return false;
        }

        auto visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();

        //Middle position ==> sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, 

        visibleSize.height/2 + origin.y));

        auto label = Label::createWithTTF("Hello!", "fonts/Marker Felt.ttf", 24);
        if (label == nullptr)
        {
            problemLoading("'fonts/Marker Felt.ttf'");
        }
        else
        {
            label->setPosition(Vec2(origin.x + visibleSize.width/2,
                                    origin.y + visibleSize.height - 
                                    label->getContentSize().height));
            this->addChild(label, 1);
        }

        GameScene::buildLayouts();
        this->scheduleUpdate();
        // GameScene::initBoard();
        // GameScene::start();

        return true;
    }

    // void GameScene::start(float dt) {
    // }

    void GameScene::update(float dt)
    {

        cocos2d::log("{jj} drawing");
        int cols = 4; //round(BOARD_WIDTH / GRID_SIZE);
        int rows = 4; //round(BOARD_HEIGHT /GRID_SIZE);

        Cell* next;

        std::stack<Cell> mainStack; 

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                Cell cell(i, j);
                Globals::grid.push_back(cell);
                cocos2d::log("{cell} cell col -- %d", cell.col);
                cocos2d::log("{cell} cell row -- %d", cell.row);
            }
        }

        currentGrid = &Globals::grid[0];
        bool mazeGenerated = false;

        //step 1
        currentGrid->visited = true;

        while(mazeGenerated == false) {
            cocos2d::log("{lo} Generating --");


            Cell *nextCell = currentGrid->checkNeighbors(rows, cols);

            // cocos2d::log("{lo} next cell nextCell -- %d", nextCell);

            if (nextCell != nullptr) {
                cocos2d::log("{lo} Entering valid index --");

                for (int i = 0; i < Globals::grid.size(); i++)
                {
                    if (nextCell ->col == Globals::grid[i].col && nextCell->row == 
                        Globals::grid[i].row) {
                        //step 2
                        mainStack.push(*currentGrid);
                        Globals::grid[i].visited = true;

                        //step 3
                        currentGrid->removeWalls(&Globals::grid[i]);
                        next = &Globals::grid[i];

                    }
                }

                currentGrid->removeWalls(next);

                next->drawCell(this->main_scroll_view);
                //step 4
                currentGrid = next;
            } else  {
                if  (!mainStack.empty()) {
                    currentGrid = &mainStack.top();
                    mainStack.pop();
                } else {
                    mazeGenerated = true;
                    cocos2d::log("{lo} maze generated --");
                }
            }
        }

        // GameScene::drawBoard();
    }

    void GameScene::drawBoard()
    {
        for (int i = 0; i < Globals::grid.size(); i++) {
            Globals::grid[i].drawCell(this->main_scroll_view);
        }
    }

    void GameScene::buildLayouts()
    {
        auto visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();

        this->main_layout = cocos2d::ui::Layout::create();
        this->main_layout->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); 
        this->main_layout->setBackGroundColor(Color3B::WHITE);
        this->main_layout->setLayoutType(ui::Layout::Type::VERTICAL);
        this->main_layout->setContentSize(Size(visibleSize.width , visibleSize.height  ));
        this->main_layout->setPosition(Vec2(origin.x + visibleSize.width/2, origin.y + 
        visibleSize.height/2));
        this->main_layout->setAnchorPoint(Vec2(0.5, 0.5));

        this->addChild(main_layout);


    Size scollFrameSize = Size(this->main_layout->getContentSize().width , 
                                 this->main_layout->getContentSize().height);
    this->main_scroll_view = cocos2d::ui::ScrollView::create();
    this->main_scroll_view->setContentSize(scollFrameSize);
    this->main_scroll_view-> 
          setBackGroundColorType(cocos2d::ui::Layout::BackGroundColorType::SOLID);
    this->main_scroll_view->setBackGroundColor(Color3B(200, 200, 200));
    this->main_scroll_view->setPosition(Vec2(0, 0));
    this->main_scroll_view->setDirection(cocos2d::ui::ScrollView::Direction::BOTH);
    this->main_scroll_view->setBounceEnabled(true);
    this->main_scroll_view->setTouchEnabled(true);
    auto containerSize = Size(scollFrameSize.width*2, scollFrameSize.height + 100);
    this->main_scroll_view->setInnerContainerSize(containerSize);

    this->main_layout->addChild(this->main_scroll_view);
}


#Cell.cpp

    #include "Cell.h"
    #include "cocos2d.h"
    #include "GameScene.h"
    #include "Globals.h"


    // constructor
    Cell::Cell(int i, int j): row(i), col(j)
    {
    };



    // bool Cell.walls[] = { true, true, true   , true };

    void Cell::drawCell(cocos2d::ui::Layout *parent)
    {
        int x = col * WIDTH;
        int y = row * WIDTH;

        auto visibleSize = cocos2d::Director::getInstance()->getVisibleSize();
        cocos2d::Vec2 origin = cocos2d::Director::getInstance()->getVisibleOrigin();

        int parent_width = parent->getContentSize().width;
        int parent_height = parent->getContentSize().height;


     //    if (visited) {
        //  auto rectNode = cocos2d::DrawNode::create();
        //  cocos2d::Vec2 rectangle[4];
        //  rectangle[0] = cocos2d::Vec2(x, y);
        //  rectangle[1] = cocos2d::Vec2(x+WIDTH, y);
        //  rectangle[2] = cocos2d::Vec2(x+WIDTH, y+ HEIGHT);
        //  rectangle[3] = cocos2d::Vec2(x, y+HEIGHT);

        //  // cocos2d::Color4F::ORANGE;
        //  rectNode->drawPolygon(rectangle, 4, cocos2d::Color4F::ORANGE, 1, 
         cocos2d::Color4F::ORANGE);
        //  parent->addChild(rectNode);
        // }

        auto drawNode = cocos2d::DrawNode::create();

        if (walls[0]) {
            drawNode->drawLine(cocos2d::Vec2(x , y + HEIGHT), cocos2d::Vec2(x + WIDTH, y + 
        HEIGHT), cocos2d::Color4F::GREEN); //top
        }

        if (walls[1]) {
            drawNode->drawLine(cocos2d::Vec2(x + WIDTH, y), cocos2d::Vec2( x + WIDTH, y + 
        HEIGHT), cocos2d::Color4F::BLUE); //right
        }

        if (walls[2]) {
            drawNode->drawLine(cocos2d::Vec2(x, y), cocos2d::Vec2(x + WIDTH, y), 
        cocos2d::Color4F::RED); //bottom
        }

        if (walls[3]) {
            drawNode->drawLine(cocos2d::Vec2(x, y ), cocos2d::Vec2(x, y +HEIGHT), 
         cocos2d::Color4F::BLACK); // left
        }

        // drawNode->setPosition(cocos2d::Vec2(parent_width/2 + origin.x, parent_height/2 + 
         origin.y));
        // this->setAnchorPoint(cocos2d::Vec2(0.5, 0.5));
        parent->addChild(drawNode);
    }

    int Cell::getIndex(int colId, int rowId,  int rows, int cols)
    {
        if ( colId < 0 || rowId < 0 || colId > 4 - 1 || rowId > 4 - 1) {
            return -1;
        }

        return colId + rowId * 4 ;
    }

    Cell* Cell::checkNeighbors( int rows, int cols) {

        std::vector<Cell> neighbors;

        int top_index, right_index, bottom_index, left_index;

        top_index    = Cell::getIndex(col, row + 1, rows, cols );
        right_index  = Cell::getIndex(col + 1, row, rows, cols );
        bottom_index = Cell::getIndex(col, row  - 1, rows, cols );
        left_index   = Cell::getIndex(col - 1, row, rows, cols);

        if (top_index != -1) {
            Cell top     = Globals::grid[top_index];

            if (!top.visited) {
                cocos2d::log("{lo} top here");
                neighbors.push_back(top);
            }
        }

        if (right_index != -1) {
            Cell right = Globals::grid[right_index];

            if (!right.visited) {
                cocos2d::log("{lo} right here");
                neighbors.push_back(right);
            }
        }

        if (bottom_index != -1) {
            Cell bottom = Globals::grid[bottom_index];

            if (!bottom.visited) {
                cocos2d::log("{lo} bottom here");
                neighbors.push_back(bottom);
            }
        }

        if (left_index != -1) {
            Cell left = Globals::grid[left_index];

            if (!left.visited) {
                cocos2d::log("{lo} left here");
                neighbors.push_back(left);
            }
        }

        if (neighbors.size() > 0) {
            srand(time(NULL)); // needed to give random number at change of time
            int randomIndex = round(rand() % neighbors.size());
            return &neighbors[randomIndex];
        } else {
            return nullptr;
        }
    }


    void Cell::removeWalls(Cell *next)
    {
        int x = this->row - next->row;

        cocos2d::log("{kk} x is %d", x);


        if (x == 1) {
            this->walls[1] = false;
            next->walls[3] = false;
        } else if (x == -1) {
            this->walls[3] = false;
            next->walls[1] = false;
        }

        int y = this->col - next->col;
        cocos2d::log("{kk} y is %d", y);

        if (y == 1) {
            this->walls[0] = false;
            next->walls[2] = false;
        } else if (y == -1) {
            this->walls[2] = false;
            next->walls[0] = false;
        }
    }

Ячейка - это блок с линиями вокруг нее, я рисую линии, если это необходимо.

...