228 lines
5.3 KiB
Plaintext
228 lines
5.3 KiB
Plaintext
|
|
// 🌀 迷路ジェネレーター - outboxキーワード活用デモ
|
|||
|
|
// 棒倒し法による迷路生成
|
|||
|
|
|
|||
|
|
print("=== Maze Generator with outbox ===")
|
|||
|
|
|
|||
|
|
// Cellの定義(迷路の1マス)
|
|||
|
|
box Cell {
|
|||
|
|
init { x, y, wall }
|
|||
|
|
|
|||
|
|
Cell(x_pos, y_pos) {
|
|||
|
|
me.x = x_pos
|
|||
|
|
me.y = y_pos
|
|||
|
|
me.wall = true // 初期状態は壁
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
makePassage() {
|
|||
|
|
me.wall = false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
isWall() {
|
|||
|
|
return me.wall
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 迷路Box定義
|
|||
|
|
box Maze {
|
|||
|
|
init { width, height, cells }
|
|||
|
|
|
|||
|
|
Maze(w, h) {
|
|||
|
|
me.width = w
|
|||
|
|
me.height = h
|
|||
|
|
me.cells = new MapBox() // 座標→Cellのマップ
|
|||
|
|
|
|||
|
|
// 初期化:全部壁にする
|
|||
|
|
local y, x, key, cell
|
|||
|
|
y = 0
|
|||
|
|
loop(y < h) {
|
|||
|
|
x = 0
|
|||
|
|
loop(x < w) {
|
|||
|
|
key = x + "," + y
|
|||
|
|
cell = new Cell(x, y)
|
|||
|
|
me.cells.set(key, cell)
|
|||
|
|
x = x + 1
|
|||
|
|
}
|
|||
|
|
y = y + 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 座標からCellを取得
|
|||
|
|
getCell(x, y) {
|
|||
|
|
local key
|
|||
|
|
key = x + "," + y
|
|||
|
|
return me.cells.get(key)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 迷路生成(簡易版:外周以外を通路にする)
|
|||
|
|
generate() {
|
|||
|
|
print("Generating maze...")
|
|||
|
|
|
|||
|
|
// まず通路を作る(1マスおきに)
|
|||
|
|
local y, x, cell
|
|||
|
|
y = 1
|
|||
|
|
loop(y < me.height - 1) {
|
|||
|
|
x = 1
|
|||
|
|
loop(x < me.width - 1) {
|
|||
|
|
// 奇数座標を通路にする
|
|||
|
|
if isOdd(x) && isOdd(y) {
|
|||
|
|
cell = me.getCell(x, y)
|
|||
|
|
cell.makePassage()
|
|||
|
|
}
|
|||
|
|
x = x + 1
|
|||
|
|
}
|
|||
|
|
y = y + 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 棒倒し法で壁を作る
|
|||
|
|
y = 2
|
|||
|
|
loop(y < me.height - 2) {
|
|||
|
|
if isEven(y) {
|
|||
|
|
x = 2
|
|||
|
|
loop(x < me.width - 2) {
|
|||
|
|
if isEven(x) {
|
|||
|
|
me.placeRandomWall(x, y)
|
|||
|
|
}
|
|||
|
|
x = x + 2
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
y = y + 2
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ランダムに壁を置く
|
|||
|
|
placeRandomWall(x, y) {
|
|||
|
|
// ランダムな方向を選ぶ(簡易版:固定パターン)
|
|||
|
|
local pattern, dir, dx, dy, targetX, targetY, key
|
|||
|
|
pattern = (x + y) * 7 // 疑似ランダム
|
|||
|
|
dir = pattern - (pattern >= 4) * 4 // 0-3の値
|
|||
|
|
|
|||
|
|
dx = 0
|
|||
|
|
dy = 0
|
|||
|
|
|
|||
|
|
if dir == 0 {
|
|||
|
|
dx = 0
|
|||
|
|
dy = -1
|
|||
|
|
} // 上
|
|||
|
|
if dir == 1 {
|
|||
|
|
dx = 1
|
|||
|
|
dy = 0
|
|||
|
|
} // 右
|
|||
|
|
if dir == 2 {
|
|||
|
|
dx = 0
|
|||
|
|
dy = 1
|
|||
|
|
} // 下
|
|||
|
|
if dir == 3 {
|
|||
|
|
dx = -1
|
|||
|
|
dy = 0
|
|||
|
|
} // 左
|
|||
|
|
|
|||
|
|
targetX = x + dx
|
|||
|
|
targetY = y + dy
|
|||
|
|
key = targetX + "," + targetY
|
|||
|
|
|
|||
|
|
// MapBox.hasを使ってキーの存在確認
|
|||
|
|
if me.cells.has(key) {
|
|||
|
|
local cell
|
|||
|
|
cell = me.getCell(targetX, targetY)
|
|||
|
|
cell.wall = true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 迷路を表示
|
|||
|
|
display() {
|
|||
|
|
print("\nGenerated Maze:")
|
|||
|
|
local y, x, line, cell
|
|||
|
|
y = 0
|
|||
|
|
loop(y < me.height) {
|
|||
|
|
line = ""
|
|||
|
|
x = 0
|
|||
|
|
loop(x < me.width) {
|
|||
|
|
cell = me.getCell(x, y)
|
|||
|
|
if cell.isWall() {
|
|||
|
|
line = line + "■"
|
|||
|
|
} else {
|
|||
|
|
line = line + " "
|
|||
|
|
}
|
|||
|
|
x = x + 1
|
|||
|
|
}
|
|||
|
|
print(line)
|
|||
|
|
y = y + 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// MazeFactory定義
|
|||
|
|
box MazeFactory {
|
|||
|
|
init { dummy }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// static関数でoutboxを使用
|
|||
|
|
static function MazeFactory.create(width, height) {
|
|||
|
|
print("MazeFactory.create called with size: " + width + "x" + height)
|
|||
|
|
|
|||
|
|
// outbox変数で迷路オブジェクトを作成
|
|||
|
|
outbox maze
|
|||
|
|
maze = new Maze(width, height)
|
|||
|
|
|
|||
|
|
// local変数も使う
|
|||
|
|
local message
|
|||
|
|
message = "Creating maze of size " + width + "x" + height
|
|||
|
|
print(message)
|
|||
|
|
|
|||
|
|
// 迷路を生成
|
|||
|
|
maze.generate()
|
|||
|
|
|
|||
|
|
return maze // 所有権を呼び出し側に移転
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 複数の迷路を作るデモ
|
|||
|
|
static function MazeFactory.createMultiple() {
|
|||
|
|
print("\nCreating multiple mazes...")
|
|||
|
|
|
|||
|
|
outbox small, medium, large
|
|||
|
|
|
|||
|
|
small = MazeFactory.create(11, 7)
|
|||
|
|
medium = MazeFactory.create(21, 11)
|
|||
|
|
large = MazeFactory.create(31, 15)
|
|||
|
|
|
|||
|
|
// 最初の迷路だけ返す(他は破棄される)
|
|||
|
|
return small
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ヘルパー関数(%演算子がないため工夫)
|
|||
|
|
function isOdd(n) {
|
|||
|
|
// n % 2 == 1 の代替実装
|
|||
|
|
local half
|
|||
|
|
half = 0
|
|||
|
|
loop(half * 2 < n) {
|
|||
|
|
half = half + 1
|
|||
|
|
}
|
|||
|
|
return (n - half * 2) == 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isEven(n) {
|
|||
|
|
// n % 2 == 0 の代替実装
|
|||
|
|
local half
|
|||
|
|
half = 0
|
|||
|
|
loop(half * 2 < n) {
|
|||
|
|
half = half + 1
|
|||
|
|
}
|
|||
|
|
return (n - half * 2) == 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// メイン実行
|
|||
|
|
print("\n--- Small Maze (11x7) ---")
|
|||
|
|
maze1 = MazeFactory.create(11, 7)
|
|||
|
|
maze1.display()
|
|||
|
|
|
|||
|
|
print("\n--- Medium Maze (21x11) ---")
|
|||
|
|
maze2 = MazeFactory.create(21, 11)
|
|||
|
|
maze2.display()
|
|||
|
|
|
|||
|
|
print("\n--- Multiple Maze Creation Test ---")
|
|||
|
|
firstMaze = MazeFactory.createMultiple()
|
|||
|
|
print("\nFirst maze from multiple creation:")
|
|||
|
|
firstMaze.display()
|
|||
|
|
|
|||
|
|
print("\n=== Maze Generator completed! ===")
|
|||
|
|
print("Note: Outbox variables successfully transferred ownership!")
|