@drmxrcy/tcg-core 0.0.0-202602060542

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 (157) hide show
  1. package/README.md +882 -0
  2. package/package.json +58 -0
  3. package/src/__tests__/alpha-clash-engine-definition.test.ts +319 -0
  4. package/src/__tests__/createMockAlphaClashGame.ts +462 -0
  5. package/src/__tests__/createMockGrandArchiveGame.ts +373 -0
  6. package/src/__tests__/createMockGundamGame.ts +379 -0
  7. package/src/__tests__/createMockLorcanaGame.ts +328 -0
  8. package/src/__tests__/createMockOnePieceGame.ts +429 -0
  9. package/src/__tests__/createMockRiftboundGame.ts +462 -0
  10. package/src/__tests__/grand-archive-engine-definition.test.ts +118 -0
  11. package/src/__tests__/gundam-engine-definition.test.ts +110 -0
  12. package/src/__tests__/integration-complete-game.test.ts +508 -0
  13. package/src/__tests__/integration-network-sync.test.ts +469 -0
  14. package/src/__tests__/lorcana-engine-definition.test.ts +100 -0
  15. package/src/__tests__/move-enumeration.test.ts +725 -0
  16. package/src/__tests__/multiplayer-engine.test.ts +555 -0
  17. package/src/__tests__/one-piece-engine-definition.test.ts +114 -0
  18. package/src/__tests__/riftbound-engine-definition.test.ts +124 -0
  19. package/src/actions/action-definition.test.ts +201 -0
  20. package/src/actions/action-definition.ts +122 -0
  21. package/src/actions/action-timing.test.ts +490 -0
  22. package/src/actions/action-timing.ts +257 -0
  23. package/src/cards/card-definition.test.ts +268 -0
  24. package/src/cards/card-definition.ts +27 -0
  25. package/src/cards/card-instance.test.ts +422 -0
  26. package/src/cards/card-instance.ts +49 -0
  27. package/src/cards/computed-properties.test.ts +530 -0
  28. package/src/cards/computed-properties.ts +84 -0
  29. package/src/cards/conditional-modifiers.test.ts +390 -0
  30. package/src/cards/modifiers.test.ts +286 -0
  31. package/src/cards/modifiers.ts +51 -0
  32. package/src/engine/MULTIPLAYER.md +425 -0
  33. package/src/engine/__tests__/rule-engine-flow.test.ts +348 -0
  34. package/src/engine/__tests__/rule-engine-history.test.ts +535 -0
  35. package/src/engine/__tests__/rule-engine-moves.test.ts +488 -0
  36. package/src/engine/__tests__/rule-engine.test.ts +366 -0
  37. package/src/engine/index.ts +14 -0
  38. package/src/engine/multiplayer-engine.example.ts +571 -0
  39. package/src/engine/multiplayer-engine.ts +409 -0
  40. package/src/engine/rule-engine.test.ts +286 -0
  41. package/src/engine/rule-engine.ts +1539 -0
  42. package/src/engine/tracker-system.ts +172 -0
  43. package/src/examples/__tests__/coin-flip-game.test.ts +641 -0
  44. package/src/filtering/card-filter.test.ts +230 -0
  45. package/src/filtering/card-filter.ts +91 -0
  46. package/src/filtering/card-query.test.ts +901 -0
  47. package/src/filtering/card-query.ts +273 -0
  48. package/src/filtering/filter-matching.test.ts +944 -0
  49. package/src/filtering/filter-matching.ts +315 -0
  50. package/src/flow/SERIALIZATION.md +428 -0
  51. package/src/flow/__tests__/flow-definition.test.ts +427 -0
  52. package/src/flow/__tests__/flow-manager.test.ts +756 -0
  53. package/src/flow/__tests__/flow-serialization.test.ts +565 -0
  54. package/src/flow/flow-definition.ts +453 -0
  55. package/src/flow/flow-manager.ts +1044 -0
  56. package/src/flow/index.ts +35 -0
  57. package/src/game-definition/__tests__/game-definition-validation.test.ts +359 -0
  58. package/src/game-definition/__tests__/game-definition.test.ts +291 -0
  59. package/src/game-definition/__tests__/move-definitions.test.ts +328 -0
  60. package/src/game-definition/game-definition.ts +261 -0
  61. package/src/game-definition/index.ts +28 -0
  62. package/src/game-definition/move-definitions.ts +188 -0
  63. package/src/game-definition/validation.ts +183 -0
  64. package/src/history/history-manager.test.ts +497 -0
  65. package/src/history/history-manager.ts +312 -0
  66. package/src/history/history-operations.ts +122 -0
  67. package/src/history/index.ts +9 -0
  68. package/src/history/types.ts +255 -0
  69. package/src/index.ts +32 -0
  70. package/src/logging/index.ts +27 -0
  71. package/src/logging/log-formatter.ts +187 -0
  72. package/src/logging/logger.ts +276 -0
  73. package/src/logging/types.ts +148 -0
  74. package/src/moves/create-move.test.ts +331 -0
  75. package/src/moves/create-move.ts +64 -0
  76. package/src/moves/move-enumeration.ts +228 -0
  77. package/src/moves/move-executor.test.ts +431 -0
  78. package/src/moves/move-executor.ts +195 -0
  79. package/src/moves/move-system.test.ts +380 -0
  80. package/src/moves/move-system.ts +463 -0
  81. package/src/moves/standard-moves.ts +231 -0
  82. package/src/operations/card-operations.test.ts +236 -0
  83. package/src/operations/card-operations.ts +116 -0
  84. package/src/operations/card-registry-impl.test.ts +251 -0
  85. package/src/operations/card-registry-impl.ts +70 -0
  86. package/src/operations/card-registry.test.ts +234 -0
  87. package/src/operations/card-registry.ts +106 -0
  88. package/src/operations/counter-operations.ts +152 -0
  89. package/src/operations/game-operations.test.ts +280 -0
  90. package/src/operations/game-operations.ts +140 -0
  91. package/src/operations/index.ts +24 -0
  92. package/src/operations/operations-impl.test.ts +354 -0
  93. package/src/operations/operations-impl.ts +468 -0
  94. package/src/operations/zone-operations.test.ts +295 -0
  95. package/src/operations/zone-operations.ts +223 -0
  96. package/src/rng/seeded-rng.test.ts +339 -0
  97. package/src/rng/seeded-rng.ts +123 -0
  98. package/src/targeting/index.ts +48 -0
  99. package/src/targeting/target-definition.test.ts +273 -0
  100. package/src/targeting/target-definition.ts +37 -0
  101. package/src/targeting/target-dsl.ts +279 -0
  102. package/src/targeting/target-resolver.ts +486 -0
  103. package/src/targeting/target-validation.test.ts +994 -0
  104. package/src/targeting/target-validation.ts +286 -0
  105. package/src/telemetry/events.ts +202 -0
  106. package/src/telemetry/index.ts +21 -0
  107. package/src/telemetry/telemetry-manager.ts +127 -0
  108. package/src/telemetry/types.ts +68 -0
  109. package/src/testing/__tests__/testing-utilities-integration.test.ts +161 -0
  110. package/src/testing/index.ts +88 -0
  111. package/src/testing/test-assertions.test.ts +341 -0
  112. package/src/testing/test-assertions.ts +256 -0
  113. package/src/testing/test-card-factory.test.ts +228 -0
  114. package/src/testing/test-card-factory.ts +111 -0
  115. package/src/testing/test-context-factory.ts +187 -0
  116. package/src/testing/test-end-assertions.test.ts +262 -0
  117. package/src/testing/test-end-assertions.ts +95 -0
  118. package/src/testing/test-engine-builder.test.ts +389 -0
  119. package/src/testing/test-engine-builder.ts +46 -0
  120. package/src/testing/test-flow-assertions.test.ts +284 -0
  121. package/src/testing/test-flow-assertions.ts +115 -0
  122. package/src/testing/test-player-builder.test.ts +132 -0
  123. package/src/testing/test-player-builder.ts +46 -0
  124. package/src/testing/test-replay-assertions.test.ts +356 -0
  125. package/src/testing/test-replay-assertions.ts +164 -0
  126. package/src/testing/test-rng-helpers.test.ts +260 -0
  127. package/src/testing/test-rng-helpers.ts +190 -0
  128. package/src/testing/test-state-builder.test.ts +373 -0
  129. package/src/testing/test-state-builder.ts +99 -0
  130. package/src/testing/test-zone-factory.test.ts +295 -0
  131. package/src/testing/test-zone-factory.ts +224 -0
  132. package/src/types/branded-utils.ts +54 -0
  133. package/src/types/branded.test.ts +175 -0
  134. package/src/types/branded.ts +33 -0
  135. package/src/types/index.ts +8 -0
  136. package/src/types/state.test.ts +198 -0
  137. package/src/types/state.ts +154 -0
  138. package/src/validation/card-type-guards.test.ts +242 -0
  139. package/src/validation/card-type-guards.ts +179 -0
  140. package/src/validation/index.ts +40 -0
  141. package/src/validation/schema-builders.test.ts +403 -0
  142. package/src/validation/schema-builders.ts +345 -0
  143. package/src/validation/type-guard-builder.test.ts +216 -0
  144. package/src/validation/type-guard-builder.ts +109 -0
  145. package/src/validation/validator-builder.test.ts +375 -0
  146. package/src/validation/validator-builder.ts +273 -0
  147. package/src/zones/index.ts +28 -0
  148. package/src/zones/zone-factory.test.ts +183 -0
  149. package/src/zones/zone-factory.ts +44 -0
  150. package/src/zones/zone-operations.test.ts +800 -0
  151. package/src/zones/zone-operations.ts +306 -0
  152. package/src/zones/zone-state-helpers.test.ts +337 -0
  153. package/src/zones/zone-state-helpers.ts +128 -0
  154. package/src/zones/zone-visibility.test.ts +156 -0
  155. package/src/zones/zone-visibility.ts +36 -0
  156. package/src/zones/zone.test.ts +186 -0
  157. package/src/zones/zone.ts +66 -0
@@ -0,0 +1,183 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import { createCardId, createPlayerId, createZoneId } from "../types";
3
+ import type { CardZoneConfig } from "./zone";
4
+ import { createZone } from "./zone-factory";
5
+
6
+ describe("Zone Factory", () => {
7
+ describe("createZone", () => {
8
+ it("should create a zone with valid configuration", () => {
9
+ const config: CardZoneConfig = {
10
+ id: createZoneId("deck"),
11
+ name: "Deck",
12
+ visibility: "secret",
13
+ ordered: true,
14
+ faceDown: true,
15
+ };
16
+
17
+ const zone = createZone(config);
18
+
19
+ expect(zone.config).toEqual(config);
20
+ expect(zone.cards).toBeInstanceOf(Array);
21
+ expect(zone.cards).toHaveLength(0);
22
+ });
23
+
24
+ it("should create a zone with initial cards", () => {
25
+ const config: CardZoneConfig = {
26
+ id: createZoneId("hand"),
27
+ name: "Hand",
28
+ visibility: "private",
29
+ ordered: false,
30
+ };
31
+
32
+ const initialCards = [createCardId("card-1"), createCardId("card-2")];
33
+ const zone = createZone(config, initialCards);
34
+
35
+ expect(zone.cards).toEqual(initialCards);
36
+ expect(zone.cards).toHaveLength(2);
37
+ });
38
+
39
+ it("should create zone with minimal configuration", () => {
40
+ const config: CardZoneConfig = {
41
+ id: createZoneId("play"),
42
+ name: "Play Area",
43
+ visibility: "public",
44
+ ordered: false,
45
+ };
46
+
47
+ const zone = createZone(config);
48
+
49
+ expect(zone.config.id).toBe(config.id);
50
+ expect(zone.config.name).toBe(config.name);
51
+ expect(zone.config.visibility).toBe("public");
52
+ expect(zone.config.owner).toBeUndefined();
53
+ expect(zone.config.maxSize).toBeUndefined();
54
+ expect(zone.cards).toHaveLength(0);
55
+ });
56
+
57
+ it("should validate maxSize when provided", () => {
58
+ const config: CardZoneConfig = {
59
+ id: createZoneId("hand"),
60
+ name: "Hand",
61
+ visibility: "private",
62
+ ordered: false,
63
+ maxSize: 7,
64
+ };
65
+
66
+ const zone = createZone(config);
67
+ expect(zone.config.maxSize).toBe(7);
68
+ });
69
+
70
+ it("should throw error if initial cards exceed maxSize", () => {
71
+ const config: CardZoneConfig = {
72
+ id: createZoneId("hand"),
73
+ name: "Hand",
74
+ visibility: "private",
75
+ ordered: false,
76
+ maxSize: 2,
77
+ };
78
+
79
+ const tooManyCards = [
80
+ createCardId("card-1"),
81
+ createCardId("card-2"),
82
+ createCardId("card-3"),
83
+ ];
84
+
85
+ expect(() => createZone(config, tooManyCards)).toThrow(
86
+ "Cannot create zone: initial cards (3) exceed maxSize (2)",
87
+ );
88
+ });
89
+
90
+ it("should create ordered zone (deck)", () => {
91
+ const config: CardZoneConfig = {
92
+ id: createZoneId("deck"),
93
+ name: "Deck",
94
+ visibility: "secret",
95
+ ordered: true,
96
+ faceDown: true,
97
+ };
98
+
99
+ const zone = createZone(config);
100
+
101
+ expect(zone.config.ordered).toBe(true);
102
+ expect(zone.config.faceDown).toBe(true);
103
+ });
104
+
105
+ it("should create unordered zone (play area)", () => {
106
+ const config: CardZoneConfig = {
107
+ id: createZoneId("play"),
108
+ name: "Play Area",
109
+ visibility: "public",
110
+ ordered: false,
111
+ };
112
+
113
+ const zone = createZone(config);
114
+
115
+ expect(zone.config.ordered).toBe(false);
116
+ });
117
+
118
+ it("should create zone with owner", () => {
119
+ const playerId = createPlayerId("player-1");
120
+ const config: CardZoneConfig = {
121
+ id: createZoneId("hand"),
122
+ name: "Hand",
123
+ visibility: "private",
124
+ ordered: false,
125
+ owner: playerId,
126
+ };
127
+
128
+ const zone = createZone(config);
129
+
130
+ expect(zone.config.owner).toBe(playerId);
131
+ });
132
+
133
+ it("should create shared zone without owner", () => {
134
+ const config: CardZoneConfig = {
135
+ id: createZoneId("graveyard"),
136
+ name: "Graveyard",
137
+ visibility: "public",
138
+ ordered: true,
139
+ };
140
+
141
+ const zone = createZone(config);
142
+
143
+ expect(zone.config.owner).toBeUndefined();
144
+ });
145
+
146
+ it("should validate zone id is provided", () => {
147
+ const invalidConfig = {
148
+ name: "Test Zone",
149
+ visibility: "public",
150
+ ordered: false,
151
+ } as CardZoneConfig;
152
+
153
+ expect(() => createZone(invalidConfig)).toThrow(
154
+ "Zone configuration must include an id",
155
+ );
156
+ });
157
+
158
+ it("should validate zone name is provided", () => {
159
+ const invalidConfig = {
160
+ id: createZoneId("test"),
161
+ visibility: "public",
162
+ ordered: false,
163
+ } as CardZoneConfig;
164
+
165
+ expect(() => createZone(invalidConfig)).toThrow(
166
+ "Zone configuration must include a name",
167
+ );
168
+ });
169
+
170
+ it("should validate visibility is valid", () => {
171
+ const invalidConfig = {
172
+ id: createZoneId("test"),
173
+ name: "Test Zone",
174
+ visibility: "invalid",
175
+ ordered: false,
176
+ } as unknown as CardZoneConfig;
177
+
178
+ expect(() => createZone(invalidConfig)).toThrow(
179
+ 'Invalid visibility: must be "public", "private", or "secret"',
180
+ );
181
+ });
182
+ });
183
+ });
@@ -0,0 +1,44 @@
1
+ import type { CardId } from "../types";
2
+ import type { CardZoneConfig, Zone, ZoneVisibility } from "./zone";
3
+
4
+ const VALID_VISIBILITIES: ZoneVisibility[] = ["public", "private", "secret"];
5
+
6
+ /**
7
+ * Creates a new zone with the given configuration
8
+ * @param config - Zone configuration
9
+ * @param initialCards - Optional initial cards for the zone
10
+ * @returns A new Zone instance
11
+ * @throws Error if configuration is invalid or initial cards exceed maxSize
12
+ */
13
+ export function createZone(
14
+ config: CardZoneConfig,
15
+ initialCards: CardId[] = [],
16
+ ): Zone {
17
+ // Validate required fields
18
+ if (!config.id) {
19
+ throw new Error("Zone configuration must include an id");
20
+ }
21
+
22
+ if (!config.name) {
23
+ throw new Error("Zone configuration must include a name");
24
+ }
25
+
26
+ // Validate visibility
27
+ if (!VALID_VISIBILITIES.includes(config.visibility)) {
28
+ throw new Error(
29
+ 'Invalid visibility: must be "public", "private", or "secret"',
30
+ );
31
+ }
32
+
33
+ // Validate maxSize constraint
34
+ if (config.maxSize !== undefined && initialCards.length > config.maxSize) {
35
+ throw new Error(
36
+ `Cannot create zone: initial cards (${initialCards.length}) exceed maxSize (${config.maxSize})`,
37
+ );
38
+ }
39
+
40
+ return {
41
+ config,
42
+ cards: [...initialCards],
43
+ };
44
+ }