From 0a2c7562132b91008ce1e263daebd5c91d05777c Mon Sep 17 00:00:00 2001 From: hypercross Date: Thu, 26 Feb 2026 09:08:05 +0800 Subject: [PATCH] refactor: format --- src/components/dice.tsx | 92 ++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/components/dice.tsx b/src/components/dice.tsx index 30ae0ce..87974de 100644 --- a/src/components/dice.tsx +++ b/src/components/dice.tsx @@ -1,5 +1,5 @@ -import { customElement, noShadowDOM } from 'solid-element'; -import { createSignal, onMount } from 'solid-js'; +import { customElement, noShadowDOM } from "solid-element"; +import { createSignal, onMount } from "solid-js"; interface RollResult { total: number; @@ -7,11 +7,6 @@ interface RollResult { detail: string; } -interface DiceOperator { - pattern: RegExp; - handler: (match: RegExpMatchArray, rolls: number[]) => { value: number; rolls: number[]; detail: string }; -} - function rollDice(formula: string): RollResult { const allRolls: number[] = []; let total = 0; @@ -19,22 +14,25 @@ function rollDice(formula: string): RollResult { // 解析骰子公式,支持 + 和 - 运算符 // 先按 + 和 - 分割,但保留运算符 - const tokens = formula.split(/([+-])/).map(t => t.trim()).filter(t => t.length > 0); - + const tokens = formula + .split(/([+-])/) + .map((t) => t.trim()) + .filter((t) => t.length > 0); + let sign = 1; - + for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; - - if (token === '+') { + + if (token === "+") { sign = 1; continue; } - if (token === '-') { + if (token === "-") { sign = -1; continue; } - + // 处理 kh/kl/dh/dl 运算符 let processedToken = token; let keepHigh = false; @@ -43,12 +41,12 @@ function rollDice(formula: string): RollResult { let dropLow = false; let keepCount = 0; let dropCount = 0; - + const khMatch = token.match(/^(.+?)kh(\d+)$/i); const klMatch = token.match(/^(.+?)kl(\d+)$/i); const dhMatch = token.match(/^(.+?)dh(\d+)$/i); const dlMatch = token.match(/^(.+?)dl(\d+)$/i); - + if (khMatch) { processedToken = khMatch[1]; keepHigh = true; @@ -66,24 +64,24 @@ function rollDice(formula: string): RollResult { dropLow = true; dropCount = parseInt(dlMatch[2]); } - + const match = processedToken.match(/^(\d+)?d(\d+)$/i); if (match) { - const count = parseInt(match[1] || '1'); + const count = parseInt(match[1] || "1"); const sides = parseInt(match[2]); const rolls: number[] = []; - + for (let j = 0; j < count; j++) { rolls.push(Math.floor(Math.random() * sides) + 1); } - + let processedRolls = [...rolls]; let detail = `${count}d${sides}`; - + // 处理 keep/drop 运算符 if (keepHigh || keepLow || dropHigh || dropLow) { const sorted = [...processedRolls].sort((a, b) => a - b); - + if (dropHigh && dropCount > 0) { processedRolls = sorted.slice(0, sorted.length - dropCount); detail += `d${dropCount}h`; @@ -98,17 +96,19 @@ function rollDice(formula: string): RollResult { detail += `kl${keepCount}`; } } - + const partTotal = processedRolls.reduce((a, b) => a + b, 0); total += sign * partTotal; allRolls.push(...processedRolls); - details.push(`${detail}=[${processedRolls.join(',')}]${sign < 0 ? ' (负)' : ''}`); + details.push( + `${detail}=[${processedRolls.join(",")}]${sign < 0 ? " (负)" : ""}`, + ); } else { // 处理固定数字 const num = parseInt(token); if (!isNaN(num)) { total += sign * num; - details.push(`${num}${sign < 0 ? ' (负)' : ''}`); + details.push(`${num}${sign < 0 ? " (负)" : ""}`); } } } @@ -116,36 +116,32 @@ function rollDice(formula: string): RollResult { return { total, rolls: allRolls, - detail: details.join(' + ') + detail: details.join(" + "), }; } -// 生成唯一 ID -let diceCounter = 0; -function generateDiceId(): string { - return `dice-${Date.now()}-${diceCounter++}`; -} - // 从 URL 参数获取骰子结果 function getDiceResultFromUrl(key: string): number | null { - if (typeof window === 'undefined') return null; + if (typeof window === "undefined") return null; const params = new URLSearchParams(window.location.search); const value = params.get(`dice-${key}`); return value ? parseInt(value) : null; } -customElement('md-dice', { key: '' }, (props, { element }) => { +// TODO:使用history.pushState +function setDiceResultToUrl(key: string, value: number) {} + +customElement("md-dice", { key: "" }, (props, { element }) => { noShadowDOM(); const [result, setResult] = createSignal(null); const [isRolled, setIsRolled] = createSignal(false); - const [rollDetail, setRollDetail] = createSignal(''); - const [diceId] = createSignal(generateDiceId()); - + const [rollDetail, setRollDetail] = createSignal(""); + // 从 element 的 textContent 获取骰子公式 - const formula = element?.textContent?.trim() || ''; - + const formula = element?.textContent?.trim() || ""; + // 使用的 key(如果没有提供则使用生成的 ID) - const effectiveKey = () => props.key || diceId(); + const effectiveKey = () => props.key; onMount(() => { // 初始化时检查 URL 参数 @@ -164,13 +160,15 @@ customElement('md-dice', { key: '' }, (props, { element }) => { setResult(rollResult.total); setRollDetail(rollResult.detail); setIsRolled(true); + // TODO:保存结果到url }; const handleTextClick = () => { // 点击文本:总是重置为公式 setResult(null); setIsRolled(false); - setRollDetail(''); + setRollDetail(""); + // TODO:从url中移除结果 }; const displayText = () => (isRolled() ? `${result()}` : formula); @@ -178,24 +176,26 @@ customElement('md-dice', { key: '' }, (props, { element }) => { return ( { e.preventDefault(); handleRoll(); }} class="text-blue-600 hover:text-blue-800 cursor-pointer" - title={rollDetail() || '掷骰子'} + title={rollDetail() || "掷骰子"} > 🎲 {displayText()} ); }); -