import type { TrayItem, CarColor } from "./types"; import { GameConfig } from "../GameConfig"; /** * 篮子匹配引擎 * 同类聚合插入 + 3 消检测 */ export class MatchEngine { /** * 将物品插入篮子(同类聚合:新物品插到最后一个同色物品旁边) */ static insertToTray( item: TrayItem, tray: TrayItem[], ): { newTray: TrayItem[]; insertIndex: number } { const newTray = [...tray]; // 寻找最后一个同色物品的位置 let lastSameColorIndex = -1; for (let i = newTray.length - 1; i >= 0; i--) { if (newTray[i].color === item.color) { lastSameColorIndex = i; break; } } let insertIndex: number; if (lastSameColorIndex >= 0) { insertIndex = lastSameColorIndex + 1; newTray.splice(insertIndex, 0, item); } else { insertIndex = newTray.length; newTray.push(item); } return { newTray, insertIndex }; } /** * 检测篮子中是否有 3 个同色物品 * @returns 匹配的物品列表(空数组表示无匹配) */ static checkMatch(tray: TrayItem[]): TrayItem[] { const colorCount = new Map(); for (const item of tray) { const list = colorCount.get(item.color) || []; list.push(item); colorCount.set(item.color, list); } for (const [, items] of colorCount) { if (items.length >= GameConfig.MATCH_COUNT) { return items.slice(0, GameConfig.MATCH_COUNT); } } return []; } /** * 从篮子中移除匹配的物品 */ static removeFromTray(tray: TrayItem[], matchedIds: string[]): TrayItem[] { const idSet = new Set(matchedIds); return tray.filter(item => !idSet.has(item.id)); } /** * 判断篮子是否已满 */ static isTrayFull(tray: TrayItem[], capacity: number): boolean { return tray.length >= capacity; } }