From 1e94f8232bb67028a1018fac3d00ce33da120b36 Mon Sep 17 00:00:00 2001 From: coelacanth657 <210202793+coelacanth657@users.noreply.github.com> Date: Sat, 15 Nov 2025 19:39:14 +0900 Subject: [PATCH 1/3] =?UTF-8?q?number[][]=E9=96=A2=E9=80=A3=E3=81=AE?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/iframe/life-game.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/iframe/life-game.js b/src/iframe/life-game.js index ba97e7d..71a8b5c 100644 --- a/src/iframe/life-game.js +++ b/src/iframe/life-game.js @@ -3,7 +3,7 @@ let timer = "stop"; let generationFigure = 0; let isDragging = false; -let dragMode = false; // true: 黒にする, false: 白にする +let dragMode = 0; // 1: 黒にする, 0: 白にする let isPlacingTemplate = false; let patternShape = []; let patternHeight = 0; @@ -70,7 +70,7 @@ function renderBoard() { for (let c = 0; c < patternWidth; c++) { const boardRow = i + r; const boardCol = j + c; - board[boardRow][boardCol] = patternShape[r][c] === 1; + board[boardRow][boardCol] = patternShape[r][c]; } } rerender(); @@ -239,7 +239,7 @@ on.pause = () => { on.board_reset = () => { //すべて白にBoardを変更 - board = Array.from({ length: boardSize }, () => Array.from({ length: boardSize }, () => false)); + board = Array.from({ length: boardSize }, () => Array.from({ length: boardSize }, () => 0)); renderBoard(); generationChange(0); }; @@ -247,7 +247,7 @@ on.board_reset = () => { on.board_randomize = () => { //白黒ランダムにBoardを変更 board = Array.from({ length: boardSize }, () => - Array.from({ length: boardSize }, () => Math.random() > 0.5), + Array.from({ length: boardSize }, () => (Math.random() > 0.5 ? 1 : 0)), ); renderBoard(); generationChange(0); From cd49cc8a71967471acc67db1fe44e8f768450ab6 Mon Sep 17 00:00:00 2001 From: coelacanth657 <210202793+coelacanth657@users.noreply.github.com> Date: Sat, 15 Nov 2025 19:58:14 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E7=9B=A4=E9=9D=A2=E3=81=A8=E5=85=B1?= =?UTF-8?q?=E3=81=AB=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E4=BF=9D=E5=AD=98?= =?UTF-8?q?/=E8=AA=AD=E8=BE=BC=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migration.sql | 10 +++++ .../migration.sql | 8 ++++ .../migration.sql | 14 +++++++ prisma/schema.prisma | 3 +- src/lib/api/board.ts | 14 +++++-- src/lib/models/BoardManager.svelte.ts | 37 ++++++++++++++++--- src/routes/+page.svelte | 10 +++-- src/routes/api/board/+server.ts | 10 +++-- 8 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 prisma/migrations/20251115084446_add_is_edited_and_code_data_column/migration.sql create mode 100644 prisma/migrations/20251115104313_delete_is_edited_column/migration.sql create mode 100644 prisma/migrations/20251115105024_rename_columns/migration.sql diff --git a/prisma/migrations/20251115084446_add_is_edited_and_code_data_column/migration.sql b/prisma/migrations/20251115084446_add_is_edited_and_code_data_column/migration.sql new file mode 100644 index 0000000..64be531 --- /dev/null +++ b/prisma/migrations/20251115084446_add_is_edited_and_code_data_column/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - Added the required column `codeData` to the `Board` table without a default value. This is not possible if the table is not empty. + - Added the required column `isEdited` to the `Board` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Board" ADD COLUMN "codeData" JSONB NOT NULL, +ADD COLUMN "isEdited" BOOLEAN NOT NULL; diff --git a/prisma/migrations/20251115104313_delete_is_edited_column/migration.sql b/prisma/migrations/20251115104313_delete_is_edited_column/migration.sql new file mode 100644 index 0000000..c2c8d3d --- /dev/null +++ b/prisma/migrations/20251115104313_delete_is_edited_column/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - You are about to drop the column `isEdited` on the `Board` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Board" DROP COLUMN "isEdited"; diff --git a/prisma/migrations/20251115105024_rename_columns/migration.sql b/prisma/migrations/20251115105024_rename_columns/migration.sql new file mode 100644 index 0000000..ca9bf31 --- /dev/null +++ b/prisma/migrations/20251115105024_rename_columns/migration.sql @@ -0,0 +1,14 @@ +/* + Warnings: + + - You are about to drop the column `codeData` on the `Board` table. All the data in the column will be lost. + - You are about to drop the column `data` on the `Board` table. All the data in the column will be lost. + - Added the required column `board` to the `Board` table without a default value. This is not possible if the table is not empty. + - Added the required column `code` to the `Board` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Board" DROP COLUMN "codeData", +DROP COLUMN "data", +ADD COLUMN "board" JSONB NOT NULL, +ADD COLUMN "code" JSONB NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index fc26eee..e93858e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -18,9 +18,10 @@ datasource db { model Board { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) - data Json + board Json name String preview Json + code Json } model Code { diff --git a/src/lib/api/board.ts b/src/lib/api/board.ts index bf474eb..bbe477c 100644 --- a/src/lib/api/board.ts +++ b/src/lib/api/board.ts @@ -1,6 +1,9 @@ import { toast } from "$lib/models/ToastStore.svelte"; -export async function saveBoard(data: { board: number[][]; name: string }, isJapanese: boolean) { +export async function saveBoard( + data: { board: number[][]; name: string; code: string }, + isJapanese: boolean, +) { try { const response = await fetch("/api/board", { method: "POST", @@ -61,10 +64,15 @@ export async function fetchBoardList(isJapanese: boolean): Promise { +): Promise { try { const response = await fetch(`/api/board?id=${id}`); @@ -78,7 +86,7 @@ export async function loadBoardById( const loadedBoard = await response.json(); - return loadedBoard as number[][]; + return loadedBoard as LoadedBoardData; } catch (err) { console.error("Load error", err); if (isJapanese) { diff --git a/src/lib/models/BoardManager.svelte.ts b/src/lib/models/BoardManager.svelte.ts index 316feba..f608637 100644 --- a/src/lib/models/BoardManager.svelte.ts +++ b/src/lib/models/BoardManager.svelte.ts @@ -1,9 +1,21 @@ import { createBoardPreview } from "$lib/board-preview"; -import { saveBoard, fetchBoardList, loadBoardById, type BoardListItem } from "$lib/api/board"; +import { + saveBoard, + fetchBoardList, + loadBoardById, + type BoardListItem, + type LoadedBoardData, +} from "$lib/api/board"; type SaveState = | { saving: false } - | { saving: true; data: number[][]; name: string; preview: number[][] }; + | { + saving: true; + board: number[][]; + name: string; + preview: number[][]; + code: string; + }; type LoadState = | { state: "closed" } @@ -16,9 +28,15 @@ export class BoardManager { constructor() {} - openSaveModal(board: number[][]) { + openSaveModal(board: number[][], code: string) { const preview = createBoardPreview(board); - this.saveState = { saving: true, data: board, name: "", preview: preview }; + this.saveState = { + saving: true, + board: board, + name: "", + preview: preview, + code: code, + }; } closeSaveModal() { @@ -28,7 +46,14 @@ export class BoardManager { async save(isJapanese: boolean) { if (!this.saveState.saving) return; const name = this.saveState.name.trim() === "" ? "Unnamed Board" : this.saveState.name.trim(); - await saveBoard({ board: this.saveState.data, name }, isJapanese); + await saveBoard( + { + board: this.saveState.board, + name: name, + code: this.saveState.code, + }, + isJapanese, + ); this.closeSaveModal(); } @@ -46,7 +71,7 @@ export class BoardManager { this.loadState = { state: "closed" }; } - async load(id: number, isJapanese: boolean): Promise { + async load(id: number, isJapanese: boolean): Promise { this.closeLoadModal(); return await loadBoardById(id, isJapanese); } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 00ffdd9..14fdc08 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -88,7 +88,7 @@ break; } case "save_board": { - boardManager.openSaveModal(event.data.data as number[][]); + boardManager.openSaveModal(event.data.data as number[][], appliedCode as string); break; } default: { @@ -110,9 +110,11 @@ } async function onBoardSelect(id: number) { - const board = await boardManager.load(id, isJapanese); - if (board) { - sendEvent("apply_board", board); + const data = await boardManager.load(id, isJapanese); + if (data) { + editingCode = data.code; + appliedCode = data.code; + sendEvent("apply_board", data.board); } } diff --git a/src/routes/api/board/+server.ts b/src/routes/api/board/+server.ts index ca696a2..6176f5e 100644 --- a/src/routes/api/board/+server.ts +++ b/src/routes/api/board/+server.ts @@ -6,6 +6,7 @@ import * as v from "valibot"; const BoardSchema = v.object({ board: v.array(v.array(v.number())), name: v.pipe(v.string(), v.minLength(1, "盤面名は必須です。")), + code: v.string(), }); export async function POST({ request }) { @@ -23,14 +24,15 @@ export async function POST({ request }) { return json({ message: "無効なリクエストデータです。" }, { status: 400 }); } - const { board, name } = result.output; + const { board, name, code } = result.output; const preview = createBoardPreview(board); const newState = await prisma.board.create({ data: { - data: board, + board: board, name: name, preview: preview, + code: code, }, }); @@ -49,14 +51,14 @@ export async function GET({ url }) { const state = await prisma.board.findUnique({ where: { id: id }, - select: { data: true }, + select: { board: true, code: true }, }); if (!state) { return json({ message: `ID: ${id} の盤面は見つかりません。` }, { status: 404 }); } - return json(state.data); + return json(state); } else { //IDが指定されなかった場合、全ての盤面のリストを返す const allStates = await prisma.board.findMany({ From 2c4ecca794b760144af2190b6d631bc895964bc7 Mon Sep 17 00:00:00 2001 From: coelacanth657 <210202793+coelacanth657@users.noreply.github.com> Date: Sat, 15 Nov 2025 21:03:06 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E7=9B=A4=E9=9D=A2=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=83=89=E6=99=82=E3=81=AB=E3=82=B3=E3=83=BC=E3=83=89=E3=82=82?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=95=E3=82=8C=E3=82=8B=E3=81=93=E3=81=A8?= =?UTF-8?q?=E3=82=92=E8=AD=A6=E5=91=8A=E3=81=99=E3=82=8B=E6=A9=9F=E8=83=BD?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/components/BoardModals.svelte | 39 ++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/lib/components/BoardModals.svelte b/src/lib/components/BoardModals.svelte index 17841a8..791271e 100644 --- a/src/lib/components/BoardModals.svelte +++ b/src/lib/components/BoardModals.svelte @@ -10,6 +10,22 @@ isJapanese: boolean; onSelect: (id: number) => void; } = $props(); + + let showConfirmation = $state(false); + let selectedBoardId = $state(null); + + function handleLoadClick(id: number) { + selectedBoardId = id; + showConfirmation = true; + } + + function handleConfirmLoad() { + if (selectedBoardId !== null) { + onSelect(selectedBoardId); + } + showConfirmation = false; + selectedBoardId = null; + } @@ -105,7 +121,7 @@ @@ -125,6 +141,27 @@ + + + +