Files
hakorune/examples/maze_generator.hako

228 lines
5.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 🌀 迷路ジェネレーター - 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!")