Skip to content

Commit 443f576

Browse files
TannPatPartMan7
andauthored
Games: Add custom points cap to Splendor games (#106)
* Add custom points cap to splendor games * chore: Rename POINTS_TO_WIN to DEFAULT_POINTS_TO_WIN * chore: Add error message for invalid cap --------- Co-authored-by: PartMan <parth.mane@sprinklr.com>
1 parent 4be6c45 commit 443f576

7 files changed

Lines changed: 33 additions & 16 deletions

File tree

src/i18n/languages/english.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export default {
168168
RESERVE: 'Reserve!',
169169
BUY_CARD: 'Buy {{card}}!',
170170
},
171+
INVALID_POINTS_CAP: 'The point cap must be between {{minCap}} and {{maxCap}}. {{cap}} is invalid.',
171172
INVALID_CARD: '{{card}} is not a valid card.',
172173
CARD_NOT_ACCESSIBLE: 'Cannot access {{card}} for the desired action.',
173174
DISCARD_TOKENS_REQUIRED: 'You need to discard tokens!',

src/i18n/languages/french.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export default {
165165
RESERVE: 'Réserver !',
166166
BUY_CARD: 'Acheter {{card}} !',
167167
},
168+
INVALID_POINTS_CAP: 'Le plafond de points doit être entre {{minCap}} et {{maxCap}}. {{cap}} est invalide.',
168169
INVALID_CARD: "{{card}} n'est pas une carte valide.",
169170
CARD_NOT_ACCESSIBLE: "Impossible d'accéder à {{card}} pour l'action souhaitée.",
170171
DISCARD_TOKENS_REQUIRED: 'Vous devez défausser des jetons !',

src/i18n/languages/hindi.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ export default {
153153
RESERVE: 'Reserve karo!',
154154
BUY_CARD: '{{card}} kharido!',
155155
},
156+
INVALID_POINTS_CAP: 'Point cap {{minCap}} aur {{maxCap}} ke beech hona chahiye. {{cap}} valid nahi hai.',
156157
INVALID_CARD: '{{card}} ek valid card nahi hai.',
157158
CARD_NOT_ACCESSIBLE: '{{card}} is action ke liye accessible nahi hai.',
158159
DISCARD_TOKENS_REQUIRED: 'Aapko tokens discard karne honge!',

src/i18n/languages/portuguese.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export default {
164164
RESERVE: 'Reservar!',
165165
BUY_CARD: 'Comprar {{card}}!',
166166
},
167+
INVALID_POINTS_CAP: 'O limite de pontos deve estar entre {{minCap}} e {{maxCap}}. {{cap}} é inválido.',
167168
INVALID_CARD: '{{card}} não é uma carta válida.',
168169
CARD_NOT_ACCESSIBLE: 'Não é possível acessar {{card}} para a ação desejada.',
169170
DISCARD_TOKENS_REQUIRED: 'Você precisa descartar fichas!',

src/ps/games/splendor/constants.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export enum VIEW_ACTION_TYPE {
2828
GAME_END = 'end',
2929
}
3030

31-
export const POINTS_TO_WIN = 15;
31+
export const MIN_POINTS_TO_WIN = 8;
32+
export const MAX_POINTS_TO_WIN = 21;
33+
export const DEFAULT_POINTS_TO_WIN = 15;
3234
export const MAX_TOKEN_COUNT = 10;
3335
export const MAX_RESERVE_COUNT = 3;

src/ps/games/splendor/index.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { BaseGame } from '@/ps/games/game';
22
import {
33
ACTIONS,
44
AllTokenTypes,
5+
DEFAULT_POINTS_TO_WIN,
6+
MAX_POINTS_TO_WIN,
57
MAX_RESERVE_COUNT,
68
MAX_TOKEN_COUNT,
7-
POINTS_TO_WIN,
9+
MIN_POINTS_TO_WIN,
810
TOKEN_TYPE,
911
TokenTypes,
1012
VIEW_ACTION_TYPE,
@@ -29,6 +31,13 @@ export class Splendor extends BaseGame<State> {
2931

3032
constructor(ctx: BaseContext) {
3133
super(ctx);
34+
35+
const givenCap = ctx.args.join('').trim();
36+
this.state.pointsToWin = givenCap ? parseInt(givenCap) : DEFAULT_POINTS_TO_WIN;
37+
if (this.state.pointsToWin < MIN_POINTS_TO_WIN || this.state.pointsToWin > MAX_POINTS_TO_WIN || isNaN(this.state.pointsToWin)) {
38+
this.throw('GAME.SPLENDOR.INVALID_POINTS_CAP', { cap: givenCap, minCap: MIN_POINTS_TO_WIN, maxCap: MAX_POINTS_TO_WIN });
39+
}
40+
3241
super.persist(ctx);
3342

3443
if (ctx.backup) return;
@@ -67,7 +76,7 @@ export class Splendor extends BaseGame<State> {
6776
this.turn === lastPlayerInRound &&
6877
Object.values(this.players)
6978
.filter(player => !player.out)
70-
.some(player => this.state.playerData[player.turn].points >= POINTS_TO_WIN)
79+
.some(player => this.state.playerData[player.turn].points >= this.state.pointsToWin)
7180
);
7281
}
7382

@@ -216,8 +225,7 @@ export class Splendor extends BaseGame<State> {
216225
case VIEW_ACTION_TYPE.CLICK_DECK: {
217226
if (!['1', '2', '3'].includes(actionCtx)) throw new ChatError(this.$T('GAME.SPLENDOR.WHICH_TIER'));
218227
const tier = +actionCtx as 1 | 2 | 3;
219-
if (this.state.board.cards[tier].deck.length === 0)
220-
throw new ChatError(this.$T('GAME.SPLENDOR.DECK_EMPTY', { tier }));
228+
if (this.state.board.cards[tier].deck.length === 0) throw new ChatError(this.$T('GAME.SPLENDOR.DECK_EMPTY', { tier }));
221229

222230
const canReserve = this.canReserve(player);
223231
if (!canReserve) throw new ChatError(this.$T('GAME.SPLENDOR.RESERVE_LIMIT'));
@@ -234,10 +242,8 @@ export class Splendor extends BaseGame<State> {
234242
const tokens = this.parseTokens(actionCtx, true);
235243
const discarding = Object.values(tokens).sum();
236244

237-
if (discarding < toDiscard)
238-
throw new ChatError(this.$T('GAME.SPLENDOR.DISCARD_MORE', { required: toDiscard, discarding }));
239-
if (!this.canAfford(tokens, playerData.tokens, null, false))
240-
throw new ChatError(this.$T('GAME.SPLENDOR.CANNOT_DISCARD'));
245+
if (discarding < toDiscard) throw new ChatError(this.$T('GAME.SPLENDOR.DISCARD_MORE', { required: toDiscard, discarding }));
246+
if (!this.canAfford(tokens, playerData.tokens, null, false)) throw new ChatError(this.$T('GAME.SPLENDOR.CANNOT_DISCARD'));
241247

242248
this.spendTokens(tokens, playerData);
243249
logEntry = { turn: player.turn, time: new Date(), action: VIEW_ACTION_TYPE.TOO_MANY_TOKENS, ctx: { discard: tokens } };
@@ -278,8 +284,7 @@ export class Splendor extends BaseGame<State> {
278284
let reservedId: string;
279285
if (deckReserve) {
280286
const tier = deckReserve as 1 | 2 | 3;
281-
if (this.state.board.cards[tier].deck.length === 0)
282-
throw new ChatError(this.$T('GAME.SPLENDOR.DECK_EMPTY', { tier }));
287+
if (this.state.board.cards[tier].deck.length === 0) throw new ChatError(this.$T('GAME.SPLENDOR.DECK_EMPTY', { tier }));
283288

284289
const [card] = this.state.board.cards[tier].deck.splice(0, 1);
285290
playerData.reserved.push(card);
@@ -421,8 +426,7 @@ export class Splendor extends BaseGame<State> {
421426
const amt = +(entry.match(/\d/) ?? '0');
422427
if (!(amt >= 0 && amt < 10)) throw new ChatError(this.$T('GAME.SPLENDOR.INVALID_COUNT', { value: entry.substring(1) }));
423428
if (!AllTokenTypes.includes(type)) throw new ChatError(this.$T('GAME.SPLENDOR.UNRECOGNIZED_TYPE', { type }));
424-
if (type === TOKEN_TYPE.DRAGON && !allowDragon)
425-
throw new ChatError(this.$T('GAME.SPLENDOR.DRAGON_NOT_ALLOWED'));
429+
if (type === TOKEN_TYPE.DRAGON && !allowDragon) throw new ChatError(this.$T('GAME.SPLENDOR.DRAGON_NOT_ALLOWED'));
426430
tokens[type] += amt;
427431
});
428432
return tokens;
@@ -433,8 +437,7 @@ export class Splendor extends BaseGame<State> {
433437
if (count > 0) return { type, count, available: this.state.board.tokens[type], name: metadata.types[type].name };
434438
});
435439

436-
if (tokens[TOKEN_TYPE.DRAGON])
437-
return { success: false, error: this.$T('GAME.SPLENDOR.DRAGON_ONLY_BY_RESERVE') };
440+
if (tokens[TOKEN_TYPE.DRAGON]) return { success: false, error: this.$T('GAME.SPLENDOR.DRAGON_ONLY_BY_RESERVE') };
438441

439442
const tooMany = input.filter(({ count, available }) => count > available);
440443
if (tooMany.length > 0) {
@@ -513,7 +516,14 @@ export class Splendor extends BaseGame<State> {
513516
else view = { type: 'player', active: false, self: side };
514517
} else view = { type: 'spectator', active: false, action: this.winCtx ? VIEW_ACTION_TYPE.GAME_END : null };
515518

516-
const ctx: RenderCtx = { id: this.id, board: this.state.board, players: this.state.playerData, turns: this.turns, view, $T: this.$T };
519+
const ctx: RenderCtx = {
520+
id: this.id,
521+
board: this.state.board,
522+
players: this.state.playerData,
523+
turns: this.turns,
524+
view,
525+
$T: this.$T,
526+
};
517527

518528
if (this.winCtx) {
519529
ctx.header = this.$T('GAME.GAME_ENDED');

src/ps/games/splendor/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export type ViewType =
8282
| (ActivePlayer & ActionState);
8383

8484
export type State = {
85+
pointsToWin: number;
8586
turn: Turn;
8687
board: Board;
8788
playerData: Record<Turn, PlayerData>;

0 commit comments

Comments
 (0)