@jjlmoya/utils-tabletop 1.27.0 → 1.29.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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -0
  3. package/src/entries.ts +2 -0
  4. package/src/tests/locale_completeness.test.ts +1 -1
  5. package/src/tests/tool_validation.test.ts +1 -1
  6. package/src/tool/mus-scoreboard/bibliography.astro +16 -0
  7. package/src/tool/mus-scoreboard/bibliography.ts +12 -0
  8. package/src/tool/mus-scoreboard/component.astro +179 -0
  9. package/src/tool/mus-scoreboard/controller.ts +178 -0
  10. package/src/tool/mus-scoreboard/dom-views.ts +87 -0
  11. package/src/tool/mus-scoreboard/entry.ts +27 -0
  12. package/src/tool/mus-scoreboard/evaluator.ts +27 -0
  13. package/src/tool/mus-scoreboard/i18n/de.ts +187 -0
  14. package/src/tool/mus-scoreboard/i18n/en.ts +187 -0
  15. package/src/tool/mus-scoreboard/i18n/es.ts +187 -0
  16. package/src/tool/mus-scoreboard/i18n/fr.ts +187 -0
  17. package/src/tool/mus-scoreboard/i18n/id.ts +187 -0
  18. package/src/tool/mus-scoreboard/i18n/it.ts +187 -0
  19. package/src/tool/mus-scoreboard/i18n/ja.ts +187 -0
  20. package/src/tool/mus-scoreboard/i18n/ko.ts +187 -0
  21. package/src/tool/mus-scoreboard/i18n/nl.ts +187 -0
  22. package/src/tool/mus-scoreboard/i18n/pl.ts +187 -0
  23. package/src/tool/mus-scoreboard/i18n/pt.ts +187 -0
  24. package/src/tool/mus-scoreboard/i18n/ru.ts +187 -0
  25. package/src/tool/mus-scoreboard/i18n/sv.ts +187 -0
  26. package/src/tool/mus-scoreboard/i18n/tr.ts +187 -0
  27. package/src/tool/mus-scoreboard/i18n/zh.ts +187 -0
  28. package/src/tool/mus-scoreboard/index.ts +11 -0
  29. package/src/tool/mus-scoreboard/logic.test.ts +82 -0
  30. package/src/tool/mus-scoreboard/logic.ts +122 -0
  31. package/src/tool/mus-scoreboard/online-mus-scoreboard.css +740 -0
  32. package/src/tool/mus-scoreboard/seo.astro +16 -0
  33. package/src/tool/mus-scoreboard/storage.ts +29 -0
  34. package/src/tool/mus-scoreboard/ui.ts +63 -0
  35. package/src/tools.ts +2 -0
@@ -0,0 +1,122 @@
1
+ export type Team = 0 | 1;
2
+ export type MusDeck = 'spanish' | 'french';
3
+
4
+ export interface MusConfig {
5
+ pairNames: [string, string];
6
+ targetPoints: number;
7
+ gamesToWin: number;
8
+ deck: MusDeck;
9
+ }
10
+
11
+ export interface MusState {
12
+ config: MusConfig;
13
+ points: [number, number];
14
+ games: [number, number];
15
+ hand: Team;
16
+ history: MusHistoryEntry[];
17
+ }
18
+
19
+ export interface MusHistoryEntry {
20
+ action: string;
21
+ team: Team | null;
22
+ amount: number;
23
+ points: [number, number];
24
+ games: [number, number];
25
+ hand: Team;
26
+ }
27
+
28
+ export interface ScoreParts {
29
+ amarracos: number;
30
+ stones: number;
31
+ }
32
+
33
+ export const DEFAULT_CONFIG: MusConfig = {
34
+ pairNames: ['Pair One', 'Pair Two'],
35
+ targetPoints: 40,
36
+ gamesToWin: 2,
37
+ deck: 'spanish',
38
+ };
39
+
40
+ const copyPair = (values: [number, number]): [number, number] => [values[0], values[1]];
41
+
42
+ const copyConfig = (config: MusConfig): MusConfig => ({
43
+ pairNames: [config.pairNames[0], config.pairNames[1]],
44
+ targetPoints: config.targetPoints,
45
+ gamesToWin: config.gamesToWin,
46
+ deck: config.deck,
47
+ });
48
+
49
+ export const createMusState = (config: MusConfig = DEFAULT_CONFIG): MusState => ({
50
+ config: copyConfig(config),
51
+ points: [0, 0],
52
+ games: [0, 0],
53
+ hand: 0,
54
+ history: [],
55
+ });
56
+
57
+ const snapshot = (state: MusState, action: string, team: Team | null, amount: number): MusHistoryEntry => ({
58
+ action,
59
+ team,
60
+ amount,
61
+ points: copyPair(state.points),
62
+ games: copyPair(state.games),
63
+ hand: state.hand,
64
+ });
65
+
66
+ export const addPoints = (state: MusState, team: Team, amount: 1 | 5): MusState => ({
67
+ ...state,
68
+ points: state.points.map((value, index) => index === team ? value + amount : value) as [number, number],
69
+ history: [...state.history, snapshot(state, `+${amount}`, team, amount)],
70
+ });
71
+
72
+ export const canCloseGame = (state: MusState, team: Team): boolean => state.points[team] >= state.config.targetPoints;
73
+
74
+ export const getMatchWinner = (state: MusState): Team | null => {
75
+ const winner = state.games.findIndex((games) => games >= state.config.gamesToWin);
76
+ return winner === -1 ? null : winner as Team;
77
+ };
78
+
79
+ export const closeGame = (state: MusState, team: Team): MusState => {
80
+ if (!canCloseGame(state, team) || getMatchWinner(state) !== null) return state;
81
+ return {
82
+ ...state,
83
+ points: [0, 0],
84
+ games: state.games.map((value, index) => index === team ? value + 1 : value) as [number, number],
85
+ history: [...state.history, snapshot(state, 'Close game', team, 0)],
86
+ };
87
+ };
88
+
89
+ export const setHand = (state: MusState, team: Team): MusState => {
90
+ if (state.hand === team) return state;
91
+ return {
92
+ ...state,
93
+ hand: team,
94
+ history: [...state.history, snapshot(state, 'Hand', team, 0)],
95
+ };
96
+ };
97
+
98
+ export const undoLastAction = (state: MusState): MusState => {
99
+ const previous = state.history.at(-1);
100
+ const history = state.history.slice(0, -1);
101
+ return previous ? {
102
+ ...state,
103
+ points: copyPair(previous.points),
104
+ games: copyPair(previous.games),
105
+ hand: previous.hand,
106
+ history,
107
+ } : createMusState(state.config);
108
+ };
109
+
110
+ export const updateConfig = (state: MusState, config: MusConfig): MusState => {
111
+ void state;
112
+ return createMusState(config);
113
+ };
114
+
115
+ export const decomposeScore = (points: number): ScoreParts => ({
116
+ amarracos: Math.floor(points / 5),
117
+ stones: points % 5,
118
+ });
119
+
120
+ export const remainingPoints = (state: MusState, team: Team): number => Math.max(0, state.config.targetPoints - state.points[team]);
121
+
122
+ export const isGameReadyToClose = (state: MusState): boolean => state.points.some((points) => points >= state.config.targetPoints);