提示画像ですがこれはダンジョンRPGのダンジョンマップ生成アルゴリズムのステージ分割した時のスクショなのですがステージを適当に分割した後に次はその分割した矩形の中にランダムな大きさの矩形を配置する必要があるのですがこれをするにはどういった思考を用いて実装するのでしょうか?
現状のように縦、横に直線を引いてステージを分割しているのですがその後の分割した矩形の中にランダムな大きさの矩形を配置する
ということをコード上で実装したいのですが実装方法が思い付きません。ステージの各エリアをどうやって認識したらいいでしょうか?
提示コードsetGenerate()
関数部
現状
縦、横に線を引いてステージを分割
参考サイト:https://kt2525family.com/rogue-development-5/
Dungeon_Generate.cpp
cpp
#include "../header/Generate_Dungeon.hpp" #include "../../FrameWork/header/FrameWork.hpp" #include <glm/glm.hpp> #include <algorithm> // ##################################### コンストラクタ ##################################### Generate_Dungeon::Generate_Dungeon(glm::ivec2 s,int div) { divNum = div; //分割数 allSize = s; //全体サイズ minSize = glm::ivec2(3,3); //最小区画サイズ maxSize = glm::ivec2(s.x / minSize.x,s.y / minSize.y); //最大区画サイズ stage.resize(s.x * s.y); area.resize(0); area.push_back(Area { s.x * s.y,glm::ivec2(0,0),s }); } // ##################################### ステージ再設定 ##################################### void Generate_Dungeon::setReSetStage(glm::ivec2 s,int div) { divNum = div; allSize = s; stage.resize(s.x * s.y); area.resize(0); area.push_back(Area { s.x * s.y,glm::ivec2(0,0),s }); } // ##################################### 一番大きいエリアを削除 ##################################### void Generate_Dungeon::DeleteMaxArea() { Area map = Area{0,glm::ivec2(0,0),glm::ivec2(allSize.x,allSize.y)}; int i = 0; int num = -1; for(std::vector<Area>::iterator itr = area.begin(); itr != area.end(); itr++) { if(map.size < itr->size) { map = *itr; num = i; // std::cout<<map.size<<std::endl; } i++; } if(num != -1) { area.erase(area.begin() + num); } else { std::cout<< "Error: 削除するエリアがありません。"<<std::endl; } } // ##################################### 一番大きいエリアを取得 ##################################### Generate_Dungeon::Area Generate_Dungeon::GetMaxArea() { Area map = Area{0,glm::ivec2(0,0),glm::ivec2(0,0)}; for(std::vector<Area>::iterator itr = area.begin(); itr != area.end(); itr++) { if(map.size < itr->size) { map = *itr; std::cout<<" map.start.y: " << map.start.y<<std::endl; // std::cout<<map.size<<std::endl; } } // std::cout<<" map.start.y: " << map.start.y<<std::endl; std::cout<<"return map.start.y: " << map.start.y<<std::endl; // std::cout<<std::endl; // std::cout<<std::endl; // std::cout<<std::endl; return map; } // ##################################### エリアに値を設定 ##################################### void Generate_Dungeon::SetArea(glm::ivec2 start,glm::ivec2 size,byte b) { for(int y = start.y; y < start.y + size.y; y++) { for(int x = start.x; x < start.x + size.x; x++) { stage.at((y * allSize.x) + x) = b; } } } // ##################################### X軸からYの長さを取得 ##################################### int Generate_Dungeon::GetCheckLineDown(glm::ivec2 start) { byte b = stage.at( (allSize.x * start.y) + start.x); int y = 0; for(int i = start.y; i < allSize.y; i++) { if(stage.at( (allSize.x * i + start.x)) != b) { return y; } y++; } return y; } // ##################################### X軸からYの長さを取得 ##################################### int Generate_Dungeon::GetCheckLineUp(glm::ivec2 start) { byte b = stage.at( (allSize.x * start.y) + start.x); int y = 0; for(int i = start.y; i > 0; i--) { if(stage.at( (allSize.x * i + start.x)) != b) { return y; } y++; } return y; } // ##################################### Y軸からXの長さを取得 ##################################### int Generate_Dungeon::GetCheckLineRight(glm::ivec2 start) { byte b = stage.at( (allSize.x * (start.y) ) + start.x); int x = 0; for(int i = start.x; i < allSize.x; i++) { if(stage.at( (allSize.x * start.y) + i) != b) { return x; } x++; } return x; } // ##################################### Y軸からXの長さを取得 ##################################### int Generate_Dungeon::GetCheckLineLeft(glm::ivec2 start) { byte b = stage.at( (allSize.x * (start.y) ) + start.x); int x = 0; for(int i = start.x; i > 0; i--) { if(stage.at( (allSize.x * start.y) + i) != b) { return x; } x++; } return x; } // ##################################### ステージに値を設定 ##################################### void Generate_Dungeon::SetStage(glm::ivec2 pos,byte b) { stage.at((allSize.x * pos.y) + pos.x) = b; } // ##################################### ステージに値を取得 ##################################### byte Generate_Dungeon::GetStage(glm::ivec2 pos) { return stage.at((allSize.x * pos.y) + pos.x); } // ##################################### X軸に分割ラインを引く ##################################### void Generate_Dungeon::SetLine_Width(int posY) { byte b = GetStage(glm::ivec2(0,posY)); for(int x = 0; x < allSize.x; x++) { if(b == GetStage(glm::ivec2(x,posY))) { SetStage(glm::ivec2(x,posY),flag); } else { break; } } } // ##################################### Y軸に分割ラインを引く ##################################### void Generate_Dungeon::SetLine_Height(int posX) { byte b = GetStage(glm::ivec2(posX,0)); for(int y = 0; y < allSize.y; y++) { if(b == GetStage(glm::ivec2(posX,y))) { SetStage(glm::ivec2(posX,y),flag); } else { break; } } } // ##################################### エリアを作成 ##################################### void Generate_Dungeon::SetCreateArea() { } // ##################################### エリアを取得 ##################################### glm::ivec2 Generate_Dungeon::GetAreaSize(glm::ivec2 start) { glm::ivec2 size = glm::ivec2(0,0); byte b = GetStage(start); for(int x = 0; x < allSize.x; x++) { if(GetStage(start + glm::ivec2(x,0)) != b) { break; } else { size.x += 1; } } for(int y = 0; y < allSize.y; y++) { if(GetStage(start + glm::ivec2(0,y)) != b) { break; } else { size.y += 1; } } return size; } // ##################################### min以上の間隔で0~maxまでの位置を取得 ##################################### int Generate_Dungeon::GetRandom_Width(int min,int max) { while(true) { int rand = FrameWork::GetRandom(0,max); if((min < GetCheckLineUp(glm::ivec2(0,rand))) && (min < GetCheckLineDown(glm::ivec2(0,rand)))) { return rand; } } } // ##################################### min以上の間隔で0~maxまでの位置を取得 ##################################### int Generate_Dungeon::GetRandom_Height(int min,int max) { while(true) { int rand = FrameWork::GetRandom(0,max); if((min < GetCheckLineLeft(glm::ivec2(rand,0))) && (min < GetCheckLineRight(glm::ivec2(rand,0)))) { return rand; } } } // ##################################### ステージを生成 ##################################### void Generate_Dungeon::setGenerate() { for(int i = 0; i < divNum; i++) { SetLine_Height(GetRandom_Height(minSize.x,allSize.x - minSize.x)); SetLine_Width(GetRandom_Width(minSize.y,allSize.y - minSize.y)); } } // ##################################### ステージを取得 ##################################### std::vector<byte> Generate_Dungeon::getStage() { return stage; } // ##################################### デストラクタ ##################################### Generate_Dungeon::~Generate_Dungeon() { }
まだ回答がついていません
会員登録して回答してみよう