Lufe Game in TOPOS-Ξ 2
// トポロジカル構造定義
space LifeGame {
properties {
dimension: Topology<Number>(2)
continuous: Topology<Boolean>(false)
quantum: Topology<Boolean>(false)
}
// 標準出力定義
shape StandardOutput<T> extends Observable<T> {
properties {
classical: true
observable: true
}
}
// セル構造の定義
shape Cell {
properties {
state: Observable<Boolean>
position: Topology<Vector2D>
}
mapping toggle() {
path {
invert_state ->
notify_observers
}
}
}
// グリッド構造の定義
shape Grid {
properties {
width: Number(25)
height: Number(25)
cells: Collection<Cell>
periodic: Boolean(true)
}
// 近傍計算のトポロジカル写像
mapping compute_neighbors(pos: Vector2D) -> Number {
properties {
continuous: true
deterministic: true
}
path {
let count = 0
for dx in [-1, 0, 1] {
for dy in [-1, 0, 1] {
if (dx == 0 && dy == 0) continue
// トーラス位相による周期的境界条件
let nx = (pos.x + dx + width) % width
let ny = (pos.y + dy + height) % height
if (cells[nx][ny].state) count += 1
}
}
return count
}
}
// 状態遷移の写像
mapping evolve() {
properties {
continuous: true
deterministic: true
}
path {
// 新状態の計算
let new_states: Collection<Boolean> = []
for x in [0..width-1] {
for y in [0..height-1] {
let neighbors = compute_neighbors(Vector2D(x, y))
let current = cells[x][y].state
let new_state = when {
current && neighbors == 2 -> true
current && neighbors == 3 -> true
!current && neighbors == 3 -> true
else -> false
}
new_states.append(new_state)
}
}
// 状態の一括更新
update_all_cells(new_states)
}
}
// 表示の写像
mapping display() -> StandardOutput<Text> {
properties {
observable: true
classical: true
}
path {
let output = StringBuilder()
// 上部境界
output.append("┌" + "─".repeat(width*2) + "┐\n")
// セル状態の描画
for x in [0..height-1] {
output.append("│")
for y in [0..width-1] {
output.append(
if cells[x][y].state then "■ " else "□ "
)
}
output.append("│\n")
}
// 下部境界
output.append("└" + "─".repeat(width*2) + "┘\n")
StandardOutput<Text>(output.toString())
}
}
}
// メインループ
mapping run() {
properties {
continuous: true
observable: true
}
path {
// グリッドの初期化
let grid = Grid(25, 25)
// ランダムな初期状態の設定
grid.randomize(probability: 0.3)
while true {
// 状態の表示
grid.display()
// 状態遷移
grid.evolve()
// インターバル
wait(milliseconds: 200)
}
}
}
}
// メイン実行部
space Main {
mapping main() {
let game = LifeGame()
game.run()
}
}
標準出力を追加し、言語仕様に対して厳密に記述したので、これは、コンパイルできれば実際実行できるものと思います。
コンパイルできるわけじゃぁないので、これをPythonに移植しました。
import numpy as np
import time
import os
class GameOfLife:
def __init__(self, width=25, height=25):
self.width = width
self.height = height
self.grid = np.zeros((height, width), dtype=bool)
self.periodic = True
def randomize(self, probability=0.3):
"""Initialize the grid with random state"""
self.grid = np.random.random((self.height, self.width)) < probability
def compute_neighbors(self, x, y):
"""Compute number of neighbors using toroidal topology"""
count = 0
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if dx == 0 and dy == 0:
continue
# Implement periodic boundary conditions (toroidal topology)
nx = (x + dx + self.width) % self.width
ny = (y + dy + self.height) % self.height
if self.grid[ny, nx]:
count += 1
return count
def evolve(self):
"""Evolve the grid one step using Game of Life rules"""
new_grid = np.zeros_like(self.grid)
for x in range(self.width):
for y in range(self.height):
neighbors = self.compute_neighbors(x, y)
current = self.grid[y, x]
# Apply Conway's Game of Life rules
if current and neighbors in [2, 3]:
new_grid[y, x] = True
elif not current and neighbors == 3:
new_grid[y, x] = True
self.grid = new_grid
def display(self):
"""Display the current state of the grid"""
# Clear screen (works on both Windows and Unix-like systems)
os.system('cls' if os.name == 'nt' else 'clear')
# Draw top border
print("┌" + "─" * (self.width * 2) + "┐")
# Draw grid
for y in range(self.height):
print("│", end="")
for x in range(self.width):
print("■ " if self.grid[y, x] else "□ ", end="")
print("│")
# Draw bottom border
print("└" + "─" * (self.width * 2) + "┘")
def run(self, interval=0.2):
"""Main game loop"""
try:
while True:
self.display()
self.evolve()
time.sleep(interval)
except KeyboardInterrupt:
print("\nGame terminated by user")
def main():
# Initialize game
game = GameOfLife(25, 25)
# Set random initial state
game.randomize(0.3)
# Run the game
game.run()
if __name__ == "__main__":
main()
かなりエレガントなソースじゃぁないですか。
かなりすばらしいと思いません?
元となるトポロジ言語があっさりとエレガントさを醸し出すのがわかりますねぇ。
結局パイソンでもトポスクサイでもない実装www