Skip to content

CardQuery ​

提供卡牌集合的查询、分组、统计与排序工具函数。

概述 ​

CardQuery 模块位于 src/combination/CardQuery.ts,是 combination 系统中的纯函数式工具集。它不持有状态,所有函数都不修改入参数组,对卡牌的解析统一委托给 RankResolver,默认使用 StandardPokerRankResolver。

这些工具被 CombinationDetector 内部使用,也对外暴露供规则与插件复用。

接口 ​

CardQuery ​

卡牌查询条件。所有字段均为可选;传入的字段以「且」关系参与匹配。rank 支持数字与字符串两种形式,比较时进行弱类型转换。

ts
interface CardQuery {
  rank?: number | string
  suit?: string
  type?: string
  tags?: string[]
}

字段 ​

字段类型说明
ranknumber | string待匹配的点数。数字与字符串形式等价(5 与 '5' 视为相同)
suitstring待匹配的花色
typestring待匹配的卡牌类型字符串
tagsstring[]待匹配的标签列表,需全部包含才算匹配(且关系)

函数 ​

findCards() ​

在卡牌集合中筛选出满足查询条件的卡牌。

ts
function findCards(cards: readonly Card[], query: CardQuery): Card[]

参数 ​

参数类型必填默认值说明
cardsreadonly Card[]是—待筛选的卡牌集合(不会被修改)
queryCardQuery是—查询条件

返回值 ​

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[]>

参数 ​

参数类型必填默认值说明
cardsreadonly Card[]是—待分组的卡牌集合
resolverRankResolver否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[]>

参数 ​

参数类型必填默认值说明
cardsreadonly 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>

参数 ​

参数类型必填默认值说明
cardsreadonly Card[]是—待统计的卡牌集合
resolverRankResolver否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>

参数 ​

参数类型必填默认值说明
cardsreadonly Card[]是—待统计的卡牌集合

返回值 ​

Map<string, number>:花色 -> 出现次数。

sortByRank() ​

按点数升序排序卡牌,返回新数组,不修改入参。

ts
function sortByRank(
  cards: readonly Card[],
  resolver?: RankResolver
): Card[]

参数 ​

参数类型必填默认值说明
cardsreadonly Card[]是—待排序的卡牌集合
resolverRankResolver否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 归一化为数字。