/** * slot_machine.aigameplay — reducer 接口模板 * * Agent 生成实际 reducer 时,必须导出以下函数。 * 此文件是接口约束模板,不是可执行代码。 * * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ * ⚠️ 重要:渲染层(GameScene)不应直接调用 dispatch() * * dispatch() 是一体化接口,内部执行完整的旋转+结算逻辑后只返回最终状态, * 中间过程(各转轮停止时机、中奖连线高亮、奖励特效)全部丢失。 * * 渲染层需要分步驱动转轮停止动画和结算特效,因此必须使用下方「分步函数」。 * * dispatch() 的用途:无头测试、AI 模拟、快速验证赔率计算。 * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */ // ─── 配置类型 ───────────────────────────────────────────────────────────────── export type SlotSymbolDef = { type: string; /** 3连同符号的赔率倍数(payout = bet × multiplier) */ multiplier: number; /** 是否为通配符(Wild,可替代任意非 Scatter 符号) */ isWild: boolean; /** 是否为散布符号(Scatter,不受连线限制) */ isScatter: boolean; }; export type Payline = { /** 连线唯一 ID */ id: number; /** 连线名称(如 'middle_row') */ name: string; /** 各转轮对应的行索引(rows[reelIdx] = rowIdx) */ rows: number[]; }; export type SlotMachineConfig = { /** 转轮数量,默认 3 */ reelCount: number; /** 每轮可见符号行数,默认 3 */ symbolsPerReel: number; /** 连线定义 */ paylines: Payline[]; /** 符号定义表 */ symbolDefs: SlotSymbolDef[]; /** 各转轮的符号池(决定随机概率)*/ reelSymbolPools: string[][]; /** Scatter 触发所需最少数量,默认 3 */ scatterMinCount: number; /** Scatter 奖励倍率表 { count: multiplier }(如 {3: 5, 4: 20, 5: 100}) */ scatterMultipliers: Record; /** 初始余额 */ initialBalance: number; /** 默认下注金额 */ defaultBet: number; }; // ─── 动作类型 ───────────────────────────────────────────────────────────────── export type SlotMachineAction = | { type: 'spin' } | { type: 'set_bet'; amount: number } | { type: 'reset' }; // ─── 状态类型 ───────────────────────────────────────────────────────────────── export type SlotMachineState = { /** 各转轮当前显示的符号矩阵:reels[reelIdx][rowIdx] */ reels: string[][]; /** 当前下注金额 */ currentBet: number; /** 玩家余额 */ balance: number; /** 最近一次 spin 的结果快照 */ lastSpinResult: SpinResult | null; /** 游戏是否结束(余额耗尽且无法下注) */ gameOver: boolean; /** 总旋转次数 */ totalSpins: number; }; /** spin() 返回值:本次旋转的原始结果 */ export type SpinResult = { /** 各转轮停止后的符号矩阵 */ reels: string[][]; /** 本次旋转扣除的下注金额 */ betAmount: number; }; /** evaluatePaylines 返回的单条连线命中结果 */ export type PaylineMatch = { /** 命中的连线 ID */ paylineId: number; /** 连线名称 */ paylineName: string; /** 匹配的符号(Wild 替换后的实际符号) */ symbol: string; /** 连续匹配数量 */ count: number; /** 是否使用了 Wild 替换 */ wildUsed: boolean; /** 该连线的奖励金额(bet × symbol.multiplier) */ payout: number; }; /** checkScatter 返回值 */ export type ScatterCheckResult = { /** Scatter 符号在所有转轮中的总数量 */ count: number; /** 是否达到触发条件(count >= scatterMinCount) */ triggered: boolean; /** 散布奖励金额(bet × scatterMultipliers[count]) */ bonus: number; /** Scatter 符号的位置列表 */ positions: Array<{ reelIdx: number; rowIdx: number }>; }; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 必须导出的函数 // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // ─── 初始化 ────────────────────────────────────────────────────────────────── /** * init:根据配置初始化游戏状态 */ export declare function init(config: SlotMachineConfig): SlotMachineState; // ─── 一体化接口(测试/AI 模拟用) ─────────────────────────────────────────── /** * dispatch:接收动作,返回新状态(纯函数,不得修改原 state) * - spin:执行完整旋转(扣注、RNG、结算、更新余额)一步到位 * - set_bet:修改下注金额 * - reset:重置到初始状态 * * ⚠️ 仅用于无头测试和 AI 模拟。渲染层请使用下方分步函数。 */ export declare function dispatch(state: SlotMachineState, action: SlotMachineAction): SlotMachineState; /** * getState:返回当前状态快照 */ export declare function getState(state: SlotMachineState): SlotMachineState; // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 分步函数(渲染层/场景层必须使用这些函数驱动动画) // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ /** * spin:执行旋转逻辑(RNG),返回各转轮停止结果,但暂不更新 balance。 * * 场景层在玩家点击 SPIN 按钮后调用: * 1. 调用 spin(state) 获取 SpinResult(同时从 balance 扣除 bet) * 2. 逐个转轮播放滚动→停止动画(每个转轮间隔约500ms) * 3. 全部转轮停止后,调用 evaluatePaylines + calculatePayout + checkScatter * 4. 播放中奖特效,然后更新 balance * * @param state 当前游戏状态(balance >= currentBet 才可执行) * @returns 包含各转轮结果的 SpinResult(balance 已扣除 bet) */ export declare function spin(state: SlotMachineState): { state: SlotMachineState; result: SpinResult }; /** * evaluatePaylines:评估所有连线,检测中奖情况(考虑 Wild 替换)。 * * 场景层在所有转轮停止动画完成后调用。 * * @param result spin() 返回的转轮结果 * @param paylines 连线定义配置 * @param symbols 符号定义表 * @param bet 当前下注金额(用于计算各连线奖励) * @returns 命中的连线列表(含奖励金额) */ export declare function evaluatePaylines( result: SpinResult, paylines: Payline[], symbols: SlotSymbolDef[], bet: number, ): PaylineMatch[]; /** * calculatePayout:汇总所有中奖连线的总奖励金额。 * * @param matches evaluatePaylines() 返回的命中连线列表 * @param bet 当前下注金额(散布奖励也需要 bet 参数,故传入) * @returns 连线总奖励金额(不含 scatter bonus) */ export declare function calculatePayout(matches: PaylineMatch[], bet: number): number; /** * checkScatter:检测散布符号数量是否触发奖励。 * * Scatter 不受连线限制,出现在任意转轮任意行均计入总数。 * * @param result spin() 返回的转轮结果 * @param symbols 符号定义表 * @param bet 当前下注金额 * @param scatterMinCount 触发所需最少 Scatter 数量 * @param scatterMultipliers Scatter 奖励倍率表 * @returns 散布检测结果(是否触发、数量、奖励金额、位置列表) */ export declare function checkScatter( result: SpinResult, symbols: SlotSymbolDef[], bet: number, scatterMinCount: number, scatterMultipliers: Record, ): ScatterCheckResult;