@hellacardgames/speed 0.5.3 → 0.6.0

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 (39) hide show
  1. package/dist/client/index.cjs.map +1 -1
  2. package/dist/client/index.d.cts +2 -2
  3. package/dist/client/index.d.cts.map +1 -1
  4. package/dist/client/index.d.mts +2 -2
  5. package/dist/client/index.d.mts.map +1 -1
  6. package/dist/client/index.mjs.map +1 -1
  7. package/dist/index-FveApXzq.d.cts +124 -0
  8. package/dist/index-FveApXzq.d.cts.map +1 -0
  9. package/dist/index-J8s2QklC.d.mts +124 -0
  10. package/dist/index-J8s2QklC.d.mts.map +1 -0
  11. package/dist/{index-BilCO_4a.d.cts → index-YAYbNr-s.d.cts} +42 -58
  12. package/dist/index-YAYbNr-s.d.cts.map +1 -0
  13. package/dist/{index-BilCO_4a.d.mts → index-YAYbNr-s.d.mts} +42 -58
  14. package/dist/index-YAYbNr-s.d.mts.map +1 -0
  15. package/dist/manager/index.cjs +2 -12
  16. package/dist/manager/index.d.cts +2 -2
  17. package/dist/manager/index.d.mts +2 -2
  18. package/dist/manager/index.mjs +2 -2
  19. package/dist/manager-BOymBQ4E.mjs +817 -0
  20. package/dist/manager-BOymBQ4E.mjs.map +1 -0
  21. package/dist/manager-BpKvQbcp.cjs +822 -0
  22. package/dist/manager-BpKvQbcp.cjs.map +1 -0
  23. package/dist/server/index.cjs +138 -157
  24. package/dist/server/index.cjs.map +1 -1
  25. package/dist/server/index.d.cts +3 -3
  26. package/dist/server/index.d.mts +3 -3
  27. package/dist/server/index.mjs +138 -157
  28. package/dist/server/index.mjs.map +1 -1
  29. package/package.json +1 -1
  30. package/dist/index-BilCO_4a.d.cts.map +0 -1
  31. package/dist/index-BilCO_4a.d.mts.map +0 -1
  32. package/dist/index-DSPZZlhq.d.cts +0 -143
  33. package/dist/index-DSPZZlhq.d.cts.map +0 -1
  34. package/dist/index-S-oO1z9X.d.mts +0 -143
  35. package/dist/index-S-oO1z9X.d.mts.map +0 -1
  36. package/dist/manager-CPmezdJa.mjs +0 -834
  37. package/dist/manager-CPmezdJa.mjs.map +0 -1
  38. package/dist/manager-DErQ_XUq.cjs +0 -899
  39. package/dist/manager-DErQ_XUq.cjs.map +0 -1
@@ -1,834 +0,0 @@
1
- //#region src/manager/constants.ts
2
- const GAME_KEY = "speed";
3
- const WATCHDOG_INTERVAL_MS = 1e4;
4
- const EXPIRY_EXTENSION_MS = 3e5;
5
- const CAN_PLAY_AT_DELAY_MS = 3e3;
6
- const CARDS = [
7
- {
8
- id: crypto.randomUUID(),
9
- rank: 2,
10
- suite: "clubs"
11
- },
12
- {
13
- id: crypto.randomUUID(),
14
- rank: 3,
15
- suite: "clubs"
16
- },
17
- {
18
- id: crypto.randomUUID(),
19
- rank: 4,
20
- suite: "clubs"
21
- },
22
- {
23
- id: crypto.randomUUID(),
24
- rank: 5,
25
- suite: "clubs"
26
- },
27
- {
28
- id: crypto.randomUUID(),
29
- rank: 6,
30
- suite: "clubs"
31
- },
32
- {
33
- id: crypto.randomUUID(),
34
- rank: 7,
35
- suite: "clubs"
36
- },
37
- {
38
- id: crypto.randomUUID(),
39
- rank: 8,
40
- suite: "clubs"
41
- },
42
- {
43
- id: crypto.randomUUID(),
44
- rank: 9,
45
- suite: "clubs"
46
- },
47
- {
48
- id: crypto.randomUUID(),
49
- rank: 10,
50
- suite: "clubs"
51
- },
52
- {
53
- id: crypto.randomUUID(),
54
- rank: 11,
55
- suite: "clubs"
56
- },
57
- {
58
- id: crypto.randomUUID(),
59
- rank: 12,
60
- suite: "clubs"
61
- },
62
- {
63
- id: crypto.randomUUID(),
64
- rank: 13,
65
- suite: "clubs"
66
- },
67
- {
68
- id: crypto.randomUUID(),
69
- rank: 14,
70
- suite: "clubs"
71
- },
72
- {
73
- id: crypto.randomUUID(),
74
- rank: 2,
75
- suite: "diamonds"
76
- },
77
- {
78
- id: crypto.randomUUID(),
79
- rank: 3,
80
- suite: "diamonds"
81
- },
82
- {
83
- id: crypto.randomUUID(),
84
- rank: 4,
85
- suite: "diamonds"
86
- },
87
- {
88
- id: crypto.randomUUID(),
89
- rank: 5,
90
- suite: "diamonds"
91
- },
92
- {
93
- id: crypto.randomUUID(),
94
- rank: 6,
95
- suite: "diamonds"
96
- },
97
- {
98
- id: crypto.randomUUID(),
99
- rank: 7,
100
- suite: "diamonds"
101
- },
102
- {
103
- id: crypto.randomUUID(),
104
- rank: 8,
105
- suite: "diamonds"
106
- },
107
- {
108
- id: crypto.randomUUID(),
109
- rank: 9,
110
- suite: "diamonds"
111
- },
112
- {
113
- id: crypto.randomUUID(),
114
- rank: 10,
115
- suite: "diamonds"
116
- },
117
- {
118
- id: crypto.randomUUID(),
119
- rank: 11,
120
- suite: "diamonds"
121
- },
122
- {
123
- id: crypto.randomUUID(),
124
- rank: 12,
125
- suite: "diamonds"
126
- },
127
- {
128
- id: crypto.randomUUID(),
129
- rank: 13,
130
- suite: "diamonds"
131
- },
132
- {
133
- id: crypto.randomUUID(),
134
- rank: 14,
135
- suite: "diamonds"
136
- },
137
- {
138
- id: crypto.randomUUID(),
139
- rank: 2,
140
- suite: "hearts"
141
- },
142
- {
143
- id: crypto.randomUUID(),
144
- rank: 3,
145
- suite: "hearts"
146
- },
147
- {
148
- id: crypto.randomUUID(),
149
- rank: 4,
150
- suite: "hearts"
151
- },
152
- {
153
- id: crypto.randomUUID(),
154
- rank: 5,
155
- suite: "hearts"
156
- },
157
- {
158
- id: crypto.randomUUID(),
159
- rank: 6,
160
- suite: "hearts"
161
- },
162
- {
163
- id: crypto.randomUUID(),
164
- rank: 7,
165
- suite: "hearts"
166
- },
167
- {
168
- id: crypto.randomUUID(),
169
- rank: 8,
170
- suite: "hearts"
171
- },
172
- {
173
- id: crypto.randomUUID(),
174
- rank: 9,
175
- suite: "hearts"
176
- },
177
- {
178
- id: crypto.randomUUID(),
179
- rank: 10,
180
- suite: "hearts"
181
- },
182
- {
183
- id: crypto.randomUUID(),
184
- rank: 11,
185
- suite: "hearts"
186
- },
187
- {
188
- id: crypto.randomUUID(),
189
- rank: 12,
190
- suite: "hearts"
191
- },
192
- {
193
- id: crypto.randomUUID(),
194
- rank: 13,
195
- suite: "hearts"
196
- },
197
- {
198
- id: crypto.randomUUID(),
199
- rank: 14,
200
- suite: "hearts"
201
- },
202
- {
203
- id: crypto.randomUUID(),
204
- rank: 2,
205
- suite: "spades"
206
- },
207
- {
208
- id: crypto.randomUUID(),
209
- rank: 3,
210
- suite: "spades"
211
- },
212
- {
213
- id: crypto.randomUUID(),
214
- rank: 4,
215
- suite: "spades"
216
- },
217
- {
218
- id: crypto.randomUUID(),
219
- rank: 5,
220
- suite: "spades"
221
- },
222
- {
223
- id: crypto.randomUUID(),
224
- rank: 6,
225
- suite: "spades"
226
- },
227
- {
228
- id: crypto.randomUUID(),
229
- rank: 7,
230
- suite: "spades"
231
- },
232
- {
233
- id: crypto.randomUUID(),
234
- rank: 8,
235
- suite: "spades"
236
- },
237
- {
238
- id: crypto.randomUUID(),
239
- rank: 9,
240
- suite: "spades"
241
- },
242
- {
243
- id: crypto.randomUUID(),
244
- rank: 10,
245
- suite: "spades"
246
- },
247
- {
248
- id: crypto.randomUUID(),
249
- rank: 11,
250
- suite: "spades"
251
- },
252
- {
253
- id: crypto.randomUUID(),
254
- rank: 12,
255
- suite: "spades"
256
- },
257
- {
258
- id: crypto.randomUUID(),
259
- rank: 13,
260
- suite: "spades"
261
- },
262
- {
263
- id: crypto.randomUUID(),
264
- rank: 14,
265
- suite: "spades"
266
- }
267
- ];
268
- //#endregion
269
- //#region src/manager/games.ts
270
- const games = /* @__PURE__ */ new Map();
271
- //#endregion
272
- //#region src/manager/watchdog.ts
273
- var Watchdog = class {
274
- start() {
275
- console.log(`watchdog start at ${Date.now()} (${GAME_KEY})`);
276
- setInterval(() => this.wakeUp(), WATCHDOG_INTERVAL_MS);
277
- }
278
- wakeUp() {
279
- const now = Date.now();
280
- for (const game of games.values()) if (game.expiresAt <= now) {
281
- games.delete(game.id);
282
- console.log(`watchdog purged ${game.id} (${GAME_KEY})`);
283
- }
284
- }
285
- };
286
- const watchdog = new Watchdog();
287
- //#endregion
288
- //#region src/manager/actions/createGame.ts
289
- function createGame(userId, username) {
290
- if (games.size === 50) return {
291
- success: false,
292
- error: "maxGamesReached"
293
- };
294
- const player = {
295
- id: crypto.randomUUID(),
296
- userId,
297
- username,
298
- events: [],
299
- hand: [],
300
- drawPile: [],
301
- sidePile: [],
302
- centerPile: [],
303
- hasNoPlayableCards: false
304
- };
305
- const createdAt = Date.now();
306
- const game = {
307
- status: "open",
308
- id: crypto.randomUUID(),
309
- createdAt,
310
- expiresAt: createdAt + EXPIRY_EXTENSION_MS,
311
- chatMessages: [],
312
- players: [player]
313
- };
314
- games.set(game.id, game);
315
- return {
316
- success: true,
317
- gameId: game.id,
318
- playerId: player.id
319
- };
320
- }
321
- //#endregion
322
- //#region src/lib/emitEvent.ts
323
- function emitEvent(game, data) {
324
- const event = {
325
- ...data,
326
- id: crypto.randomUUID()
327
- };
328
- for (const p of game.players) p.events.push(event);
329
- }
330
- //#endregion
331
- //#region src/lib/emitEventToPlayer.ts
332
- function emitEventToPlayer(player, data) {
333
- player.events.push({
334
- ...data,
335
- id: crypto.randomUUID()
336
- });
337
- }
338
- //#endregion
339
- //#region src/manager/actions/drawCard.ts
340
- function drawCard(gameId, playerId) {
341
- const game = games.get(gameId);
342
- if (!game) return {
343
- success: false,
344
- error: "gameNotFound"
345
- };
346
- const player = game.players.find((p) => p.id === playerId);
347
- if (!player) return {
348
- success: false,
349
- error: "playerNotFound"
350
- };
351
- if (game.status !== "started") return {
352
- success: false,
353
- error: "invalidStatus"
354
- };
355
- if (Date.now() < game.canPlayAt) return {
356
- success: false,
357
- error: "canPlayAtNotReached"
358
- };
359
- if (player.hand.length >= 5) return {
360
- success: false,
361
- error: "handFull"
362
- };
363
- if (player.drawPile.length === 0) return {
364
- success: false,
365
- error: "drawPileEmpty"
366
- };
367
- game.expiresAt = Date.now() + EXPIRY_EXTENSION_MS;
368
- emitEvent(game, {
369
- type: "expirationUpdated",
370
- expiresAt: game.expiresAt
371
- });
372
- const card = player.drawPile.pop();
373
- player.hand.push(card);
374
- emitEventToPlayer(player, {
375
- type: "drewCard",
376
- card
377
- });
378
- emitEvent(game, {
379
- type: "playerDrewCard",
380
- username: player.username
381
- });
382
- return { success: true };
383
- }
384
- //#endregion
385
- //#region src/manager/actions/getClientStateAndClearEvents.ts
386
- function getClientStateAndClearEvents(gameId, playerId) {
387
- const game = games.get(gameId);
388
- if (!game) return {
389
- success: false,
390
- error: "gameNotFound"
391
- };
392
- const player = game.players.find((p) => p.id === playerId);
393
- if (!player) return {
394
- success: false,
395
- error: "playerNotFound"
396
- };
397
- const state = {
398
- status: game.status,
399
- gameId,
400
- playerId,
401
- username: player.username,
402
- players: game.players.map((p) => ({
403
- username: p.username,
404
- handSize: p.hand.length,
405
- drawPileSize: p.drawPile.length,
406
- sidePileSize: p.sidePile.length,
407
- centerPileTopCard: p.centerPile.length ? p.centerPile[p.centerPile.length - 1] : null
408
- })),
409
- expiresAt: game.expiresAt,
410
- chatMessages: game.chatMessages,
411
- hand: player.hand,
412
- canPlayAt: game.status === "started" ? game.canPlayAt : null
413
- };
414
- player.events.length = 0;
415
- return {
416
- success: true,
417
- state
418
- };
419
- }
420
- //#endregion
421
- //#region src/manager/actions/getEventsAndClearAcknowledged.ts
422
- function getEventsAndClearAcknowledged(gameId, playerId, lastReadId) {
423
- const game = games.get(gameId);
424
- if (!game) return {
425
- success: false,
426
- error: "gameNotFound"
427
- };
428
- const player = game.players.find((p) => p.id === playerId);
429
- if (!player) return {
430
- success: false,
431
- error: "playerNotFound"
432
- };
433
- const lastReadEventIndex = player.events.findIndex((e) => e.id === lastReadId);
434
- player.events.splice(0, lastReadEventIndex + 1);
435
- return {
436
- success: true,
437
- events: player.events
438
- };
439
- }
440
- //#endregion
441
- //#region src/manager/actions/getJoinableGames.ts
442
- function getJoinableGames() {
443
- return {
444
- success: true,
445
- games: Array.from(games.values()).filter((g) => g.status === "open" && g.players.length < 2).map((g) => ({
446
- id: g.id,
447
- numPlayers: g.players.length
448
- }))
449
- };
450
- }
451
- //#endregion
452
- //#region src/manager/actions/joinGame.ts
453
- function joinGame(gameId, userId, username) {
454
- const game = games.get(gameId);
455
- if (!game) return {
456
- success: false,
457
- error: "gameNotFound"
458
- };
459
- if (game.status !== "open") return {
460
- success: false,
461
- error: "invalidStatus"
462
- };
463
- if (game.players.length === 2) return {
464
- success: false,
465
- error: "maxPlayersReached"
466
- };
467
- if (game.players.find((p) => p.userId === userId)) return {
468
- success: false,
469
- error: "alreadyInGame"
470
- };
471
- const player = {
472
- id: crypto.randomUUID(),
473
- userId,
474
- username,
475
- events: [],
476
- hand: [],
477
- drawPile: [],
478
- sidePile: [],
479
- centerPile: [],
480
- hasNoPlayableCards: false
481
- };
482
- game.players.push(player);
483
- emitEvent(game, {
484
- type: "playerJoined",
485
- username
486
- });
487
- return {
488
- success: true,
489
- playerId: player.id
490
- };
491
- }
492
- //#endregion
493
- //#region src/manager/actions/leaveGame.ts
494
- function leaveGame(gameId, playerId) {
495
- const game = games.get(gameId);
496
- if (!game) return {
497
- success: false,
498
- error: "gameNotFound"
499
- };
500
- const playerIndex = game.players.findIndex((p) => p.id === playerId);
501
- if (playerIndex === -1) return {
502
- success: false,
503
- error: "playerNotFound"
504
- };
505
- const player = game.players[playerIndex];
506
- emitEvent(game, {
507
- type: "playerLeft",
508
- username: player.username
509
- });
510
- game.players.splice(playerIndex, 1);
511
- if (game.status === "started" && game.players.length < 2) {
512
- const forfeitedGame = {
513
- ...game,
514
- status: "forfeited",
515
- expiresAt: Date.now() + EXPIRY_EXTENSION_MS
516
- };
517
- games.set(game.id, forfeitedGame);
518
- emitEvent(forfeitedGame, { type: "gameForfeited" });
519
- emitEvent(forfeitedGame, {
520
- type: "expirationUpdated",
521
- expiresAt: forfeitedGame.expiresAt
522
- });
523
- }
524
- if (game.players.length === 0) games.delete(game.id);
525
- return { success: true };
526
- }
527
- //#endregion
528
- //#region src/manager/lib/isCardPlayable.ts
529
- function isCardPlayable(card, targetPile) {
530
- const targetCard = targetPile[targetPile.length - 1];
531
- return Math.abs(card.rank - targetCard.rank) % 11 === 1;
532
- }
533
- //#endregion
534
- //#region src/manager/lib/hasPlayableCard.ts
535
- function hasPlayableCard(player, game) {
536
- const otherPlayer = game.players.find((p) => p !== player);
537
- const targetPile1 = player.centerPile;
538
- const targetPile2 = otherPlayer.centerPile;
539
- for (const card of player.hand) if (isCardPlayable(card, targetPile1) || isCardPlayable(card, targetPile2)) return true;
540
- return false;
541
- }
542
- //#endregion
543
- //#region src/manager/actions/playCard.ts
544
- function playCard(gameId, playerId, cardId, isForOtherPlayerPile) {
545
- const game = games.get(gameId);
546
- if (!game) return {
547
- success: false,
548
- error: "gameNotFound"
549
- };
550
- const player = game.players.find((p) => p.id === playerId);
551
- if (!player) return {
552
- success: false,
553
- error: "playerNotFound"
554
- };
555
- if (game.status !== "started") return {
556
- success: false,
557
- error: "invalidStatus"
558
- };
559
- if (Date.now() < game.canPlayAt) return {
560
- success: false,
561
- error: "canPlayAtNotReached"
562
- };
563
- const cardIndex = player.hand.findIndex((c) => c.id === cardId);
564
- if (cardIndex === -1) return {
565
- success: false,
566
- error: "cardNotFound"
567
- };
568
- const otherPlayer = game.players.find((p) => p !== player);
569
- const targetPile = isForOtherPlayerPile ? otherPlayer.centerPile : player.centerPile;
570
- const card = player.hand[cardIndex];
571
- if (!isCardPlayable(card, targetPile)) return {
572
- success: false,
573
- error: "cardNotPlayable"
574
- };
575
- game.expiresAt = Date.now() + EXPIRY_EXTENSION_MS;
576
- emitEvent(game, {
577
- type: "expirationUpdated",
578
- expiresAt: game.expiresAt
579
- });
580
- player.hand.splice(cardIndex, 1);
581
- targetPile.push(card);
582
- emitEvent(game, {
583
- type: "cardPlayed",
584
- username: player.username,
585
- card,
586
- isForOtherPlayerPile
587
- });
588
- if (otherPlayer.hasNoPlayableCards && hasPlayableCard(otherPlayer, game)) otherPlayer.hasNoPlayableCards = false;
589
- if (player.hand.length === 0 && player.drawPile.length === 0) {
590
- emitEvent(game, { type: "gameCompleted" });
591
- const completedGame = {
592
- ...game,
593
- status: "completed"
594
- };
595
- games.set(game.id, completedGame);
596
- }
597
- return { success: true };
598
- }
599
- //#endregion
600
- //#region src/lib/shuffleCards.ts
601
- function shuffleCards(cards) {
602
- for (let i = cards.length - 1; i > 0; i--) {
603
- const j = Math.floor(Math.random() * (i + 1));
604
- [cards[i], cards[j]] = [cards[j], cards[i]];
605
- }
606
- }
607
- //#endregion
608
- //#region src/manager/actions/reportNoPlayableCards.ts
609
- function reportNoPlayableCards(gameId, playerId) {
610
- const game = games.get(gameId);
611
- if (!game) return {
612
- success: false,
613
- error: "gameNotFound"
614
- };
615
- const player = game.players.find((p) => p.id === playerId);
616
- if (!player) return {
617
- success: false,
618
- error: "playerNotFound"
619
- };
620
- if (game.status !== "started") return {
621
- success: false,
622
- error: "invalidStatus"
623
- };
624
- if (Date.now() < game.canPlayAt) return {
625
- success: false,
626
- error: "canPlayAtNotReached"
627
- };
628
- if (player.hasNoPlayableCards) return {
629
- success: false,
630
- error: "alreadyReported"
631
- };
632
- if (hasPlayableCard(player, game)) return {
633
- success: false,
634
- error: "hasPlayableCard"
635
- };
636
- if (player.drawPile.length > 0 && player.hand.length < 5) return {
637
- success: false,
638
- error: "canDraw"
639
- };
640
- game.expiresAt = Date.now() + EXPIRY_EXTENSION_MS;
641
- emitEvent(game, {
642
- type: "expirationUpdated",
643
- expiresAt: game.expiresAt
644
- });
645
- player.hasNoPlayableCards = true;
646
- const otherPlayer = game.players.find((p) => p !== player);
647
- if (otherPlayer.hasNoPlayableCards) {
648
- if (player.sidePile.length === 0 && otherPlayer.sidePile.length === 0) {
649
- const cards = [...player.centerPile, ...otherPlayer.centerPile];
650
- shuffleCards(cards);
651
- player.sidePile.push(...cards.splice(0, 5));
652
- emitEvent(game, {
653
- type: "playerSidePileInitialized",
654
- username: player.username,
655
- numCards: player.sidePile.length
656
- });
657
- player.centerPile.push(...cards.splice(0, 1));
658
- emitEvent(game, {
659
- type: "playerCenterPileInitialized",
660
- username: player.username,
661
- card: player.centerPile[player.centerPile.length - 1]
662
- });
663
- otherPlayer.centerPile.push(...cards.splice(0, 1));
664
- emitEvent(game, {
665
- type: "playerCenterPileInitialized",
666
- username: otherPlayer.username,
667
- card: otherPlayer.centerPile[otherPlayer.centerPile.length - 1]
668
- });
669
- otherPlayer.sidePile.push(...cards.splice(0, 5));
670
- emitEvent(game, {
671
- type: "playerSidePileInitialized",
672
- username: otherPlayer.username,
673
- numCards: otherPlayer.sidePile.length
674
- });
675
- } else {
676
- const playerSidePileCard = player.sidePile.pop();
677
- player.centerPile.push(playerSidePileCard);
678
- emitEvent(game, {
679
- type: "cardDrawnFromSidePileToCenterPile",
680
- username: player.username,
681
- card: playerSidePileCard
682
- });
683
- const otherPlayerSidePileCard = otherPlayer.sidePile.pop();
684
- otherPlayer.centerPile.push(otherPlayerSidePileCard);
685
- emitEvent(game, {
686
- type: "cardDrawnFromSidePileToCenterPile",
687
- username: otherPlayer.username,
688
- card: otherPlayerSidePileCard
689
- });
690
- }
691
- player.hasNoPlayableCards = false;
692
- otherPlayer.hasNoPlayableCards = false;
693
- game.canPlayAt = Date.now() + CAN_PLAY_AT_DELAY_MS;
694
- emitEvent(game, {
695
- type: "canPlayAtUpdated",
696
- canPlayAt: game.canPlayAt
697
- });
698
- }
699
- return { success: true };
700
- }
701
- //#endregion
702
- //#region src/manager/actions/sendChat.ts
703
- function sendChat(gameId, playerId, text) {
704
- const game = games.get(gameId);
705
- if (!game) return {
706
- success: false,
707
- error: "gameNotFound"
708
- };
709
- const player = game.players.find((p) => p.id === playerId);
710
- if (!player) return {
711
- success: false,
712
- error: "playerNotFound"
713
- };
714
- const message = {
715
- id: crypto.randomUUID(),
716
- username: player.username,
717
- text
718
- };
719
- game.chatMessages.push(message);
720
- emitEvent(game, {
721
- type: "chat",
722
- message
723
- });
724
- return { success: true };
725
- }
726
- //#endregion
727
- //#region src/manager/actions/startGame.ts
728
- function startGame(gameId, playerId) {
729
- const game = games.get(gameId);
730
- if (!game) return {
731
- success: false,
732
- error: "gameNotFound"
733
- };
734
- const player = game.players.find((p) => p.id === playerId);
735
- if (!player) return {
736
- success: false,
737
- error: "playerNotFound"
738
- };
739
- if (game.status !== "open") return {
740
- success: false,
741
- error: "invalidStatus"
742
- };
743
- if (game.players.indexOf(player) !== 0) return {
744
- success: false,
745
- error: "playerNotAdmin"
746
- };
747
- if (game.players.length < 2) return {
748
- success: false,
749
- error: "minPlayersNotReached"
750
- };
751
- const otherPlayer = game.players[1];
752
- const cards = [...CARDS];
753
- shuffleCards(cards);
754
- player.sidePile.push(...cards.splice(0, 5));
755
- emitEvent(game, {
756
- type: "playerSidePileInitialized",
757
- username: player.username,
758
- numCards: player.sidePile.length
759
- });
760
- player.centerPile.push(...cards.splice(0, 1));
761
- emitEvent(game, {
762
- type: "playerCenterPileInitialized",
763
- username: player.username,
764
- card: player.centerPile[player.centerPile.length - 1]
765
- });
766
- otherPlayer.centerPile.push(...cards.splice(0, 1));
767
- emitEvent(game, {
768
- type: "playerCenterPileInitialized",
769
- username: otherPlayer.username,
770
- card: otherPlayer.centerPile[otherPlayer.centerPile.length - 1]
771
- });
772
- otherPlayer.sidePile.push(...cards.splice(0, 5));
773
- emitEvent(game, {
774
- type: "playerSidePileInitialized",
775
- username: otherPlayer.username,
776
- numCards: otherPlayer.sidePile.length
777
- });
778
- player.drawPile.push(...cards.splice(0, 15));
779
- emitEvent(game, {
780
- type: "playerDrawPileInitialized",
781
- username: player.username,
782
- numCards: player.drawPile.length
783
- });
784
- player.hand.push(...cards.splice(0, 5));
785
- emitEventToPlayer(player, {
786
- type: "handInitialized",
787
- cards: player.hand
788
- });
789
- emitEvent(game, {
790
- type: "playerHandInitialized",
791
- username: player.username,
792
- numCards: player.hand.length
793
- });
794
- otherPlayer.drawPile.push(...cards.splice(0, 15));
795
- emitEvent(game, {
796
- type: "playerDrawPileInitialized",
797
- username: otherPlayer.username,
798
- numCards: otherPlayer.drawPile.length
799
- });
800
- otherPlayer.hand.push(...cards.splice(0, 5));
801
- emitEventToPlayer(otherPlayer, {
802
- type: "handInitialized",
803
- cards: otherPlayer.hand
804
- });
805
- emitEvent(game, {
806
- type: "playerHandInitialized",
807
- username: otherPlayer.username,
808
- numCards: otherPlayer.hand.length
809
- });
810
- const startedGame = {
811
- ...game,
812
- status: "started",
813
- expiresAt: Date.now() + EXPIRY_EXTENSION_MS,
814
- canPlayAt: Date.now() + CAN_PLAY_AT_DELAY_MS
815
- };
816
- games.set(game.id, startedGame);
817
- emitEvent(startedGame, { type: "gameStarted" });
818
- emitEvent(startedGame, {
819
- type: "expirationUpdated",
820
- expiresAt: startedGame.expiresAt
821
- });
822
- emitEvent(startedGame, {
823
- type: "canPlayAtUpdated",
824
- canPlayAt: startedGame.canPlayAt
825
- });
826
- return { success: true };
827
- }
828
- //#endregion
829
- //#region src/manager/index.ts
830
- watchdog.start();
831
- //#endregion
832
- export { leaveGame as a, getEventsAndClearAcknowledged as c, createGame as d, playCard as i, getClientStateAndClearEvents as l, sendChat as n, joinGame as o, reportNoPlayableCards as r, getJoinableGames as s, startGame as t, drawCard as u };
833
-
834
- //# sourceMappingURL=manager-CPmezdJa.mjs.map