Использование A* для создания процедурно сгенерированных комнат при обработкеJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Гость
 Использование A* для создания процедурно сгенерированных комнат при обработке

Сообщение Гость »


I've been working on this Processing project for a couple days and have a couple questions. First I'll show you where I started and how I got to where I am.
I first began by using a variation of the A* algorithm to randomly generate mazes as seen below.
A depiction of the maze:
Изображение
I divide the window into even cells, and give each one four walls, and let the A* algorithm do its thing.
it gives the result you see above.
Next I decided I wanted to have more dynamically shaped and placed rooms, so I took advantage of how all the cells are evenly spaced, and placed a room of random size, at least half the size of a cell, and at most the size of a cell. The result can be seen below.
Using the cells to make rooms:
Изображение
For clarification, red lines indicate a solid wall, and green represents doorways. Now while I could generate hallways in-between each room, to connect them in the shape of the maze, I believe that this could create unnecessarily long walks in-between rooms.
I decided to add a section to the part of the algorithm that moves the random walker, so that when it creates a new room, it moves it closer to the room it moved from. Once again I present the results below.
Moving the rooms closer together:
Изображение
As you can see this presented some obvious errors in the map generation. The arrows I drew point to two rooms that should be connected as you can see by their respective coordinates (7, 7) -> (7, 8). I then realized that when the walker moved up for example, not only would I have to move that room down, but I may also have to move left or right, after fixing this simple oversite everything was looking good, until I realized a couple of the rooms overlapped.
Rooms sometimes overlap:
Изображение
In the image above I highlighted some of the overlap. I thought of a few ways I could solve this issue. Maybe I could have all the colliding rooms shrink their size little by little? but this would only work if they weren't intersecting over their position coordinate. Maybe I could move them away from each other? This might cause their partner rooms to become disconnected resulting in the whole thing needing to be moved around. Maybe even multiple times over. Эта дилемма — мой первый вопрос.

Код: Выделить всё

Generator gen;

void setup() {
size(1500, 900);
background(0);

int max = 100;
gen = new Generator(floor(width/max), floor(height/max), max);
}

void draw() {
}

void keyPressed() {
setup();
}

Код: Выделить всё

class Generator {
ArrayList stack = new ArrayList();
Room rooms[][];
PVector pos;

float buffer = 20;
float gap = 2;

boolean done = false;

int maxRoomSize;
int columns;
int rows;

Generator(int col, int row, int max) {
maxRoomSize = max;
columns = col;
rows = row;

pos = new PVector(floor(random(columns)), floor(random(rows)));

rooms = new Room[columns][rows];
for (int x = 0; x < columns; x++) {
for (int y = 0; y < rows; y++) {
rooms[x][y] = new Room(x, y, maxRoomSize);
}
}

generateMap();

showRooms();
}

void generateMap() {
while (!done) {
ArrayList dir = new ArrayList();
int x = int(pos.x);
int y = int(pos.y);
if (x > 0 && !rooms[x-1][y].visited) {
dir.add("Left");
}

if (x < columns-1 && !rooms[x+1][y].visited) {
dir.add("Right");
}

if (y > 0 && !rooms[x][y-1].visited) {
dir.add("Up");
}

if (y < rows-1 && !rooms[x][y+1].visited) {
dir.add("Down");
}

int chance = round(random(1, dir.size()));
String move = "";
if (dir.size() > 0) {
move = dir.get(chance-1);
}

if (!rooms[x][y].visited) {
rooms[x][y].visited = true;
}

if (move == "Up") {
up(x, y);
} else if (move == "Right") {
right(x, y);
} else if (move == "Down") {
down(x, y);
} else if (move == "Left") {
left(x, y);
} else if (stack.size() > 0) {
pos = stack.get(stack.size()-1);
stack.remove(stack.size()-1);
} else {
done = true;
}
}
}

void up(int x, int y) {
Room currentRoom = rooms[x][y];
Room nextRoom = rooms[x][y-1];

nextRoom.worldPos.y += currentRoom.worldPos.y - (nextRoom.worldPos.y+nextRoom.roomHeight) - gap;

if (currentRoom.worldPos.x - (nextRoom.worldPos.x+nextRoom.roomWidth) > -buffer) {
nextRoom.worldPos.x += currentRoom.worldPos.x - (nextRoom.worldPos.x+nextRoom.roomWidth) - gap + buffer;
}

if (nextRoom.worldPos.x - (currentRoom.worldPos.x+currentRoom.roomWidth) > -buffer) {
nextRoom.worldPos.x -= nextRoom.worldPos.x - (currentRoom.worldPos.x+currentRoom.roomWidth) - gap + buffer;
}

currentRoom.t = false;
nextRoom.b = false;

pos.y -= 1;
stack.add(pos.copy());
}

void right(int x, int y) {
Room currentRoom = rooms[x][y];
Room nextRoom = rooms[x+1][y];

nextRoom.worldPos.x -= nextRoom.worldPos.x - (currentRoom.worldPos.x+currentRoom.roomWidth) - gap;

if (currentRoom.worldPos.y - (nextRoom.worldPos.y+nextRoom.roomHeight) > -buffer) {
nextRoom.worldPos.y += currentRoom.worldPos.y - (nextRoom.worldPos.y+nextRoom.roomHeight) - gap + buffer;
}

if (nextRoom.worldPos.y - (currentRoom.worldPos.y+currentRoom.roomHeight) > -buffer) {
nextRoom.worldPos.y -= nextRoom.worldPos.y - (currentRoom.worldPos.y+currentRoom.roomHeight) - gap + buffer;
}

currentRoom.r = false;
nextRoom.l = false;

pos.x += 1;
stack.add(pos.copy());
}

void down(int x, int y) {
Room currentRoom = rooms[x][y];
Room nextRoom = rooms[x][y+1];

nextRoom.worldPos.y -= nextRoom.worldPos.y - (currentRoom.worldPos.y+currentRoom.roomHeight) - gap;

if (currentRoom.worldPos.x - (nextRoom.worldPos.x+nextRoom.roomWidth) > -buffer) {
nextRoom.worldPos.x += currentRoom.worldPos.x - (nextRoom.worldPos.x+nextRoom.roomWidth) - gap + buffer;
}

if (nextRoom.worldPos.x - (currentRoom.worldPos.x+currentRoom.roomWidth) - buffer >  -buffer) {
nextRoom.worldPos.x -= nextRoom.worldPos.x - (currentRoom.worldPos.x+currentRoom.roomWidth) - пробел + буфер;

currentRoom.b = false;
nextRoom.t = false;

pos.y += 1;
stack.add(pos.copy());

void left(int x, int y) {
Комната currentRoom = Rooms[x][y];
Комната nextRoom = Rooms[x-1][y] ;

nextRoom.worldPos.x += currentRoom.worldPos.x - (nextRoom.worldPos.x+nextRoom.roomWidth) - пробел;

if (currentRoom.worldPos. y - (nextRoom.worldPos.y+nextRoom.roomHeight) > -buffer) {
nextRoom.worldPos.y += currentRoom.worldPos.y - (nextRoom.worldPos.y+nextRoom.roomHeight) - пробел + буфер ;
}

if (nextRoom.worldPos.y - (currentRoom.worldPos.y+currentRoom.roomHeight) > -buffer) {
nextRoom.worldPos.y -= nextRoom .worldPos.y - (currentRoom.worldPos.y+currentRoom.roomHeight) - пробел + буфер;

currentRoom.l = false;
nextRoom.r = false;

pos.x -= 1;
stack.add(pos.copy());

void showRooms() {
for (int x = 0; х 
class Room {
PVector pos;

Boolean t = true;
Boolean r = true;
Boolean b = true;
Boolean l = true;

Boolean visited = false;

int maxRoomSize;
int roomWidth;
int roomHeight;
PVector worldPos;

PVector moved = new PVector();

Room(int x, int y, int max) {
pos = new PVector(x, y);

maxRoomSize = max;
roomWidth = floor(random(maxRoomSize/2, maxRoomSize));
roomHeight = floor(random(maxRoomSize/2, maxRoomSize));

worldPos = new PVector(floor(random(pos.x*maxRoomSize, pos.x*maxRoomSize+(maxRoomSize-roomWidth))), floor(random(pos.y*maxRoomSize, pos.y*maxRoomSize+(maxRoomSize-roomHeight))));
}

void showRooms() {
push();
noFill();
stroke(1, 200, 32);
rect(worldPos.x, worldPos.y, roomWidth, roomHeight);

stroke(255);
text(int(pos.x) + ", " + int(pos.y), worldPos.x+1, worldPos.y + 10);
pop();

push();
noFill();
stroke(255, 0, 0);

float x = worldPos.x;
float y = worldPos.y;

float w = roomWidth;
float h = roomHeight;

if (t) {
line(x, y, x+w, y);
}

if (r) {
line(x+w, y, x+w, y+h);
}

if (b) {
line(x+w, y+h, x, y+h);
}

if (l) {
line(x, y+h, x, y);
}
pop();
}

void showMaze() {
float x = pos.x*maxRoomSize;
float y = pos.y*maxRoomSize;

float w = maxRoomSize;
float h = maxRoomSize;

push();
noStroke();
fill(0, 200, 0);
rect(x, y, w, h);
pop();

push();
noFill();
strokeWeight(3);
stroke(1, 50, 32);

if (t) {
line(x, y, x+w, y);
}

if (r) {
line(x+w, y, x+w, y+h);
}

if (b) {
line(x+w, y+h, x, y+h);
}

if (l) {
line(x, y+h, x, y);
}
pop();
}
}
If you see any way for me to optimize this please let me know, I am open to any and all suggestions. Especially suggestions related to writing code in a way that's easier to understand from outside eyes, and easier to make sense of. Do keep in mind I am entirely self taught and it is likely I don't know things that I probably should by the time I'm attempting a project like this, so I apologize if the answer should be obvious.
To all those who read this far and answer: Seriously - Thank You! I've been stuck on this for a while and haven't been able to make any progress and I can't get it out of my mind.


Источник: https://stackoverflow.com/questions/780 ... processing
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как я могу процедурно объединить все PDF-файлы в каталоге в один PDF-файл, названный в зависимости от каталога, и повтор
    Anonymous » » в форуме Linux
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Процедурно генерировать модели glb
    Anonymous » » в форуме Html
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Процедурно генерировать модели glb
    Anonymous » » в форуме Html
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Внедрить базу данных комнат в Koin в режиме создания мультиплатформы.
    Anonymous » » в форуме Android
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Использование базы данных комнат с Dagger 2 и Multi-Module Project
    Anonymous » » в форуме Android
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»