Я пытаюсь создать генератор-лабиринт в рамках 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;
}
}
Ячейка - это блок с линиями вокруг нее, я рисую линии, если это необходимо.