CardQuery
提供卡牌集合的查询、分组、统计与排序工具函数。
概述
CardQuery 模块位于 src/combination/CardQuery.ts,是 combination 系统中的纯函数式工具集。它不持有状态,所有函数都不修改入参数组,对卡牌的解析统一委托给 RankResolver,默认使用 StandardPokerRankResolver。
这些工具被 CombinationDetector 内部使用,也对外暴露供规则与插件复用。
接口
CardQuery
卡牌查询条件。所有字段均为可选;传入的字段以「且」关系参与匹配。rank 支持数字与字符串两种形式,比较时进行弱类型转换。
ts
interface CardQuery {
rank?: number | string
suit?: string
type?: string
tags?: string[]
}字段
| 字段 | 类型 | 说明 |
|---|---|---|
rank | number | string | 待匹配的点数。数字与字符串形式等价(5 与 '5' 视为相同) |
suit | string | 待匹配的花色 |
type | string | 待匹配的卡牌类型字符串 |
tags | string[] | 待匹配的标签列表,需全部包含才算匹配(且关系) |
函数
findCards()
在卡牌集合中筛选出满足查询条件的卡牌。
ts
function findCards(cards: readonly Card[], query: CardQuery): Card[]参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
cards | readonly Card[] | 是 | — | 待筛选的卡牌集合(不会被修改) |
query | CardQuery | 是 | — | 查询条件 |
返回值
Card[]:新的卡牌数组,包含所有匹配项。原数组不被修改。
行为
- 各字段以「且」关系组合;任一字段不匹配则该卡牌不入选。
rank比较在类型不一致时通过String(...)归一化,保证rank: '5'与rank: 5等价。tags为数组时,需全部包含于卡牌的tags中才算匹配。
示例
ts
import { findCards } from '../combination/CardQuery.js'
import type { Card } from '../card/Card.js'
const cards: Card[] = [
{ id: 'c1', type: 'standard', suit: 'spade', rank: 'A', data: {} },
{ id: 'c2', type: 'standard', suit: 'heart', rank: '5', data: {} },
{ id: 'c3', type: 'standard', suit: 'spade', rank: '5', data: {} }
]
findCards(cards, { rank: 5 })
// -> [c2, c3]
findCards(cards, { suit: 'spade' })
// -> [c1, c3]
findCards(cards, { rank: '5', suit: 'spade' })
// -> [c3]groupByRank()
按点数将卡牌分组。
ts
function groupByRank(
cards: readonly Card[],
resolver?: RankResolver
): Map<number, Card[]>参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
cards | readonly Card[] | 是 | — | 待分组的卡牌集合 |
resolver | RankResolver | 否 | new StandardPokerRankResolver() | 点数解析器 |
返回值
Map<number, Card[]>:点数 -> 该点数下的卡牌数组。
示例
ts
import { groupByRank } from '../combination/CardQuery.js'
const groups = groupByRank(cards)
// Map { 14 => [cardA], 5 => [card2, card3] }groupBySuit()
按花色将卡牌分组。卡牌缺省花色时归入占位键 '_'。
ts
function groupBySuit(cards: readonly Card[]): Map<string, Card[]>参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
cards | readonly Card[] | 是 | — | 待分组的卡牌集合 |
返回值
Map<string, Card[]>:花色 -> 该花色下的卡牌数组。无花色卡牌归入键 '_'。
示例
ts
import { groupBySuit } from '../combination/CardQuery.js'
groupBySuit(cards)
// Map { 'spade' => [c1, c3], 'heart' => [c2] }countByRank()
统计每个点数在卡牌集合中出现的次数。
ts
function countByRank(
cards: readonly Card[],
resolver?: RankResolver
): Map<number, number>参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
cards | readonly Card[] | 是 | — | 待统计的卡牌集合 |
resolver | RankResolver | 否 | new StandardPokerRankResolver() | 点数解析器 |
返回值
Map<number, number>:点数 -> 出现次数。
示例
ts
import { countByRank } from '../combination/CardQuery.js'
countByRank(cards)
// Map { 14 => 1, 5 => 2 }countBySuit()
统计每个花色在卡牌集合中出现的次数。
ts
function countBySuit(cards: readonly Card[]): Map<string, number>参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
cards | readonly Card[] | 是 | — | 待统计的卡牌集合 |
返回值
Map<string, number>:花色 -> 出现次数。
sortByRank()
按点数升序排序卡牌,返回新数组,不修改入参。
ts
function sortByRank(
cards: readonly Card[],
resolver?: RankResolver
): Card[]参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
cards | readonly Card[] | 是 | — | 待排序的卡牌集合 |
resolver | RankResolver | 否 | new StandardPokerRankResolver() | 点数解析器 |
返回值
Card[]:排序后的新卡牌数组。原数组不被修改。
示例
ts
import { sortByRank } from '../combination/CardQuery.js'
sortByRank([{ id: 'k', rank: 'K', data: {} }, { id: 'a', rank: 'A', data: {} }])
// -> [cardA(rank=14), cardK(rank=13)] —— A 视为 14 排在 K 之后注意事项
- 所有函数均为纯函数:不会修改入参数组,需要返回数组时返回新数组。
- 默认
RankResolver为StandardPokerRankResolver(A 视为 14);如需将 A 视为 1,请显式传入LowAceRankResolver。 rank字段的弱类型比较仅用于findCards;分组与排序函数均通过resolver.resolveRank归一化为数字。