volleyballsimtypes 0.0.139 → 0.0.140

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 (185) hide show
  1. package/dist/esm/data/index.d.ts +3 -0
  2. package/dist/esm/data/index.js +3 -0
  3. package/dist/esm/data/init-models.d.ts +2 -0
  4. package/dist/esm/data/init-models.js +194 -0
  5. package/dist/esm/data/models/coach.d.ts +40 -0
  6. package/dist/esm/data/models/coach.js +51 -0
  7. package/dist/esm/data/models/competition-champion.d.ts +23 -0
  8. package/dist/esm/data/models/competition-champion.js +34 -0
  9. package/dist/esm/data/models/competition-match.d.ts +29 -0
  10. package/dist/esm/data/models/competition-match.js +42 -0
  11. package/dist/esm/data/models/competition-teams.d.ts +23 -0
  12. package/dist/esm/data/models/competition-teams.js +38 -0
  13. package/dist/esm/data/models/competition.d.ts +67 -0
  14. package/dist/esm/data/models/competition.js +34 -0
  15. package/dist/esm/data/models/country.d.ts +61 -0
  16. package/dist/esm/data/models/country.js +30 -0
  17. package/dist/esm/data/models/draft-pick.d.ts +31 -0
  18. package/dist/esm/data/models/draft-pick.js +46 -0
  19. package/dist/esm/data/models/draft.d.ts +29 -0
  20. package/dist/esm/data/models/draft.js +30 -0
  21. package/dist/esm/data/models/index.d.ts +24 -0
  22. package/dist/esm/data/models/index.js +24 -0
  23. package/dist/esm/data/models/iteration.d.ts +26 -0
  24. package/dist/esm/data/models/iteration.js +26 -0
  25. package/dist/esm/data/models/league-season.d.ts +23 -0
  26. package/dist/esm/data/models/league-season.js +34 -0
  27. package/dist/esm/data/models/league.d.ts +44 -0
  28. package/dist/esm/data/models/league.js +34 -0
  29. package/dist/esm/data/models/match-rating.d.ts +27 -0
  30. package/dist/esm/data/models/match-rating.js +48 -0
  31. package/dist/esm/data/models/match-set-stats.d.ts +58 -0
  32. package/dist/esm/data/models/match-set-stats.js +123 -0
  33. package/dist/esm/data/models/match-set.d.ts +85 -0
  34. package/dist/esm/data/models/match-set.js +47 -0
  35. package/dist/esm/data/models/match.d.ts +67 -0
  36. package/dist/esm/data/models/match.js +47 -0
  37. package/dist/esm/data/models/performance-stats.d.ts +40 -0
  38. package/dist/esm/data/models/performance-stats.js +81 -0
  39. package/dist/esm/data/models/player-team.d.ts +28 -0
  40. package/dist/esm/data/models/player-team.js +48 -0
  41. package/dist/esm/data/models/player-trait.d.ts +23 -0
  42. package/dist/esm/data/models/player-trait.js +38 -0
  43. package/dist/esm/data/models/player.d.ts +124 -0
  44. package/dist/esm/data/models/player.js +42 -0
  45. package/dist/esm/data/models/rally.d.ts +29 -0
  46. package/dist/esm/data/models/rally.js +46 -0
  47. package/dist/esm/data/models/set-position.d.ts +29 -0
  48. package/dist/esm/data/models/set-position.js +46 -0
  49. package/dist/esm/data/models/team.d.ts +162 -0
  50. package/dist/esm/data/models/team.js +59 -0
  51. package/dist/esm/data/models/trait.d.ts +37 -0
  52. package/dist/esm/data/models/trait.js +26 -0
  53. package/dist/esm/data/models/user.d.ts +22 -0
  54. package/dist/esm/data/models/user.js +53 -0
  55. package/dist/esm/data/transformers/coach.d.ts +5 -0
  56. package/dist/esm/data/transformers/coach.js +25 -0
  57. package/dist/esm/data/transformers/country.d.ts +5 -0
  58. package/dist/esm/data/transformers/country.js +16 -0
  59. package/dist/esm/data/transformers/court-position.d.ts +5 -0
  60. package/dist/esm/data/transformers/court-position.js +27 -0
  61. package/dist/esm/data/transformers/draft-pick.d.ts +5 -0
  62. package/dist/esm/data/transformers/draft-pick.js +18 -0
  63. package/dist/esm/data/transformers/draft.d.ts +5 -0
  64. package/dist/esm/data/transformers/draft.js +20 -0
  65. package/dist/esm/data/transformers/formation.d.ts +5 -0
  66. package/dist/esm/data/transformers/formation.js +8 -0
  67. package/dist/esm/data/transformers/index.d.ts +25 -0
  68. package/dist/esm/data/transformers/index.js +25 -0
  69. package/dist/esm/data/transformers/iteration.d.ts +5 -0
  70. package/dist/esm/data/transformers/iteration.js +14 -0
  71. package/dist/esm/data/transformers/league.d.ts +5 -0
  72. package/dist/esm/data/transformers/league.js +28 -0
  73. package/dist/esm/data/transformers/match-rating.d.ts +4 -0
  74. package/dist/esm/data/transformers/match-rating.js +13 -0
  75. package/dist/esm/data/transformers/match-set-stats.d.ts +5 -0
  76. package/dist/esm/data/transformers/match-set-stats.js +57 -0
  77. package/dist/esm/data/transformers/match-set.d.ts +5 -0
  78. package/dist/esm/data/transformers/match-set.js +44 -0
  79. package/dist/esm/data/transformers/match.d.ts +5 -0
  80. package/dist/esm/data/transformers/match.js +27 -0
  81. package/dist/esm/data/transformers/performance-stats.d.ts +5 -0
  82. package/dist/esm/data/transformers/performance-stats.js +33 -0
  83. package/dist/esm/data/transformers/player-team.d.ts +3 -0
  84. package/dist/esm/data/transformers/player-team.js +9 -0
  85. package/dist/esm/data/transformers/player.d.ts +5 -0
  86. package/dist/esm/data/transformers/player.js +26 -0
  87. package/dist/esm/data/transformers/rally.d.ts +5 -0
  88. package/dist/esm/data/transformers/rally.js +23 -0
  89. package/dist/esm/data/transformers/role.d.ts +5 -0
  90. package/dist/esm/data/transformers/role.js +23 -0
  91. package/dist/esm/data/transformers/season-match.d.ts +4 -0
  92. package/dist/esm/data/transformers/season-match.js +13 -0
  93. package/dist/esm/data/transformers/season.d.ts +5 -0
  94. package/dist/esm/data/transformers/season.js +39 -0
  95. package/dist/esm/data/transformers/set-position.d.ts +5 -0
  96. package/dist/esm/data/transformers/set-position.js +16 -0
  97. package/dist/esm/data/transformers/stage.d.ts +5 -0
  98. package/dist/esm/data/transformers/stage.js +21 -0
  99. package/dist/esm/data/transformers/team.d.ts +5 -0
  100. package/dist/esm/data/transformers/team.js +28 -0
  101. package/dist/esm/data/transformers/tournament-match.d.ts +5 -0
  102. package/dist/esm/data/transformers/tournament-match.js +19 -0
  103. package/dist/esm/data/transformers/tournament.d.ts +5 -0
  104. package/dist/esm/data/transformers/tournament.js +33 -0
  105. package/dist/esm/data/transformers/trait.d.ts +5 -0
  106. package/dist/esm/data/transformers/trait.js +15 -0
  107. package/dist/esm/index.d.ts +2 -0
  108. package/dist/esm/index.js +2 -0
  109. package/dist/esm/service/coach/coach.d.ts +19 -0
  110. package/dist/esm/service/coach/coach.js +11 -0
  111. package/dist/esm/service/coach/formation.d.ts +31 -0
  112. package/dist/esm/service/coach/formation.js +122 -0
  113. package/dist/esm/service/coach/index.d.ts +2 -0
  114. package/dist/esm/service/coach/index.js +2 -0
  115. package/dist/esm/service/competition/index.d.ts +11 -0
  116. package/dist/esm/service/competition/index.js +12 -0
  117. package/dist/esm/service/competition/iteration.d.ts +10 -0
  118. package/dist/esm/service/competition/iteration.js +8 -0
  119. package/dist/esm/service/competition/league.d.ts +16 -0
  120. package/dist/esm/service/competition/league.js +8 -0
  121. package/dist/esm/service/competition/season.d.ts +23 -0
  122. package/dist/esm/service/competition/season.js +27 -0
  123. package/dist/esm/service/competition/stage.d.ts +11 -0
  124. package/dist/esm/service/competition/stage.js +24 -0
  125. package/dist/esm/service/competition/standing.d.ts +28 -0
  126. package/dist/esm/service/competition/standing.js +76 -0
  127. package/dist/esm/service/competition/tournament-match.d.ts +14 -0
  128. package/dist/esm/service/competition/tournament-match.js +9 -0
  129. package/dist/esm/service/competition/tournament.d.ts +20 -0
  130. package/dist/esm/service/competition/tournament.js +18 -0
  131. package/dist/esm/service/country/country.d.ts +17 -0
  132. package/dist/esm/service/country/country.js +18 -0
  133. package/dist/esm/service/country/index.d.ts +1 -0
  134. package/dist/esm/service/country/index.js +1 -0
  135. package/dist/esm/service/draft/draft-pick.d.ts +14 -0
  136. package/dist/esm/service/draft/draft-pick.js +7 -0
  137. package/dist/esm/service/draft/draft.d.ts +15 -0
  138. package/dist/esm/service/draft/draft.js +8 -0
  139. package/dist/esm/service/draft/index.d.ts +2 -0
  140. package/dist/esm/service/draft/index.js +2 -0
  141. package/dist/esm/service/event/index.d.ts +1 -0
  142. package/dist/esm/service/event/index.js +1 -0
  143. package/dist/esm/service/event/rally-event.d.ts +20 -0
  144. package/dist/esm/service/event/rally-event.js +16 -0
  145. package/dist/esm/service/index.d.ts +9 -0
  146. package/dist/esm/service/index.js +9 -0
  147. package/dist/esm/service/match/court-position.d.ts +21 -0
  148. package/dist/esm/service/match/court-position.js +53 -0
  149. package/dist/esm/service/match/court-target-enum.d.ts +21 -0
  150. package/dist/esm/service/match/court-target-enum.js +54 -0
  151. package/dist/esm/service/match/index.d.ts +7 -0
  152. package/dist/esm/service/match/index.js +7 -0
  153. package/dist/esm/service/match/match-rating.d.ts +35 -0
  154. package/dist/esm/service/match/match-rating.js +61 -0
  155. package/dist/esm/service/match/match-set.d.ts +65 -0
  156. package/dist/esm/service/match/match-set.js +56 -0
  157. package/dist/esm/service/match/match-team.d.ts +7 -0
  158. package/dist/esm/service/match/match-team.js +17 -0
  159. package/dist/esm/service/match/match.d.ts +36 -0
  160. package/dist/esm/service/match/match.js +57 -0
  161. package/dist/esm/service/match/rally.d.ts +22 -0
  162. package/dist/esm/service/match/rally.js +13 -0
  163. package/dist/esm/service/player/index.d.ts +5 -0
  164. package/dist/esm/service/player/index.js +5 -0
  165. package/dist/esm/service/player/performance-stats.d.ts +30 -0
  166. package/dist/esm/service/player/performance-stats.js +34 -0
  167. package/dist/esm/service/player/player.d.ts +46 -0
  168. package/dist/esm/service/player/player.js +84 -0
  169. package/dist/esm/service/player/role.d.ts +17 -0
  170. package/dist/esm/service/player/role.js +42 -0
  171. package/dist/esm/service/player/stats.d.ts +11 -0
  172. package/dist/esm/service/player/stats.js +25 -0
  173. package/dist/esm/service/player/trait.d.ts +21 -0
  174. package/dist/esm/service/player/trait.js +108 -0
  175. package/dist/esm/service/team/index.d.ts +1 -0
  176. package/dist/esm/service/team/index.js +1 -0
  177. package/dist/esm/service/team/team.d.ts +31 -0
  178. package/dist/esm/service/team/team.js +32 -0
  179. package/dist/esm/service/utils/index.d.ts +2 -0
  180. package/dist/esm/service/utils/index.js +2 -0
  181. package/dist/esm/service/utils/object-utils.d.ts +1 -0
  182. package/dist/esm/service/utils/object-utils.js +1 -0
  183. package/dist/esm/service/utils/string-utils.d.ts +2 -0
  184. package/dist/esm/service/utils/string-utils.js +11 -0
  185. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ import { validateUUID } from '../utils';
2
+ import { MatchTeam } from './match-team';
3
+ export var MatchScore;
4
+ (function (MatchScore) {
5
+ MatchScore["3-0"] = "3-0";
6
+ MatchScore["3-1"] = "3-1";
7
+ MatchScore["3-2"] = "3-2";
8
+ MatchScore["2-3"] = "2-3";
9
+ MatchScore["1-3"] = "1-3";
10
+ MatchScore["0-3"] = "0-3";
11
+ })(MatchScore || (MatchScore = {}));
12
+ export class Match {
13
+ constructor({ id, homeTeam, awayTeam, scheduledDate, sets, isSimulated }) {
14
+ validateUUID(id);
15
+ this.id = id;
16
+ this.homeTeam = homeTeam;
17
+ this.awayTeam = awayTeam;
18
+ this.scheduledDate = scheduledDate;
19
+ this.sets = sets;
20
+ this.isSimulated = isSimulated;
21
+ }
22
+ addSet(set) {
23
+ if (this.sets.length >= Match.BEST_OF)
24
+ throw new Error('SET_AMOUNT_EXCEEDED');
25
+ this.sets.push(set);
26
+ }
27
+ getTeamSets(team) {
28
+ return this.sets.reduce((sets, set) => sets + (!set.isOver() ? 0 : set.getWinner() === team ? 1 : 0), 0);
29
+ }
30
+ getScore() {
31
+ return `${this.getTeamSets(MatchTeam.HOME)}-${this.getTeamSets(MatchTeam.AWAY)}`;
32
+ }
33
+ isOver() {
34
+ const gamesRequired = Math.ceil(Match.BEST_OF / 2);
35
+ const lastSet = this.sets.at(-1);
36
+ if (lastSet == null || !lastSet.isOver() || this.sets.length < gamesRequired)
37
+ return false;
38
+ const homeSets = this.getTeamSets(MatchTeam.HOME);
39
+ const awaySets = this.getTeamSets(MatchTeam.AWAY);
40
+ // Check if any of the teams has enough sets to win.
41
+ return !(homeSets < gamesRequired && awaySets < gamesRequired);
42
+ }
43
+ getWinner() {
44
+ if (!this.isOver())
45
+ throw new Error('UNFINISHED_MATCH');
46
+ const homeSets = this.getTeamSets(MatchTeam.HOME);
47
+ const awaySets = this.getTeamSets(MatchTeam.AWAY);
48
+ return homeSets > awaySets ? this.homeTeam : this.awayTeam;
49
+ }
50
+ isWinner(team) {
51
+ if (team === MatchTeam.HOME && this.getWinner() === this.homeTeam)
52
+ return true;
53
+ else
54
+ return team === MatchTeam.AWAY && this.getWinner() === this.awayTeam;
55
+ }
56
+ }
57
+ Match.BEST_OF = 5;
@@ -0,0 +1,22 @@
1
+ import { Team } from '../team';
2
+ import { CourtPosition } from './court-position';
3
+ import { RallyEvent } from '../event';
4
+ interface RallyParams {
5
+ readonly id: string;
6
+ readonly order: number;
7
+ readonly servingTeam: Team;
8
+ readonly events: RallyEvent[];
9
+ }
10
+ export interface PlayerPosition {
11
+ position: CourtPosition;
12
+ playerId: string;
13
+ }
14
+ export declare class Rally {
15
+ readonly id: string;
16
+ readonly servingTeam: Team;
17
+ readonly events: RallyEvent[];
18
+ readonly order: number;
19
+ constructor({ id, order, servingTeam, events }: RallyParams);
20
+ addEvent(event: RallyEvent): void;
21
+ }
22
+ export {};
@@ -0,0 +1,13 @@
1
+ import { validateUUID } from '../utils';
2
+ export class Rally {
3
+ constructor({ id, order, servingTeam, events }) {
4
+ validateUUID(id);
5
+ this.id = id;
6
+ this.order = order;
7
+ this.servingTeam = servingTeam;
8
+ this.events = events;
9
+ }
10
+ addEvent(event) {
11
+ this.events.push(event);
12
+ }
13
+ }
@@ -0,0 +1,5 @@
1
+ export * from './player';
2
+ export * from './performance-stats';
3
+ export * from './role';
4
+ export * from './trait';
5
+ export * from './stats';
@@ -0,0 +1,5 @@
1
+ export * from './player';
2
+ export * from './performance-stats';
3
+ export * from './role';
4
+ export * from './trait';
5
+ export * from './stats';
@@ -0,0 +1,30 @@
1
+ interface PerformanceStatsParams {
2
+ readonly setting: number;
3
+ readonly pass: number;
4
+ readonly reception: number;
5
+ readonly spike: number;
6
+ readonly backAttack: number;
7
+ readonly jump: number;
8
+ readonly block: number;
9
+ readonly awareness: number;
10
+ readonly serve: number;
11
+ readonly defense: number;
12
+ readonly stamina: number;
13
+ }
14
+ export declare class PerformanceStats {
15
+ readonly setting: number;
16
+ readonly pass: number;
17
+ readonly reception: number;
18
+ readonly spike: number;
19
+ readonly backAttack: number;
20
+ readonly jump: number;
21
+ readonly block: number;
22
+ readonly awareness: number;
23
+ readonly serve: number;
24
+ readonly defense: number;
25
+ readonly stamina: number;
26
+ constructor(opts: PerformanceStatsParams);
27
+ toString(): string;
28
+ static fromAverage(average: number): PerformanceStats;
29
+ }
30
+ export {};
@@ -0,0 +1,34 @@
1
+ import { getKeys } from '../utils';
2
+ export class PerformanceStats {
3
+ constructor(opts) {
4
+ this.serve = opts.serve;
5
+ this.pass = opts.pass;
6
+ this.setting = opts.setting;
7
+ this.reception = opts.reception;
8
+ this.spike = opts.spike;
9
+ this.backAttack = opts.backAttack;
10
+ this.jump = opts.jump;
11
+ this.block = opts.block;
12
+ this.awareness = opts.awareness;
13
+ this.defense = opts.defense;
14
+ this.stamina = opts.stamina;
15
+ }
16
+ toString() {
17
+ return getKeys(this).map(key => `${key}: ${this[key]}`).join(', ');
18
+ }
19
+ static fromAverage(average) {
20
+ return new PerformanceStats({
21
+ setting: average,
22
+ pass: average,
23
+ reception: average,
24
+ spike: average,
25
+ backAttack: average,
26
+ jump: average,
27
+ block: average,
28
+ awareness: average,
29
+ serve: average,
30
+ defense: average,
31
+ stamina: average
32
+ });
33
+ }
34
+ }
@@ -0,0 +1,46 @@
1
+ import { PerformanceStats } from './performance-stats';
2
+ import { Role } from './role';
3
+ import { Trait } from './trait';
4
+ import { Country } from '../country';
5
+ import { GeneralStat } from './stats';
6
+ export declare class Stat {
7
+ readonly name: GeneralStat;
8
+ readonly value: number;
9
+ constructor({ name, value }: {
10
+ name: GeneralStat;
11
+ value: number;
12
+ });
13
+ toString(): string;
14
+ }
15
+ interface PlayerParams {
16
+ readonly id: string;
17
+ readonly name: Name;
18
+ readonly country: Country;
19
+ readonly stats: PerformanceStats;
20
+ readonly roles: Role[];
21
+ readonly traits: Trait[];
22
+ }
23
+ export declare class Name {
24
+ readonly first: string;
25
+ readonly last: string;
26
+ constructor({ first, last }: {
27
+ first: string;
28
+ last: string;
29
+ });
30
+ toString(): string;
31
+ }
32
+ export declare class Player {
33
+ readonly id: string;
34
+ readonly name: Name;
35
+ readonly country: Country;
36
+ readonly stats: PerformanceStats;
37
+ readonly roles: Role[];
38
+ readonly traits: Trait[];
39
+ readonly generalStats: Stat[];
40
+ constructor({ id, name, country, stats, roles, traits }: PlayerParams);
41
+ static sortPlayers(roles: Role[]): (p1: Player, p2: Player) => number;
42
+ static compareStats(p1: Player, p2: Player): number;
43
+ canPlayLibero(): boolean;
44
+ toString(): string;
45
+ }
46
+ export {};
@@ -0,0 +1,84 @@
1
+ import { Role } from './role';
2
+ import { validateUUID } from '../utils';
3
+ import { GeneralStat } from './stats';
4
+ export class Stat {
5
+ constructor({ name, value }) {
6
+ this.name = name;
7
+ this.value = value;
8
+ }
9
+ toString() {
10
+ return `${this.name}: ${this.value}`;
11
+ }
12
+ }
13
+ export class Name {
14
+ constructor({ first, last }) {
15
+ this.first = first;
16
+ this.last = last;
17
+ }
18
+ toString() {
19
+ return `${this.first} ${this.last}`;
20
+ }
21
+ }
22
+ export class Player {
23
+ constructor({ id, name, country, stats, roles, traits }) {
24
+ validateUUID(id);
25
+ this.id = id;
26
+ this.name = name;
27
+ this.country = country;
28
+ this.stats = stats;
29
+ this.roles = roles;
30
+ this.traits = traits;
31
+ this.generalStats = GeneralStat.getStats()
32
+ .map(stat => ({
33
+ name: stat,
34
+ value: GeneralStat.calculateScore(stats, stat)
35
+ }));
36
+ }
37
+ // Used as a base sorting function for players
38
+ static sortPlayers(roles) {
39
+ return (p1, p2) => roles.reduce((x, role) => {
40
+ const p2Score = Role.calculateScore(p2.stats, role);
41
+ const p1Score = Role.calculateScore(p1.stats, role);
42
+ return x + p2Score - p1Score;
43
+ }, 0);
44
+ }
45
+ static compareStats(p1, p2) {
46
+ const compareFn = (acc, current) => {
47
+ let x = current.value;
48
+ switch (current.name) {
49
+ case GeneralStat.ATTACK:
50
+ x *= 0.35;
51
+ break;
52
+ case GeneralStat.DEFENSE:
53
+ x *= 0.35;
54
+ break;
55
+ case GeneralStat.SERVE:
56
+ x *= 0.2;
57
+ break;
58
+ case GeneralStat.PHYSICAL:
59
+ x *= 0.1;
60
+ break;
61
+ default:
62
+ x *= 0;
63
+ }
64
+ return acc + x;
65
+ };
66
+ const s1 = p1.generalStats.reduce(compareFn, 0);
67
+ const s2 = p2.generalStats.reduce(compareFn, 0);
68
+ return s2 - s1;
69
+ }
70
+ canPlayLibero() {
71
+ return this.roles.includes(Role.LIBERO);
72
+ }
73
+ toString() {
74
+ return JSON.stringify({
75
+ id: this.id,
76
+ name: this.name.toString(),
77
+ country: this.country.toString(),
78
+ stats: this.stats.toString(),
79
+ roles: `[${this.roles.map(r => r.toString()).join(',')}]`,
80
+ traits: `[${this.traits.map(r => r.toString()).join(',')}]`,
81
+ generalStats: `[${this.generalStats.map(r => r.toString()).join(',')}]`
82
+ });
83
+ }
84
+ }
@@ -0,0 +1,17 @@
1
+ import { PerformanceStats } from './performance-stats';
2
+ import { RoleType } from '../../data';
3
+ export declare class Role {
4
+ static readonly SETTER: Role;
5
+ static readonly LIBERO: Role;
6
+ static readonly OUTSIDE_HITTER: Role;
7
+ static readonly OPPOSITE_HITTER: Role;
8
+ static readonly MIDDLE_BLOCKER: Role;
9
+ static readonly DEFENSIVE_SPECIALIST: Role;
10
+ private static readonly ROLES;
11
+ readonly name: RoleType;
12
+ private constructor();
13
+ toString(): string;
14
+ static getRoles(): Role[];
15
+ static calculateScore(stats: PerformanceStats, role: Role): number;
16
+ static assignRoles(stats: PerformanceStats): Role[];
17
+ }
@@ -0,0 +1,42 @@
1
+ import roleWeights from '../../../data/role.formula.json';
2
+ export class Role {
3
+ constructor(name) {
4
+ this.name = name;
5
+ }
6
+ toString() {
7
+ return this.name;
8
+ }
9
+ static getRoles() {
10
+ return [...Role.ROLES];
11
+ }
12
+ static calculateScore(stats, role) {
13
+ const weights = roleWeights.find(r => r.role === role.name);
14
+ if (weights == null)
15
+ throw new Error('COULD_NOT_FIND_ROLE_WEIGHT');
16
+ const score = Object.entries(weights.weight)
17
+ .reduce((score, [key, value]) => score + (stats[key] * weights.weight[key]), 0);
18
+ return Math.round(score);
19
+ }
20
+ static assignRoles(stats) {
21
+ const scores = this.getRoles().map(role => ({
22
+ role,
23
+ score: this.calculateScore(stats, role)
24
+ })).sort((x, y) => y.score - x.score);
25
+ const out = [scores[0].role];
26
+ if (scores[1].score >= 75) {
27
+ out.push(scores[1].role);
28
+ }
29
+ if (scores[2].score >= 85) {
30
+ out.push(scores[2].role);
31
+ }
32
+ return out;
33
+ }
34
+ }
35
+ Role.SETTER = new Role('SETTER');
36
+ Role.LIBERO = new Role('LIBERO');
37
+ Role.OUTSIDE_HITTER = new Role('OUTSIDE_HITTER');
38
+ Role.OPPOSITE_HITTER = new Role('OPPOSITE_HITTER');
39
+ Role.MIDDLE_BLOCKER = new Role('MIDDLE_BLOCKER');
40
+ Role.DEFENSIVE_SPECIALIST = new Role('DEFENSIVE_SPECIALIST');
41
+ Role.ROLES = [Role.LIBERO, Role.SETTER, Role.OPPOSITE_HITTER, Role.OUTSIDE_HITTER, Role.MIDDLE_BLOCKER,
42
+ Role.DEFENSIVE_SPECIALIST];
@@ -0,0 +1,11 @@
1
+ import { PerformanceStats } from './performance-stats';
2
+ export declare enum GeneralStat {
3
+ ATTACK = "ATTACK",
4
+ DEFENSE = "DEFENSE",
5
+ SERVE = "SERVE",
6
+ PHYSICAL = "PHYSICAL"
7
+ }
8
+ export declare namespace GeneralStat {
9
+ function getStats(): GeneralStat[];
10
+ function calculateScore(performanceStats: PerformanceStats, statName: GeneralStat): number;
11
+ }
@@ -0,0 +1,25 @@
1
+ import stats from '../../../data/stat.formula.json';
2
+ export var GeneralStat;
3
+ (function (GeneralStat) {
4
+ GeneralStat["ATTACK"] = "ATTACK";
5
+ GeneralStat["DEFENSE"] = "DEFENSE";
6
+ GeneralStat["SERVE"] = "SERVE";
7
+ GeneralStat["PHYSICAL"] = "PHYSICAL";
8
+ })(GeneralStat || (GeneralStat = {}));
9
+ // eslint-disable-next-line @typescript-eslint/no-namespace
10
+ (function (GeneralStat) {
11
+ const STATS = [GeneralStat.ATTACK, GeneralStat.DEFENSE, GeneralStat.SERVE, GeneralStat.PHYSICAL];
12
+ function getStats() {
13
+ return [...STATS];
14
+ }
15
+ GeneralStat.getStats = getStats;
16
+ function calculateScore(performanceStats, statName) {
17
+ const weights = stats.find(s => s.statName === statName);
18
+ if (weights == null)
19
+ throw new Error('COULD_NOT_FIND_ROLE_WEIGHT');
20
+ const score = Object.entries(weights.weight)
21
+ .reduce((score, [key, value]) => score + (performanceStats[key] * value), 0);
22
+ return Math.round(score);
23
+ }
24
+ GeneralStat.calculateScore = calculateScore;
25
+ })(GeneralStat || (GeneralStat = {}));
@@ -0,0 +1,21 @@
1
+ import { GeneralStat } from './stats';
2
+ import { PerformanceStats } from './performance-stats';
3
+ export declare class Trait {
4
+ static readonly MASTER_MIND: Trait;
5
+ static readonly MOVING_WALL: Trait;
6
+ static readonly MARKSMAN: Trait;
7
+ static readonly METEOR_SERVE: Trait;
8
+ static readonly VIGOROUS: Trait;
9
+ static readonly GUARDIAN: Trait;
10
+ readonly id: string;
11
+ readonly name: string;
12
+ readonly modifier: number;
13
+ readonly chance: number;
14
+ readonly statThreshold: number;
15
+ readonly stat: GeneralStat;
16
+ readonly weight: number;
17
+ private constructor();
18
+ static getTraits(): Trait[];
19
+ static assignTraits(performanceStats: PerformanceStats): Trait[];
20
+ toString(): string;
21
+ }
@@ -0,0 +1,108 @@
1
+ import { GeneralStat } from './stats';
2
+ export class Trait {
3
+ constructor({ id, name, modifier, chance, statThreshold, stat, weight }) {
4
+ this.id = id;
5
+ this.name = name;
6
+ this.modifier = modifier;
7
+ this.chance = chance;
8
+ this.statThreshold = statThreshold;
9
+ this.stat = stat;
10
+ this.weight = weight;
11
+ }
12
+ static getTraits() {
13
+ return [Trait.GUARDIAN, Trait.MARKSMAN, Trait.METEOR_SERVE, Trait.VIGOROUS, Trait.MOVING_WALL, Trait.MASTER_MIND];
14
+ }
15
+ static assignTraits(performanceStats) {
16
+ const qualifiedTraits = this.getTraits().filter(trait => {
17
+ return GeneralStat.calculateScore(performanceStats, trait.stat) >= trait.statThreshold;
18
+ });
19
+ const random = Math.random();
20
+ let traitCount;
21
+ switch (true) {
22
+ case random > 0.95:
23
+ traitCount = 3;
24
+ break;
25
+ case random > 0.85:
26
+ traitCount = 2;
27
+ break;
28
+ case random > 0.6:
29
+ traitCount = 1;
30
+ break;
31
+ default:
32
+ traitCount = 0;
33
+ }
34
+ return qualifiedTraits.sort((t1, t2) => t2.weight - t1.weight)
35
+ .slice(0, traitCount);
36
+ }
37
+ toString() {
38
+ return JSON.stringify({
39
+ name: this.name,
40
+ modifier: this.modifier,
41
+ statThreshold: this.statThreshold,
42
+ chance: this.chance,
43
+ stat: this.stat,
44
+ weight: this.weight
45
+ });
46
+ }
47
+ }
48
+ // A Setter gets a bonus to their score and the receiving attacker gets a bonus as well.
49
+ // Stacks with attacker bonus
50
+ Trait.MASTER_MIND = new Trait({
51
+ id: '0117a315-a743-43e3-9ec2-ad5cf700ef08',
52
+ name: 'Master Mind',
53
+ modifier: 1.1,
54
+ chance: 0.2,
55
+ statThreshold: 80,
56
+ stat: GeneralStat.ATTACK,
57
+ weight: 10
58
+ });
59
+ // Will always participate in blocking regardless of chance and adds
60
+ Trait.MOVING_WALL = new Trait({
61
+ id: '304c53f6-5e7a-44d3-9625-f10d8109421a',
62
+ name: 'Moving Wall',
63
+ modifier: 1.1,
64
+ chance: 1,
65
+ statThreshold: 75,
66
+ stat: GeneralStat.DEFENSE,
67
+ weight: 5
68
+ });
69
+ // On attack, will always pick the worst receiver and adds a 10% to score
70
+ Trait.MARKSMAN = new Trait({
71
+ id: 'ace3458e-69ab-487c-a9c0-d656f705d8dd',
72
+ name: 'Marksman',
73
+ modifier: 1.01,
74
+ chance: 0.3,
75
+ statThreshold: 75,
76
+ stat: GeneralStat.ATTACK,
77
+ weight: 5
78
+ });
79
+ // Increases the score of the serve by 25% when serve type is Jumping.
80
+ Trait.METEOR_SERVE = new Trait({
81
+ id: 'c929a79d-5866-40d6-bbd6-b0b67a929c4c',
82
+ name: 'Meteor Serve',
83
+ modifier: 1.1,
84
+ chance: 0.1,
85
+ statThreshold: 75,
86
+ stat: GeneralStat.SERVE,
87
+ weight: 10
88
+ });
89
+ // Has a 50% chance of taking an action without decreasing energy.
90
+ Trait.VIGOROUS = new Trait({
91
+ id: 'f9599b87-b3b2-49ce-8224-470f6fe6ed64',
92
+ name: 'Vigorous',
93
+ modifier: 1,
94
+ statThreshold: 60,
95
+ chance: 0.5,
96
+ stat: GeneralStat.PHYSICAL,
97
+ weight: 1
98
+ });
99
+ // Takes place of the receiver and increases reception score by 25%, guaranteeing success. Can only trigger in back-row.
100
+ Trait.GUARDIAN = new Trait({
101
+ id: 'c3291953-9256-4559-b5a9-955ccb8f9a6f',
102
+ name: 'Guardian',
103
+ chance: 0.25,
104
+ statThreshold: 75,
105
+ modifier: 1.25,
106
+ stat: GeneralStat.DEFENSE,
107
+ weight: 10
108
+ });
@@ -0,0 +1 @@
1
+ export * from './team';
@@ -0,0 +1 @@
1
+ export * from './team';
@@ -0,0 +1,31 @@
1
+ import { Coach } from '../coach';
2
+ import { Player } from '../player';
3
+ import { Country } from '../country';
4
+ import { League } from '../competition';
5
+ interface TeamParams {
6
+ readonly id: string;
7
+ readonly rating: number;
8
+ readonly name: string;
9
+ readonly shortName: string;
10
+ readonly roster: Player[];
11
+ readonly country?: Country;
12
+ readonly league?: League;
13
+ readonly coach?: Coach;
14
+ }
15
+ export declare class Team {
16
+ readonly id: string;
17
+ readonly roster: Player[];
18
+ readonly name: string;
19
+ readonly shortName: string;
20
+ readonly coach?: Coach;
21
+ readonly league?: League;
22
+ readonly country?: Country;
23
+ private _rating;
24
+ constructor({ id, rating, name, shortName, country, roster, coach, league }: TeamParams);
25
+ get rating(): number;
26
+ set rating(value: number);
27
+ isPlayerInRoster(player: Player): boolean;
28
+ toString(): string;
29
+ updateRating(rankingPoints: number): void;
30
+ }
31
+ export {};
@@ -0,0 +1,32 @@
1
+ import { validateUUID } from '../utils';
2
+ export class Team {
3
+ constructor({ id, rating, name, shortName, country, roster, coach, league }) {
4
+ validateUUID(id);
5
+ this.id = id;
6
+ this._rating = rating;
7
+ this.roster = roster;
8
+ this.coach = coach;
9
+ this.name = name;
10
+ this.shortName = shortName;
11
+ this.country = country;
12
+ this.league = league;
13
+ }
14
+ get rating() {
15
+ return this._rating;
16
+ }
17
+ set rating(value) {
18
+ this._rating = value;
19
+ }
20
+ isPlayerInRoster(player) {
21
+ return this.roster.some(p => p.id === player.id);
22
+ }
23
+ toString() {
24
+ if (this.country == null) {
25
+ throw new Error('UNKNOWN_COUNTRY');
26
+ }
27
+ return `${this.name} [${this.shortName}] (${this.country?.name}) ELO=${this._rating}`;
28
+ }
29
+ updateRating(rankingPoints) {
30
+ this._rating += rankingPoints;
31
+ }
32
+ }
@@ -0,0 +1,2 @@
1
+ export * from './string-utils';
2
+ export * from './object-utils';
@@ -0,0 +1,2 @@
1
+ export * from './string-utils';
2
+ export * from './object-utils';
@@ -0,0 +1 @@
1
+ export declare const getKeys: <T extends object>(obj: T) => (keyof T)[];
@@ -0,0 +1 @@
1
+ export const getKeys = Object.keys;
@@ -0,0 +1,2 @@
1
+ export declare function formatNumber(n: number): string;
2
+ export declare function validateUUID(uuid: string): boolean;
@@ -0,0 +1,11 @@
1
+ export function formatNumber(n) {
2
+ if (n < 0)
3
+ throw new Error('UNEXPECTED_NEGATIVE_NUMBER');
4
+ return n < 10 ? `0${n}` : `${n}`;
5
+ }
6
+ export function validateUUID(uuid) {
7
+ const regex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;
8
+ if (!regex.test(uuid))
9
+ throw new Error('INVALID_UUID');
10
+ return true;
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.139",
3
+ "version": "0.0.140",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",