@drmxrcy/tcg-lorcana 0.0.0-202602060544

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +160 -0
  2. package/package.json +45 -0
  3. package/src/__tests__/integration/move-enumeration.test.ts +256 -0
  4. package/src/__tests__/rules/section-01-concepts.test.ts +426 -0
  5. package/src/__tests__/rules/section-03-gameplay.test.ts +298 -0
  6. package/src/__tests__/rules/section-04-turn-structure.test.ts +708 -0
  7. package/src/__tests__/rules/section-05-cards.test.ts +158 -0
  8. package/src/__tests__/rules/section-06-card-types.test.ts +342 -0
  9. package/src/__tests__/rules/section-07-abilities.test.ts +333 -0
  10. package/src/__tests__/rules/section-08-zones.test.ts +231 -0
  11. package/src/__tests__/rules/section-09-damage.test.ts +148 -0
  12. package/src/__tests__/rules/section-10-keywords.test.ts +469 -0
  13. package/src/__tests__/spec-01-foundation-types.test.ts +534 -0
  14. package/src/__tests__/spec-02-zones-card-states.test.ts +295 -0
  15. package/src/card-utils.ts +302 -0
  16. package/src/cards/README.md +296 -0
  17. package/src/cards/abilities/index.ts +175 -0
  18. package/src/cards/index.ts +10 -0
  19. package/src/deck-validation.ts +175 -0
  20. package/src/engine/lorcana-engine.ts +625 -0
  21. package/src/game-definition/__tests__/core-zone-integration.test.ts +553 -0
  22. package/src/game-definition/__tests__/zone-operations.test.ts +362 -0
  23. package/src/game-definition/__tests__/zones.test.ts +176 -0
  24. package/src/game-definition/definition.ts +45 -0
  25. package/src/game-definition/flow/turn-flow.ts +216 -0
  26. package/src/game-definition/index.ts +31 -0
  27. package/src/game-definition/moves/abilities/activate-ability.ts +51 -0
  28. package/src/game-definition/moves/core/__tests__/move-parameter-enumeration.test.ts +316 -0
  29. package/src/game-definition/moves/core/challenge.test.ts +545 -0
  30. package/src/game-definition/moves/core/challenge.ts +81 -0
  31. package/src/game-definition/moves/core/play-card.ts +83 -0
  32. package/src/game-definition/moves/core/quest.test.ts +448 -0
  33. package/src/game-definition/moves/core/quest.ts +49 -0
  34. package/src/game-definition/moves/debug/manual-exert.ts +36 -0
  35. package/src/game-definition/moves/effects/resolve-bag.ts +35 -0
  36. package/src/game-definition/moves/effects/resolve-effect.ts +34 -0
  37. package/src/game-definition/moves/index.ts +85 -0
  38. package/src/game-definition/moves/locations/move-character-to-location.ts +42 -0
  39. package/src/game-definition/moves/resources/put-card-into-inkwell.test.ts +462 -0
  40. package/src/game-definition/moves/resources/put-card-into-inkwell.ts +51 -0
  41. package/src/game-definition/moves/setup/alter-hand.test.ts +395 -0
  42. package/src/game-definition/moves/setup/alter-hand.ts +210 -0
  43. package/src/game-definition/moves/setup/choose-first-player.test.ts +450 -0
  44. package/src/game-definition/moves/setup/choose-first-player.ts +105 -0
  45. package/src/game-definition/moves/setup/draw-cards.ts +37 -0
  46. package/src/game-definition/moves/songs/sing-together.ts +47 -0
  47. package/src/game-definition/moves/songs/sing.ts +56 -0
  48. package/src/game-definition/moves/standard/concede.test.ts +189 -0
  49. package/src/game-definition/moves/standard/concede.ts +72 -0
  50. package/src/game-definition/moves/standard/pass-turn.ts +49 -0
  51. package/src/game-definition/setup/game-setup.ts +19 -0
  52. package/src/game-definition/trackers/tracker-config.ts +23 -0
  53. package/src/game-definition/win-conditions/lore-victory.ts +26 -0
  54. package/src/game-definition/zone-operations.ts +405 -0
  55. package/src/game-definition/zones/zone-configs.ts +59 -0
  56. package/src/game-definition/zones.ts +283 -0
  57. package/src/index.ts +189 -0
  58. package/src/operations/index.ts +7 -0
  59. package/src/operations/lorcana-operations.ts +288 -0
  60. package/src/queries/README.md +56 -0
  61. package/src/resolvers/__tests__/condition-resolver.test.ts +301 -0
  62. package/src/resolvers/condition-registry.ts +70 -0
  63. package/src/resolvers/condition-resolver.ts +85 -0
  64. package/src/resolvers/conditions/basic.ts +81 -0
  65. package/src/resolvers/conditions/card-state.ts +12 -0
  66. package/src/resolvers/conditions/comparison.ts +102 -0
  67. package/src/resolvers/conditions/existence.ts +219 -0
  68. package/src/resolvers/conditions/history.ts +68 -0
  69. package/src/resolvers/conditions/index.ts +15 -0
  70. package/src/resolvers/conditions/logical.ts +55 -0
  71. package/src/resolvers/conditions/resolution.ts +41 -0
  72. package/src/resolvers/conditions/revealed.ts +42 -0
  73. package/src/resolvers/conditions/zone.ts +84 -0
  74. package/src/setup.test.ts +18 -0
  75. package/src/targeting/__tests__/filter-resolver.test.ts +294 -0
  76. package/src/targeting/__tests__/real-cards-targeting.test.ts +303 -0
  77. package/src/targeting/__tests__/targeting-dsl.test.ts +386 -0
  78. package/src/targeting/enum-expansion.ts +387 -0
  79. package/src/targeting/filter-registry.ts +322 -0
  80. package/src/targeting/filter-resolver.ts +145 -0
  81. package/src/targeting/index.ts +91 -0
  82. package/src/targeting/lorcana-target-dsl.ts +495 -0
  83. package/src/targeting/targeting-ui.ts +407 -0
  84. package/src/testing/index.ts +14 -0
  85. package/src/testing/lorcana-test-engine.ts +813 -0
  86. package/src/types/README.md +303 -0
  87. package/src/types/__tests__/lorcana-state.test.ts +168 -0
  88. package/src/types/__tests__/move-enumeration.test.ts +179 -0
  89. package/src/types/branded-types.ts +106 -0
  90. package/src/types/game-state.ts +184 -0
  91. package/src/types/index.ts +87 -0
  92. package/src/types/keywords.ts +187 -0
  93. package/src/types/lorcana-state.ts +260 -0
  94. package/src/types/move-enumeration.ts +126 -0
  95. package/src/types/move-params.ts +216 -0
  96. package/src/validators/index.ts +7 -0
  97. package/src/validators/move-validators.ts +374 -0
  98. package/src/zones/card-state.ts +234 -0
  99. package/src/zones/index.ts +42 -0
  100. package/src/zones/zone-config.ts +150 -0
@@ -0,0 +1,145 @@
1
+ import type { CardInstance, CardRegistry } from "@drmxrcy/tcg-core";
2
+ import type { LorcanaCardDefinition } from "@drmxrcy/tcg-lorcana-types";
3
+ import type { LorcanaCardMeta, LorcanaGameState } from "../types/game-state";
4
+ import { filterRegistry, registerDefaultFilters } from "./filter-registry";
5
+ import type { LorcanaContext, LorcanaFilter } from "./lorcana-target-dsl";
6
+
7
+ // Initialize registry
8
+ registerDefaultFilters();
9
+
10
+ /**
11
+ * Check if a card matches a Lorcana-specific filter using the registry
12
+ */
13
+ export function matchesLorcanaFilter(
14
+ card: CardInstance<LorcanaCardMeta>,
15
+ filter: LorcanaFilter,
16
+ state: LorcanaGameState,
17
+ registry: CardRegistry<LorcanaCardDefinition>,
18
+ context?: LorcanaContext,
19
+ ): boolean {
20
+ const handler = filterRegistry.get(filter.type);
21
+ if (!handler) {
22
+ console.warn(`No handler found for filter type: ${filter.type}`);
23
+ return false;
24
+ }
25
+
26
+ return handler.evaluate(filter, card, { state, registry, context });
27
+ }
28
+
29
+ /**
30
+ * Sort filters by rank using registry complexity
31
+ */
32
+ export function sortFilters(filters: LorcanaFilter[]): LorcanaFilter[] {
33
+ return [...filters].sort((a, b) => {
34
+ const handlerA = filterRegistry.get(a.type);
35
+ const handlerB = filterRegistry.get(b.type);
36
+ const rankA = handlerA ? handlerA.complexity : 100;
37
+ const rankB = handlerB ? handlerB.complexity : 100;
38
+ return rankA - rankB;
39
+ });
40
+ }
41
+
42
+ /**
43
+ * Creates a predicate function that checks if a card matches all filters
44
+ */
45
+ export function createTargetFiltersPredicate(
46
+ filters: LorcanaFilter[] | undefined,
47
+ state: LorcanaGameState,
48
+ registry: CardRegistry<LorcanaCardDefinition>,
49
+ context?: LorcanaContext,
50
+ ): (card: CardInstance<LorcanaCardMeta>) => boolean {
51
+ if (!filters || filters.length === 0) {
52
+ return () => true;
53
+ }
54
+
55
+ const sortedFilters = sortFilters(filters);
56
+
57
+ return (card: CardInstance<LorcanaCardMeta>) => {
58
+ return sortedFilters.every((filter) =>
59
+ matchesLorcanaFilter(card, filter, state, registry, context),
60
+ );
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Debug info for filter evaluation
66
+ */
67
+ export interface FilterDebugInfo {
68
+ filter: LorcanaFilter;
69
+ passed: boolean;
70
+ executionTime: number;
71
+ }
72
+
73
+ /**
74
+ * Create a predicate with debug capabilities
75
+ */
76
+ export function createTargetFiltersPredicateWithDebug(
77
+ filters: LorcanaFilter[] | undefined,
78
+ state: LorcanaGameState,
79
+ registry: CardRegistry<LorcanaCardDefinition>,
80
+ context?: LorcanaContext,
81
+ ): {
82
+ predicate: (card: CardInstance<LorcanaCardMeta>) => boolean;
83
+ debug: (card: CardInstance<LorcanaCardMeta>) => {
84
+ result: boolean;
85
+ details: FilterDebugInfo[];
86
+ };
87
+ } {
88
+ const rawPredicate = createTargetFiltersPredicate(
89
+ filters,
90
+ state,
91
+ registry,
92
+ context,
93
+ );
94
+ const sortedFilters = filters ? sortFilters(filters) : [];
95
+
96
+ const debug = (card: CardInstance<LorcanaCardMeta>) => {
97
+ const details: FilterDebugInfo[] = [];
98
+ let result = true;
99
+
100
+ for (const filter of sortedFilters) {
101
+ const start = performance.now();
102
+ const passed = matchesLorcanaFilter(
103
+ card,
104
+ filter,
105
+ state,
106
+ registry,
107
+ context,
108
+ );
109
+ const duration = performance.now() - start;
110
+
111
+ details.push({
112
+ filter,
113
+ passed,
114
+ executionTime: duration,
115
+ });
116
+
117
+ if (!passed) {
118
+ result = false;
119
+ break;
120
+ }
121
+ }
122
+
123
+ return { result, details };
124
+ };
125
+
126
+ return { predicate: rawPredicate, debug };
127
+ }
128
+
129
+ /**
130
+ * Validate filters configuration
131
+ */
132
+ export function validateFilters(filters: LorcanaFilter[]): {
133
+ valid: boolean;
134
+ errors: string[];
135
+ } {
136
+ const errors: string[] = [];
137
+ for (const f of filters) {
138
+ const handler = filterRegistry.get(f.type);
139
+ if (!handler) {
140
+ errors.push(`Unknown filter type: ${f.type}`);
141
+ }
142
+ // TODO: Add specific handler validation if needed
143
+ }
144
+ return { valid: errors.length === 0, errors };
145
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Lorcana Targeting Module
3
+ *
4
+ * Provides Lorcana-specific targeting DSL and utilities.
5
+ *
6
+ * @module targeting
7
+ */
8
+
9
+ // Re-export core types for convenience
10
+ export type {
11
+ BaseContext,
12
+ OwnerScope,
13
+ PlayerTargetDSL,
14
+ SelectorScope,
15
+ TargetCount,
16
+ TargetDSL,
17
+ TargetingUIHint,
18
+ } from "@drmxrcy/tcg-core";
19
+
20
+ // Enum expansion utilities
21
+ export {
22
+ ALL_TARGET_ENUMS,
23
+ CHARACTER_TARGET_ENUMS,
24
+ expandCharacterTarget,
25
+ expandItemTarget,
26
+ expandLocationTarget,
27
+ expandTarget,
28
+ ITEM_TARGET_ENUMS,
29
+ isCharacterEnum,
30
+ isItemEnum,
31
+ isLocationEnum,
32
+ LOCATION_TARGET_ENUMS,
33
+ } from "./enum-expansion";
34
+ export {
35
+ type FilterHandler,
36
+ FilterRegistry,
37
+ filterRegistry,
38
+ registerDefaultFilters,
39
+ } from "./filter-registry";
40
+ // Filter matching logic
41
+ export {
42
+ createTargetFiltersPredicate,
43
+ createTargetFiltersPredicateWithDebug,
44
+ type FilterDebugInfo,
45
+ matchesLorcanaFilter,
46
+ sortFilters,
47
+ validateFilters,
48
+ } from "./filter-resolver";
49
+ // Lorcana Target DSL types
50
+ export {
51
+ type AtLocationFilter,
52
+ type CharacterTarget,
53
+ type CharacterTargetEnum,
54
+ type CostFilter,
55
+ type DamagedFilter,
56
+ type DryFilter,
57
+ type ExertedFilter,
58
+ type HasClassificationFilter,
59
+ type HasKeywordFilter,
60
+ type InkableFilter,
61
+ type ItemTarget,
62
+ type ItemTargetEnum,
63
+ isDSLTarget,
64
+ isNumericFilter,
65
+ isStateFilter,
66
+ type LocationTarget,
67
+ type LocationTargetEnum,
68
+ type LorcanaCardTarget,
69
+ type LorcanaCardType,
70
+ type LorcanaCharacterTarget,
71
+ type LorcanaContext,
72
+ type LorcanaFilter,
73
+ type LorcanaItemTarget,
74
+ type LorcanaLocationTarget,
75
+ type LorcanaPlayerTarget,
76
+ type LorcanaTarget,
77
+ type LoreValueFilter,
78
+ type MoveCostFilter,
79
+ type NameFilter,
80
+ type ReadyFilter,
81
+ type StrengthFilter,
82
+ type UndamagedFilter,
83
+ type WillpowerFilter,
84
+ } from "./lorcana-target-dsl";
85
+
86
+ // UI utilities
87
+ export {
88
+ generateTargetDescription,
89
+ getTargetUIHints,
90
+ type LorcanaTargetUIHint,
91
+ } from "./targeting-ui";