/* global React, Btn, Coin, TicketIcon, useGame, fmt, useState, useEffect, useRef, scf, scfIdem */ const CHIPS = [1, 2, 5, 10]; const pipMap = { 1: [4], 2: [0, 8], 3: [0, 4, 8], 4: [0, 2, 6, 8], 5: [0, 2, 4, 6, 8], 6: [0, 2, 3, 5, 6, 8], }; function Die({ v, rolling, reveal }) { return React.createElement("div", { className: "die" + (rolling ? " roll" : "") + (reveal ? " reveal" : "") }, Array.from({ length: 9 }).map((_, i) => React.createElement("div", { key: i, style: { display: "flex", alignItems: "center", justifyContent: "center" } }, pipMap[v] && pipMap[v].includes(i) ? React.createElement("div", { className: "pip" }) : null))); } function MoneyScreen({ onResult }) { const g = useGame(); const [chip, setChip] = useState(1); const [dice, setDice] = useState([2, 5, 1]); const [rolling, setRolling] = useState(false); const [revealed, setRevealed] = useState(false); const [winNums, setWinNums] = useState([]); const [bets, setBets] = useState({ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 }); const [ticketPrice, setTicketPrice] = useState(500); const [betCap, setBetCap] = useState(100000); const [busy, setBusy] = useState(false); const timer = useRef(null); const placed = Object.values(bets).reduce((a, b) => a + b, 0); useEffect(() => { (async () => { try { const d = await scf("money/info"); setTicketPrice(Number(d.ticketPrice || 500)); setBetCap(Number(d.betCapPerNum || 100000)); } catch (e) { } })(); g.refreshWallet(); return () => { if (timer.current) clearInterval(timer.current); }; }, []); const bet = (n) => { if (rolling) return; if ((bets[n] + chip) * ticketPrice > betCap) { g.showToast("單個數字下注超出上限"); return; } if (placed + chip > g.tickets) { g.showToast("車票不足,請先購買車票"); return; } setBets(b => ({ ...b, [n]: b[n] + chip })); setWinNums([]); }; const clearBets = () => { if (rolling) return; setBets({ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 }); }; const buyTicket = async () => { if (busy) return; setBusy(true); try { await scf("money/ticket/buy", { ticketCount: 10, idemKey: scfIdem() }); await g.refreshWallet(); g.showToast("已購買 10 張車票"); } catch (e) { g.showToast("✗ " + e.message); } finally { setBusy(false); } }; const play = async () => { if (rolling) return; if (placed === 0) { g.showToast("請先選擇數字下注"); return; } setRolling(true); setWinNums([]); setRevealed(false); if (timer.current) clearInterval(timer.current); timer.current = setInterval(() => setDice([1 + (Math.random() * 6 | 0), 1 + (Math.random() * 6 | 0), 1 + (Math.random() * 6 | 0)]), 90); try { const arr = []; for (let n = 1; n <= 6; n++) if (bets[n] > 0) arr.push({ num: n, amount: bets[n] }); const d = await scf("money/play", { bets: arr, idemKey: scfIdem() }); await new Promise(r => setTimeout(r, 700)); clearInterval(timer.current); const final = d.dice || dice; setDice(final); setRevealed(true); const wins = (d.results || []).filter(x => Number(x.payout) > 0).map(x => x.num); setWinNums(wins); await g.refreshWallet(); if (onResult) onResult({ dice: final, plate: d.plate, payout: Number(d.totalPayout || 0), wins }); setBets({ 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 }); } catch (e) { clearInterval(timer.current); g.showToast("✗ " + e.message); } finally { setRolling(false); } }; return React.createElement("div", { className: "fade-in", style: { padding: "12px 14px 8px" } }, React.createElement("div", { className: "panel", style: { padding: "18px 0", marginBottom: 14 } }, React.createElement("div", { className: "dice-row" }, dice.map((d, i) => React.createElement(Die, { key: i, v: d, rolling, reveal: revealed }))), React.createElement("div", { style: { textAlign: "center", marginTop: 12, fontSize: 12, color: "var(--txt-dim)" } }, rolling ? "開獎中…" : React.createElement(React.Fragment, null, "車牌號 ", React.createElement("b", { className: "gold-text disp", style: { fontSize: 17 } }, dice.join(" · "))))), React.createElement("div", { className: "betgrid" }, [1, 2, 3, 4, 5, 6].map(n => React.createElement("div", { key: n, className: "betcell" + (bets[n] > 0 ? " on" : "") + (winNums.includes(n) ? " win" : ""), onClick: () => bet(n) }, React.createElement("span", { className: "bc-odd" }, "×2"), React.createElement("div", { className: "bc-num" }, n), React.createElement("div", { className: "bc-tag disp upper" }, "車牌號"), React.createElement("div", { className: "bc-amt" }, bets[n] > 0 ? bets[n] + " 票" : "0")))), React.createElement("div", { style: { display: "flex", gap: 7, marginTop: 13, alignItems: "center" } }, React.createElement("span", { style: { fontSize: 11, color: "var(--txt-mute)", flex: "none" } }, "投註(票)"), CHIPS.map(c => React.createElement("button", { key: c, onClick: () => setChip(c), className: "subtab" + (c === chip ? " on" : ""), style: { flex: 1, padding: "7px 0", fontSize: 13 } }, c)), React.createElement("button", { onClick: clearBets, className: "subtab", style: { flex: "none", padding: "7px 10px", fontSize: 12, color: "var(--red-hi)" } }, "清空")), React.createElement("div", { style: { textAlign: "center", fontSize: 11, color: "var(--txt-mute)", margin: "12px 0", letterSpacing: ".02em" } }, "購買車票 › 選投註額 › 點選數字 › 點擊開車"), React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "0 2px 12px" } }, React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--gold-100)" } }, React.createElement(TicketIcon, { s: 20 }), "車票 ", React.createElement("b", { className: "disp", style: { fontSize: 15 } }, fmt(g.tickets))), React.createElement("div", { style: { fontSize: 11, color: "var(--txt-mute)" } }, "已下注 " + placed + " 票")), React.createElement("div", { style: { display: "flex", gap: 10 } }, React.createElement(Btn, { kind: "ghost", size: "lg", onClick: buyTicket, disabled: busy, style: { flex: 1 } }, "車票購買"), React.createElement(Btn, { kind: "red", size: "lg", onClick: play, disabled: rolling, style: { flex: 1.3 } }, rolling ? "開獎中…" : "開 車")), React.createElement("div", { style: { fontSize: 11, color: "var(--txt-mute)", lineHeight: 1.7, padding: "12px 2px 0", textWrap: "pretty" } }, "單人即時開獎:本人買票、下注、開車即時結算。命中 1 次 ×2、同數字 2 次 ×4.1、3 次 ×6.2;單數字上限 " + fmt(betCap) + " 金幣。") ); } Object.assign(window, { MoneyScreen });