diff --git a/src/iframe/life-game.html b/src/iframe/life-game.html index 0c4d69c..9c936cf 100644 --- a/src/iframe/life-game.html +++ b/src/iframe/life-game.html @@ -13,9 +13,7 @@ padding-top: 10px; " > -
-
-
+
diff --git a/src/iframe/life-game.js b/src/iframe/life-game.js index 0daea76..5cea482 100644 --- a/src/iframe/life-game.js +++ b/src/iframe/life-game.js @@ -1,37 +1,44 @@ "use strict"; -let timer = "stop"; let generationFigure = 0; let isDragging = false; -let dragMode = 0; // 1: 黒にする, 0: 白にする +let dragMode = 0; // 1: 生きたセルにする, 0: 死んだセルにする let isPlacingTemplate = false; let patternShape = []; let patternHeight = 0; let patternWidth = 0; let previewCells = []; -//変数設定 -let boardSize = 20; //盤面の大きさ(20x20) -const cellSize = 600 / boardSize; //セルの大きさ(px) +//盤面の大きさ +let boardSize = 20; +const cellSize = 450 / boardSize; + +//セルの色 +const aliveCellColor = "black"; +const deadCellColor = "white"; + +//セルの誕生/生存条件 +const birthCounts = [3]; +const survivalCounts = [2, 3]; // around: 周囲の生きたセル数 self: 自身が生きているかどうか function isNextAlive(around, self) { - // 自身が生きている & 周囲が 2 か 3 で生存 - if (self && 2 <= around && around <= 3) { - return self; - } - // 自身が死んでいる & 周囲が 3 で誕生 - if (!self && around === 3) { + // 自身が死んでいる & 周囲が birthCounts で誕生 + if (!self && birthCounts.includes(around)) { return 1; } + // 自身が生きている & 周囲が survivalCounts で生存 + if (self && survivalCounts.includes(around)) { + return self; + } return 0; } // cellの状態に応じた色を返す関数 function getStyle(cell) { - if (cell === 0) return "white"; + if (cell === 0) return deadCellColor; // cellの値に応じて色を返す場合はここに追加 - return "black"; // デフォルトは黒 + return aliveCellColor; // デフォルトは黒 } //Boardの初期化 @@ -57,7 +64,7 @@ function renderBoard() { const td = document.createElement("td"); td.style.padding = "0"; const button = document.createElement("button"); - button.style.backgroundColor = board[i][j] ? "black" : "white"; //Boardの対応する値によって色を変更 + button.style.backgroundColor = board[i][j] ? aliveCellColor : deadCellColor; //Boardの対応する値によって色を変更 // ボードが大きいときは border をつけない if (boardSize >= 50) { button.style.border = "none"; @@ -67,8 +74,8 @@ function renderBoard() { } button.style.width = `${cellSize}px`; button.style.height = `${cellSize}px`; - button.style.padding = "0"; //cellSizeが小さいとき、セルが横長になることを防ぐ - button.style.display = "block"; //cellSizeが小さいとき、行間が空きすぎるのを防ぐ + button.style.padding = "0"; + button.style.display = "block"; button.onclick = () => { if (isPlacingTemplate) { clearPreview(); @@ -96,17 +103,17 @@ function renderBoard() { }; button.onmousedown = (e) => { e.preventDefault(); - if (timer === "stop" && !isPlacingTemplate) { + if (!isPlacingTemplate) { isDragging = true; - board[i][j] = !board[i][j]; + board[i][j] = board[i][j] === 1 ? 0 : 1; dragMode = board[i][j]; - button.style.backgroundColor = board[i][j] ? "black" : "white"; + button.style.backgroundColor = board[i][j] ? aliveCellColor : deadCellColor; } }; button.onmouseenter = () => { - if (isDragging && timer === "stop" && board[i][j] !== dragMode && !isPlacingTemplate) { + if (isDragging && board[i][j] !== dragMode && !isPlacingTemplate) { board[i][j] = dragMode; - button.style.backgroundColor = board[i][j] ? "black" : "white"; + button.style.backgroundColor = board[i][j] ? aliveCellColor : deadCellColor; } if (isPlacingTemplate) { drawPreview(i, j); @@ -145,7 +152,7 @@ function drawPreview(row, col) { function clearPreview() { previewCells.forEach((cellPos) => { const cell = table.rows[cellPos.row].cells[cellPos.col].firstChild; - cell.style.backgroundColor = board[cellPos.row][cellPos.col] ? "black" : "white"; + cell.style.backgroundColor = board[cellPos.row][cellPos.col] ? aliveCellColor : deadCellColor; }); previewCells = []; } @@ -196,7 +203,7 @@ function progressBoard() { const newBoard = structuredClone(board); for (let i = 0; i < boardSize; i++) { for (let j = 0; j < boardSize; j++) { - //周囲のマスに黒マスが何個あるかを計算(aroundに格納)↓ + //周囲のマスに生きたセルが何個あるかを計算(aroundに格納)↓ let around = 0; let tate, yoko; if (i === 0) { @@ -220,7 +227,7 @@ function progressBoard() { } } } - //↑周囲のマスに黒マスが何個あるかを計算(aroundに格納) + //↑周囲のマスに生きたセルが何個あるかを計算(aroundに格納) newBoard[i][j] = isNextAlive(around, board[i][j]); } } @@ -235,23 +242,15 @@ on.progress = () => { progressBoard(); }; -on.play = () => { - timer = "start"; -}; - -on.pause = () => { - timer = "stop"; -}; - on.board_reset = () => { - //すべて白にBoardを変更 + //すべて死んだセルにBoardを変更 board = Array.from({ length: boardSize }, () => Array.from({ length: boardSize }, () => 0)); renderBoard(); generationChange(0); }; on.board_randomize = () => { - //白黒ランダムにBoardを変更 + //生きたセル死んだセルランダムにBoardを変更 board = Array.from({ length: boardSize }, () => Array.from({ length: boardSize }, () => (Math.random() > 0.5 ? 1 : 0)), ); @@ -259,18 +258,8 @@ on.board_randomize = () => { generationChange(0); }; -on.request_sync = () => { - window.parent.postMessage( - { - type: "sync", - data: { - generationFigure: generationFigure, - boardSize: boardSize, - }, - }, - "*", - ); - console.log("generationFigure:", generationFigure, "boardSize:", boardSize); +on.get_boardsize = () => { + window.parent.postMessage({ type: "get_boardsize", data: boardSize }, "*"); }; on.place_template = (template) => { @@ -279,7 +268,6 @@ on.place_template = (template) => { patternWidth = patternShape[0].length; isPlacingTemplate = true; table.style.cursor = "crosshair"; - stop(); }; on.save_board = async () => { @@ -290,5 +278,4 @@ on.apply_board = (newBoard) => { board = newBoard; renderBoard(); generationChange(0); - stop(); }; diff --git a/src/lib/components/HelpModal.svelte b/src/lib/components/HelpModal.svelte new file mode 100644 index 0000000..de5f411 --- /dev/null +++ b/src/lib/components/HelpModal.svelte @@ -0,0 +1,388 @@ + + + + + + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 2abb85e..59e190a 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -10,6 +10,7 @@ import { CodeManager } from "$lib/models/CodeManager.svelte"; import BoardModals from "$lib/components/BoardModals.svelte"; import CodeModals from "$lib/components/CodeModals.svelte"; + import HelpModal from "$lib/components/HelpModal.svelte"; import { toast } from "$lib/models/ToastStore.svelte"; import CodeMirror from "svelte-codemirror-editor"; import { javascript } from "@codemirror/lang-javascript"; @@ -23,10 +24,10 @@ let showEditor = $state(true); let preview_iframe: HTMLIFrameElement | undefined = $state(); - let isProgress = $state(false); let isJapanese = $state(true); let resetModalOpen = $state(false); - let bottomDrawerOpen = $state(false); + let helpModalOpen = $state(true); + let templateDrawerOpen = $state(false); let ruleDrawerOpen = $state(false); let generationFigure = $state(0); @@ -45,10 +46,10 @@ return newDisabledState; }); - let timer: "running" | "stopped" = $state("stopped"); + let timerIsRunnning = $state(false); let intervalMs = $state(1000); $effect(() => { - if (timer === "stopped") return; + if (!timerIsRunnning) return; const timerId = setInterval(() => { sendEvent("progress"); }, intervalMs); @@ -56,17 +57,15 @@ }); type OngoingEvent = - | "play" - | "pause" | "board_reset" | "board_randomize" | "place_template" | "save_board" | "apply_board" - | "request_sync" + | "get_boardsize" | "progress"; - type IncomingEvent = "generation_change" | "sync" | "Size shortage" | "save_board"; + type IncomingEvent = "generation_change" | "get_boardsize" | "Size shortage" | "save_board"; function handleMessage(event: MessageEvent<{ type: IncomingEvent; data: unknown }>) { switch (event.data.type) { @@ -74,10 +73,9 @@ generationFigure = event.data.data as number; break; } - case "sync": { - const data = event.data.data as { generationFigure: number; boardSize: number }; - generationFigure = data.generationFigure; - sizeValue = data.boardSize; + case "get_boardsize": { + const data = event.data.data as number; + sizeValue = data; break; } case "Size shortage": { @@ -173,8 +171,7 @@ + + + +
-
- - -
+
+
{isJapanese ? "世代数:" + generationFigure : "Generation:" + generationFigure}
-
- -
-
+
{isJapanese ? "現在の速度" : "Current speed"}: x{1000 / intervalMs}
-
- -
- -
+ +
{isJapanese ? "盤面" : "Board"}:
+
-
- + +
{isJapanese ? "コード" : "Code"}:
-
diff --git a/static/help_img/rules_en.png b/static/help_img/rules_en.png new file mode 100644 index 0000000..6526f32 Binary files /dev/null and b/static/help_img/rules_en.png differ diff --git a/static/help_img/rules_ja.png b/static/help_img/rules_ja.png new file mode 100644 index 0000000..53ae6e3 Binary files /dev/null and b/static/help_img/rules_ja.png differ diff --git a/static/help_img/ui_map_en.png b/static/help_img/ui_map_en.png new file mode 100644 index 0000000..fc2b887 Binary files /dev/null and b/static/help_img/ui_map_en.png differ diff --git a/static/help_img/ui_map_ja.png b/static/help_img/ui_map_ja.png new file mode 100644 index 0000000..655b719 Binary files /dev/null and b/static/help_img/ui_map_ja.png differ