|
1 | 1 | <script lang="ts"> |
2 | 2 | import lifeGameHTML from "@/iframe/life-game.html?raw"; |
3 | 3 | import lifeGameJS from "@/iframe/life-game.js?raw"; |
4 | | - import placetemplate from "@/iframe/place_template.js?raw"; |
5 | 4 | import event from "@/iframe/event.js?raw"; |
6 | 5 |
|
7 | 6 | import * as icons from "$lib/icons/index.ts"; |
|
18 | 17 | `<script> |
19 | 18 | \n${event}\n |
20 | 19 | \n${appliedCode}\n |
21 | | - \n${placetemplate}\n |
22 | 20 | <\/script>`, |
23 | 21 | ), |
24 | 22 | ); |
|
31 | 29 |
|
32 | 30 | let intervalMs = $state(1000); |
33 | 31 | let generationFigure = $state(0); |
34 | | - let sizeInputValue = $state(20); |
| 32 | + let sizeValue = $state(20); |
35 | 33 |
|
36 | 34 | type SaveState = { saving: false } | { saving: true; boardData: boolean[][] }; |
37 | 35 | let saveState: SaveState = $state({ saving: false }); |
38 | 36 | let boardNameInput = $state(""); |
39 | 37 |
|
40 | 38 | onMount(() => { |
41 | 39 | const handleMessage = (event: MessageEvent) => { |
42 | | - if (event.data.type === "patternError") { |
43 | | - alert(event.data.message); |
44 | | - } |
45 | 40 | if (event.data.type === "generation_change") { |
46 | 41 | generationFigure = event.data.data; |
47 | 42 | } |
48 | | - if (event.data.type === "stateupdate") { |
| 43 | + if (event.data.type === "Sync") { |
49 | 44 | generationFigure = event.data.data.generationFigure; |
50 | | - sizeInputValue = event.data.data.boardSize; |
| 45 | + sizeValue = event.data.data.boardSize; |
51 | 46 | } |
52 | 47 | }; |
53 | 48 |
|
|
139 | 134 | <button |
140 | 135 | class="btn overflow-hidden p-0 w-24 h-24" |
141 | 136 | onclick={() => { |
142 | | - preview_iframe?.contentWindow?.postMessage( |
143 | | - { type: "setPattern", pattern: patterns[patternName] }, |
144 | | - "*", |
| 137 | + sendEvent("requestSync"); |
| 138 | + |
| 139 | + const newBoard = Array.from({ length: sizeValue }, () => |
| 140 | + Array.from({ length: sizeValue }, () => false), |
145 | 141 | ); |
| 142 | + const patternData = patterns[patternName]; |
| 143 | + const patternShape = patternData.shape; |
| 144 | + const patternHeight = patternShape.length; |
| 145 | + const patternWidth = patternShape[0].length; |
| 146 | + |
| 147 | + if (sizeValue < (patternData.minBoardSize || 0)) { |
| 148 | + alert( |
| 149 | + `このパターンには ${patternData.minBoardSize}x${patternData.minBoardSize} 以上の盤面が必要です`, |
| 150 | + ); |
| 151 | + return; |
| 152 | + } |
| 153 | + // パターンがボードの中央に来るよう、パターンの左上のセルの位置(startRow, startCol)を調整 |
| 154 | + const startRow = Math.floor((sizeValue - patternHeight) / 2); |
| 155 | + const startCol = Math.floor((sizeValue - patternWidth) / 2); |
| 156 | + |
| 157 | + for (let r = 0; r < patternHeight; r++) { |
| 158 | + for (let c = 0; c < patternWidth; c++) { |
| 159 | + const boardRow = startRow + r; |
| 160 | + const boardCol = startCol + c; |
| 161 | + newBoard[boardRow][boardCol] = patternShape[r][c] === 1; |
| 162 | + } |
| 163 | + } |
146 | 164 | bottomDrawerOpen = false; |
| 165 | + sendEvent("placetemplate", newBoard); |
147 | 166 | }} |
148 | 167 | > |
149 | 168 | <img |
|
245 | 264 | 第 {generationFigure} 世代 |
246 | 265 | </div> |
247 | 266 |
|
248 | | - <p class="ml-10 text-black">ボードのサイズ(10~100):</p> |
249 | | - <input type="number" bind:value={sizeInputValue} class="w-10 text-black bg-white ml-2" /> |
| 267 | + <button |
| 268 | + class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] text-black ml-20" |
| 269 | + onclick={() => { |
| 270 | + intervalMs = intervalMs * 2; |
| 271 | + sendEvent("timer_change", intervalMs); |
| 272 | + }} |
| 273 | + > |
| 274 | + <img class="size-6" src={icons.decelerate} alt="decelerate" /> |
| 275 | + </button> |
250 | 276 |
|
251 | 277 | <button |
252 | | - class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black ml-2" |
| 278 | + class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] text-black ml-2" |
253 | 279 | onclick={() => { |
254 | | - isProgress = false; |
255 | | - if (isNaN(sizeInputValue) || sizeInputValue < 10 || sizeInputValue > 100) { |
256 | | - alert("サイズは10から100の間で指定してください。"); |
257 | | - return; |
258 | | - } |
259 | | - sendEvent("sizechange", sizeInputValue.toString()); |
| 280 | + intervalMs = 1000; |
| 281 | + sendEvent("timer_change", intervalMs); |
| 282 | + }} |
| 283 | + > |
| 284 | + x1 |
| 285 | + </button> |
| 286 | + |
| 287 | + <button |
| 288 | + class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] text-black ml-2" |
| 289 | + onclick={() => { |
| 290 | + intervalMs = intervalMs / 2; |
| 291 | + sendEvent("timer_change", intervalMs); |
260 | 292 | }} |
261 | 293 | > |
262 | | - Change |
| 294 | + <img class="size-6" src={icons.accelerate} alt="accelerate" /> |
263 | 295 | </button> |
264 | 296 |
|
| 297 | + <div class="font-bold text-black ml-5"> |
| 298 | + 現在の速度: x{1000 / intervalMs} |
| 299 | + </div> |
| 300 | + |
265 | 301 | <div |
266 | 302 | class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] swap fixed left-1/2 !-translate-x-1/2 -ml-15 bottom-1" |
267 | 303 | > |
|
287 | 323 | <img class="size-6" src={icons.RightArrow} alt="Right Arrow" /> |
288 | 324 | </div> |
289 | 325 |
|
290 | | - <button |
291 | | - class="btn btn-ghost hover:bg-[rgb(220,220,220)] ml-50 text-black" |
292 | | - onclick={() => { |
293 | | - isProgress = false; |
294 | | - sendEvent("boardreset"); |
295 | | - }} |
296 | | - > |
297 | | - Reset |
298 | | - </button> |
| 326 | + <div class="font-bold text-black absolute right-143">Board:</div> |
299 | 327 |
|
300 | 328 | <button |
301 | | - class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black" |
302 | | - onclick={() => { |
303 | | - isProgress = false; |
304 | | - sendEvent("boardrandom"); |
305 | | - }} |
306 | | - > |
307 | | - Random |
308 | | - </button> |
309 | | - |
310 | | - <button |
311 | | - class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black" |
| 329 | + class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black fixed right-125 bottom-1" |
312 | 330 | onclick={() => { |
313 | 331 | isProgress = false; |
314 | 332 | sendEvent("save_board"); |
|
318 | 336 | </button> |
319 | 337 |
|
320 | 338 | <button |
321 | | - class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black" |
| 339 | + class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black fixed right-109 bottom-1" |
322 | 340 | onclick={() => { |
323 | 341 | isProgress = false; |
324 | 342 | sendEvent("pause"); |
|
329 | 347 | </button> |
330 | 348 |
|
331 | 349 | <button |
332 | | - class="btn btn-ghost hover:bg-[rgb(220,220,220)] ml-5 text-black" |
333 | | - onclick={() => { |
334 | | - appliedCode = editingcode; |
335 | | - }} |
336 | | - > |
337 | | - Apply Code |
338 | | - </button> |
339 | | - <button |
340 | | - class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] text-black ml-2" |
| 350 | + class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black fixed right-92 bottom-1" |
341 | 351 | onclick={() => { |
342 | | - intervalMs = intervalMs / 2; |
343 | | - sendEvent("timer_change", intervalMs); |
| 352 | + isProgress = false; |
| 353 | + sendEvent("boardreset"); |
344 | 354 | }} |
345 | 355 | > |
346 | | - x2 |
| 356 | + Reset |
347 | 357 | </button> |
348 | 358 |
|
349 | 359 | <button |
350 | | - class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] text-black ml-2" |
| 360 | + class="btn btn-ghost hover:bg-[rgb(220,220,220)] text-black fixed right-70 bottom-1" |
351 | 361 | onclick={() => { |
352 | | - intervalMs = intervalMs * 2; |
353 | | - sendEvent("timer_change", intervalMs); |
| 362 | + isProgress = false; |
| 363 | + sendEvent("boardrandom"); |
354 | 364 | }} |
355 | 365 | > |
356 | | - x0.5 |
| 366 | + Random |
357 | 367 | </button> |
358 | 368 |
|
359 | 369 | <button |
360 | | - class="btn btn-ghost btn-circle hover:bg-[rgb(220,220,220)] text-black ml-2" |
| 370 | + class="btn btn-ghost hover:bg-[rgb(220,220,220)] ml-5 text-black fixed right-20 bottom-1" |
361 | 371 | onclick={() => { |
362 | | - intervalMs = 1000; |
363 | | - sendEvent("timer_change", intervalMs); |
| 372 | + appliedCode = editingcode; |
364 | 373 | }} |
365 | 374 | > |
366 | | - Reset Timer |
| 375 | + Apply Code |
367 | 376 | </button> |
368 | 377 | </div> |
0 commit comments