From 06c801e6ae790aa7c9345c0a94d7d89c198d545e Mon Sep 17 00:00:00 2001 From: hypercross Date: Thu, 2 Apr 2026 16:39:08 +0800 Subject: [PATCH] refactor: improve tic tac toe with region entity --- src/core/region.ts | 10 +++++++--- src/index.ts | 2 +- src/samples/tic-tac-toe.ts | 16 +++++----------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/core/region.ts b/src/core/region.ts index 5ecd0e0..6951c9b 100644 --- a/src/core/region.ts +++ b/src/core/region.ts @@ -1,4 +1,4 @@ -import {computed, ReadonlySignal, SignalOptions} from "@preact/signals-core"; +import {batch, computed, ReadonlySignal, SignalOptions} from "@preact/signals-core"; import {Entity} from "@/utils/entity"; import {Part} from "./part"; import {RNG} from "@/utils/rng"; @@ -33,7 +33,9 @@ export class RegionEntity extends Entity { } export function applyAlign(region: Entity) { - region.produce(applyAlignCore); + batch(() => { + region.produce(applyAlignCore); + }); } function applyAlignCore(region: Region) { @@ -91,7 +93,9 @@ function applyAlignCore(region: Region) { } export function shuffle(region: Entity, rng: RNG) { - region.produce(region => shuffleCore(region, rng)); + batch(() => { + region.produce(region => shuffleCore(region, rng)); + }); } function shuffleCore(region: Region, rng: RNG){ diff --git a/src/index.ts b/src/index.ts index 7c3b226..e9095e4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ export type { Part } from './core/part'; export { flip, flipTo, roll } from './core/part'; export type { Region, RegionAxis } from './core/region'; -export { applyAlign, shuffle } from './core/region'; +export { applyAlign, shuffle, RegionEntity } from './core/region'; // Utils export type { Command, CommandSchema, CommandParamSchema, CommandOptionSchema, CommandFlagSchema } from './utils/command'; diff --git a/src/samples/tic-tac-toe.ts b/src/samples/tic-tac-toe.ts index a74b4c3..817eb74 100644 --- a/src/samples/tic-tac-toe.ts +++ b/src/samples/tic-tac-toe.ts @@ -1,4 +1,4 @@ -import {createGameCommandRegistry, Part, Entity, entity, Region} from '@/index'; +import {createGameCommandRegistry, Part, Entity, entity, RegionEntity} from '@/index'; const BOARD_SIZE = 3; const MAX_TURNS = BOARD_SIZE * BOARD_SIZE; @@ -20,7 +20,7 @@ type TicTacToePart = Part & { player: PlayerType }; export function createInitialState() { return { - board: entity('board', { + board: new RegionEntity('board', { id: 'board', axes: [ { name: 'x', min: 0, max: BOARD_SIZE - 1 }, @@ -89,15 +89,9 @@ function isValidMove(row: number, col: number): boolean { return !isNaN(row) && !isNaN(col) && row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE; } -export function getBoardRegion(host: Entity) { - return host.value.board; -} - export function isCellOccupied(host: Entity, row: number, col: number): boolean { - const board = getBoardRegion(host); - return board.value.children.some( - part => part.value.position[0] === row && part.value.position[1] === col - ); + const board = host.value.board; + return board.partsMap.value[`${row},${col}`] !== undefined; } export function hasWinningLine(positions: number[][]): boolean { @@ -122,7 +116,7 @@ export function checkWinner(host: Entity): WinnerType { } export function placePiece(host: Entity, row: number, col: number, player: PlayerType) { - const board = getBoardRegion(host); + const board = host.value.board; const moveNumber = host.value.parts.length + 1; const piece: TicTacToePart = { id: `piece-${player}-${moveNumber}`,