3D 迷路(立体迷路)を作って、自動で探索(探索アルゴリズムでゴールへ到達)する Java サンプルを、
プログラミング初心者向けに“超かみ砕いて”説明します。
以下の内容がセットになっています:
✅ 3D 迷路の考え方
✅ 3D 配列で迷路を表す方法
✅ 自動探索(BFS / DFS)
✅ ステップごとの解説
✅ 完全な Java 動くサンプルコード
1. 3D 迷路とは?(まずイメージ)
2D 迷路は「縦 × 横」
3D 迷路は「縦 × 横 × 高さ(階層)」で迷路を扱います。
階層 = Z(高さ)
行 = Y
列 = X
3D 配列のイメージ:
maze[z][y][x]
2. 迷路の表現(0 = 通路 / 1 = 壁)
例:3階建ての迷路(3 × 5 × 5)
Z = 0 (1階)
Z = 1 (2階)
Z = 2 (3階)
Java の配列:
int[][][] maze = {
{ // Z=0 (1階)
{0,1,0,0,0},
{0,1,0,1,0},
{0,0,0,1,0},
{1,1,0,0,0},
{0,0,0,1,0}
},
{ // Z=1 (2階)
{0,0,1,1,0},
{1,0,0,1,0},
{1,1,0,0,0},
{0,0,0,1,1},
{0,1,0,0,0}
},
{ // Z=2 (3階)
{0,0,0,1,0},
{1,1,0,1,0},
{0,0,0,0,0},
{0,1,1,1,0},
{0,0,0,1,0}
}
};
Java3. 自動探索(BFS)とは?
3D の「迷路探索」でよく使うのが BFS(幅優先探索)。
BFS の特徴:
- 一番近いルートを最優先して広げる
- ゴールまでの最短ルートが確実に見つかる
- キュー(Queue)を使う
移動方向は 3D なので 6 方向:
+X(右)
−X(左)
+Y(下)
−Y(上)
+Z(上の階へ)
−Z(下の階へ)
4. 完全サンプル:3D 迷路の探索(BFS)
✔ このサンプルは以下を実装
- 3D 迷路を配列で定義
- BFS で自動探索
- 移動ログを表示
- ゴールまでの最短経路を復元して表示
完全 Java コード(コピペで動く)
import java.util.*;
public class Maze3D {
// 移動方向(x, y, z)
static int[][] DIRS = {
{ 1, 0, 0}, // 右
{-1, 0, 0}, // 左
{ 0, 1, 0}, // 下
{ 0,-1, 0}, // 上
{ 0, 0, 1}, // 上の階
{ 0, 0,-1} // 下の階
};
public static void main(String[] args) {
// ------- 3D迷路定義(0=道、1=壁)-----------
int[][][] maze = {
{ // Z=0
{0,1,0,0,0},
{0,1,0,1,0},
{0,0,0,1,0},
{1,1,0,0,0},
{0,0,0,1,0}
},
{ // Z=1
{0,0,1,1,0},
{1,0,0,1,0},
{1,1,0,0,0},
{0,0,0,1,1},
{0,1,0,0,0}
},
{ // Z=2
{0,0,0,1,0},
{1,1,0,1,0},
{0,0,0,0,0},
{0,1,1,1,0},
{0,0,0,1,0}
}
};
int zSize = maze.length;
int ySize = maze[0].length;
int xSize = maze[0][0].length;
// start と goal
int[] start = {0, 0, 0}; // (x=0,y=0,z=0)
int[] goal = {4, 4, 2}; // (右下・最上階)
List<int[]> path = bfs(maze, start, goal);
if (path == null) {
System.out.println("ゴールまでの道が見つかりませんでした。");
} else {
System.out.println("=== 最短ルート ===");
for (int[] p : path) {
System.out.printf("(x=%d, y=%d, z=%d)\n", p[0], p[1], p[2]);
}
}
}
// BFSで探索
static List<int[]> bfs(int[][][] maze, int[] start, int[] goal) {
int zSize = maze.length;
int ySize = maze[0].length;
int xSize = maze[0][0].length;
boolean[][][] visited = new boolean[zSize][ySize][xSize];
int[][][] prev = new int[zSize][ySize][xSize]; // 経路復元用
Queue<int[]> queue = new ArrayDeque<>();
queue.add(start);
visited[start[2]][start[1]][start[0]] = true;
prev[start[2]][start[1]][start[0]] = -1; // 開始点
while (!queue.isEmpty()) {
int[] cur = queue.poll();
int x = cur[0], y = cur[1], z = cur[2];
if (x == goal[0] && y == goal[1] && z == goal[2]) {
return buildPath(prev, start, goal);
}
for (int[] d : DIRS) {
int nx = x + d[0];
int ny = y + d[1];
int nz = z + d[2];
if (0 <= nz && nz < zSize &&
0 <= ny && ny < ySize &&
0 <= nx && nx < xSize &&
maze[nz][ny][nx] == 0 &&
!visited[nz][ny][nx])
{
visited[nz][ny][nx] = true;
prev[nz][ny][nx] = z*10000 + y*100 + x; // 前の座標を保存
queue.add(new int[]{nx,ny,nz});
}
}
}
return null;
}
// 経路復元(prev の値を逆にたどる)
static List<int[]> buildPath(int[][][] prev, int[] start, int[] goal) {
List<int[]> path = new ArrayList<>();
int x = goal[0], y = goal[1], z = goal[2];
while (true) {
path.add(new int[]{x,y,z});
if (x==start[0] && y==start[1] && z==start[2]) break;
int v = prev[z][y][x];
int px = v % 100;
int py = (v / 100) % 100;
int pz = v / 10000;
x = px; y = py; z = pz;
}
Collections.reverse(path);
return path;
}
}
Java実行結果(例)
=== 最短ルート ===
(x=0, y=0, z=0)
(x=0, y=1, z=0)
(x=0, y=2, z=0)
(x=1, y=2, z=0)
(x=2, y=2, z=0)
(x=2, y=2, z=1)
(x=2, y=2, z=2)
(x=3, y=2, z=2)
(x=4, y=2, z=2)
(x=4, y=3, z=2)
(x=4, y=4, z=2)
3階を含む立体迷路の探索ができています。


