📌ㅤ헥사곤 그리드 배치
📍
제약 및 구현 조건
- 방들이 겹치거나 중간에 빈 공간이 생기지 않아야 한다.
- 규칙성 있게 확장되어야 하며, 나의 방은 항상 중앙에 위치해야 한다.
- 헥사곤 좌표계를 이용하여 배치한다.
🚨 10번째 방부터 중복 배치되는 현상

⛔️
문제 정의
- 헥사곤 그리드를 사용하여 방을 배치하는 과정에서 10번째 방 이후부터 중복 배치되는 현상이 발생했다.
- 육각형 그리드의 기하학적 특성과 좌표계의 일관성을 보장하지 못한 좌표 배치 로직에서 발생했다.
📎
헥사곤 그리드의 좌표 시스템
- 헥사곤 그리드를 코드로 구현하려면, 좌표 시스템이 필요하다.
- 여러가지 좌표 시스템이 있지만, 큐브 좌표계가 직관적이고 계산이 쉬워서 이를 활용했다.
✅ㅤ큐브 좌표계
- 형식 :
[q, r, s] - 항상
q + r + s = 0조건을 만족해야 한다. - 3개의 축(q, r, s)을 사용하며, 각 축은 6방향 중 3개의 방향을 표현
- 장점 : 방향 계산이 직관적이며, 인접 셀 계산이 쉬움.
중앙: [0, 0, 0] | 왼쪽: [-1, 0, 1] | 오른쪽: [1, 0, -1]
🤔
문제 분석
q + r + s = 0조건을 만족하지 않는 좌표가 생성visitedSet을 활용했으나, 잘못된 위치에서도 중복 방이 배치
jsx
1
const directions = [
[1, -1, 0], // 6. 위 오른쪽 대각선 상단
[0, -1, 1], // 5. 위 왼쪽 대각선 상단
[0, 1, 1], // 4. 아래 왼쪽 대각선 하단
[-1, 1, 1], // 3. 아래 오른쪽 대각선 하단
[-1, 0, 1], // 2. 왼쪽
[1, 0, -1], // 1. 오른쪽
];jsx
1
for (let step = 0; step < steps && result.length < roomCount; step++) {
const posKey = `${cubeX},${cubeY},${cubeZ}`;
if (!visited.has(posKey)) { // ✅ 방문 여부만 확인
visited.add(posKey);
result.push({ position: [cubeX, cubeY, cubeZ], room: rooms[roomIndex] });
roomIndex++;
}
cubeX += directions[side][0];
cubeY += directions[side][1];
cubeZ += directions[side][2];
}- 일부
dx, dy, dz값이q + r + s = 0조건을 만족하지 않음 - 그로인해 헥사곤 그리드 내에서 유효한 위치로 간주되지 않음ㅤ➡️ㅤ중복 체크가 제대로 되지 않음
visited.has(posKey)만으로는 잘못된 위치의 중복 배치를 방지할 수 없음
✅
해결
- 큐브 좌표계의 조건을 유지하는 방향 벡터로 수정
- 중복 방지를 강화
- 배치 순서를 수정하여 순환 배치를 개선
jsx
1
const directions = [
[-1, 0, 1], // 1. 왼쪽
[1, 0, -1], // 2. 오른쪽
[0, -1, 1], // 3. 위 왼쪽 대각선 상단
[1, -1, 0], // 4. 위 오른쪽 대각선 상단
[-1, 1, 0], // 5. 아래 왼쪽 대각선 하단
[0, 1, -1], // 6. 아래 오른쪽 대각선 하단
];jsx
1
for (let step = 0; step < (ring - 1) && placedInRing < positionsInRing; step++) {
const [x, y, z] = currentPos;
const posKey = `${x},${y},${z}`;
if (!visited.has(posKey) && (x + y + z) === 0) {
visited.add(posKey);
result.push({ position: [x, y, z], room: rooms[roomIndex] });
roomIndex++;
placedInRing++;
}
currentPos = [x + dx, y + dy, z + dz];
}
🚨 18번째 방부터 아래쪽에서만 배치되는 현상

⛔️
문제 정의
헥사곤 그리드를 확장하면서 18번째 방 이후부터 배치 방향이 한쪽으로만 치우치는 현상이 발생했다.
🤔
문제 분석
baseIndex가 단일 위치로 고정되어 있음- 새로운 위치를 찾을 때, 이전 링의 첫 번째 요소만 기준으로 사용하여 의도대로 안 이루어짐
- 그렇게 일부 방향에서 배치가 누락되면서 아래쪽으로만 방이 추가
jsx
1
const baseIndex = previousRing[directionIndex % previousRing.length];
const basePos = result[baseIndex].position;
const [dx, dy, dz] = dir;
const newPos: Position = [basePos[0] + dx, basePos[1] + dy, basePos[2] + dz];
const posKey = `${newPos[0]},${newPos[1]},${newPos[2]}`;
if (!visited.has(posKey) && newPos[0] + newPos[1] + newPos[2] === 0) {
visited.add(posKey);
result.push({ position: newPos, room: rooms[roomIndex] });
return { roomIndex: roomIndex + 1, placedInRing: placedInRing + 1 };
}✅
해결
baseIndex를 단일 위치가 아닌, 이전 링의 모든 위치를 순회하며 유효한 새 위치를 찾도록 수정(directionIndex + i) % previousRing.length로 시작점을 조정하여 방형별 배치가 누락되지 않도록 개선
jsx
1
for (let i = 0; i < previousRing.length; i++) {
const baseIndex = previousRing[(directionIndex + i) % previousRing.length];
const basePos = result[baseIndex].position;
const [dx, dy, dz] = dir;
const newPos: Position = [basePos[0] + dx, basePos[1] + dy, basePos[2] + dz];
const posKey = `${newPos[0]},${newPos[1]},${newPos[2]}`;
if (!visited.has(posKey) && newPos[0] + newPos[1] + newPos[2] === 0) {
visited.add(posKey);
result.push({ position: newPos, room: rooms[roomIndex] });
return { roomIndex: roomIndex + 1, placedInRing: placedInRing + 1 };
}
}
return { roomIndex, placedInRing };💬ㅤ비하인드
어지러운
x,y,z좌표계.... 최상의 배치를 맞추기 위한 노력...


첫 번째 링을 완성하기 까지의 여정...


첫 번째 링 이후의 방황하는 방들...


여러가지 확장 방식을 시도해보면서 겪은 다양한 형태




