Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Last active April 8, 2025 12:56
Show Gist options
  • Save kujirahand/3f1acb7d148f4f9b4ac998f92b048a79 to your computer and use it in GitHub Desktop.
Save kujirahand/3f1acb7d148f4f9b4ac998f92b048a79 to your computer and use it in GitHub Desktop.
lifegame using PyScript
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<!-- PyScriptのライブラリを取り込み -->
<link rel="stylesheet" href="https://pyscript.net/releases/2025.3.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.3.1/core.js"></script>
<title>PyScriptでライフゲーム</title>
</head>
<body>
<h1>ライフゲーム</h1>
<canvas id="game" width="400" height="400" style="border: 1px solid black">
</canvas><br />
<button id="start-btn">▶️ 開始する</button>
<button id="reset-btn">🔄 初期化</button>
<script type="py">
# 必要なライブラリをインポートする --- (*1)
from js import document, window
from pyodide.ffi import create_proxy
import random, math
# 描画用のコンテキストを取得する --- (*2)
canvas = document.getElementById("game")
ctx = canvas.getContext("2d")
# キャンバスのサイズを計算
cell_size = 10
rows = canvas.height // cell_size
cols = canvas.width // cell_size
interval_id = None
# グリッドを初期化 --- (*3)
def create_grid():
global grid
grid = [[random.choice([0, 0, 1]) for _ in range(cols)] for _ in range(rows)]
# グリッドを描画する --- (*4)
def draw_grid():
ctx.clearRect(0, 0, canvas.width, canvas.height)
for y in range(rows):
for x in range(cols):
# 値が1の時生物を描画する ---- (*5)
if grid[y][x] == 1:
ctx.beginPath()
ctx.arc(
x * cell_size + cell_size / 2,
y * cell_size + cell_size / 2,
cell_size / 2,
0,
2 * math.pi
)
ctx.fillStyle = "red"
ctx.fill()
ctx.closePath()
# グリッドの世代を進める --- (*6)
def update_grid():
global grid
new_grid = [[0 for _ in range(cols)] for _ in range(rows)]
for y in range(rows):
for x in range(cols):
neighbors = sum(
grid[(y + dy) % rows][(x + dx) % cols]
for dy in [-1, 0, 1]
for dx in [-1, 0, 1]
if not (dy == 0 and dx == 0)
)
if grid[y][x] == 1 and neighbors in [2, 3]:
new_grid[y][x] = 1
elif grid[y][x] == 0 and neighbors == 3:
new_grid[y][x] = 1
grid = new_grid
draw_grid()
# 開始・停止・リセット --- (*7)
def start(event):
global interval_id
if interval_id is None:
# タイマーイベントを設定 --- (*8)
interval_id = window.setInterval(
create_proxy(update_grid), 300)
def stop(event):
global interval_id
if interval_id is not None:
window.clearInterval(interval_id)
interval_id = None
def reset(event):
stop(None)
create_grid()
draw_grid()
# ボタン操作を指定 --- (*9)
document.getElementById("start-btn").onclick = create_proxy(start)
document.getElementById("reset-btn").onclick = create_proxy(reset)
reset(None)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment