volleyballsimtypes 0.0.7 → 0.0.8
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.
- package/package.json +5 -5
- package/src/data/index.ts +0 -2
- package/src/data/models/block.ts +0 -159
- package/src/data/models/coach.ts +0 -94
- package/src/data/models/country.ts +0 -105
- package/src/data/models/event.ts +0 -83
- package/src/data/models/index.ts +0 -22
- package/src/data/models/league.ts +0 -90
- package/src/data/models/libero-replacement.ts +0 -104
- package/src/data/models/match-set-stats.ts +0 -204
- package/src/data/models/match-set.ts +0 -152
- package/src/data/models/match.ts +0 -106
- package/src/data/models/performance-stats.ts +0 -136
- package/src/data/models/player.ts +0 -370
- package/src/data/models/rally-position.ts +0 -79
- package/src/data/models/rally.ts +0 -229
- package/src/data/models/reception.ts +0 -113
- package/src/data/models/score.ts +0 -99
- package/src/data/models/season-teams.ts +0 -67
- package/src/data/models/season.ts +0 -103
- package/src/data/models/serve.ts +0 -113
- package/src/data/models/set.ts +0 -113
- package/src/data/models/spike.ts +0 -113
- package/src/data/models/substitution.ts +0 -98
- package/src/data/models/team.ts +0 -193
- package/src/data/transformers/block.ts +0 -117
- package/src/data/transformers/coach.ts +0 -33
- package/src/data/transformers/country.ts +0 -23
- package/src/data/transformers/court-position.ts +0 -43
- package/src/data/transformers/court-target.ts +0 -58
- package/src/data/transformers/event-type.ts +0 -35
- package/src/data/transformers/formation.ts +0 -16
- package/src/data/transformers/index.ts +0 -27
- package/src/data/transformers/league.ts +0 -26
- package/src/data/transformers/libero-replacement.ts +0 -62
- package/src/data/transformers/match-set-stats.ts +0 -101
- package/src/data/transformers/match-set.ts +0 -59
- package/src/data/transformers/match.ts +0 -48
- package/src/data/transformers/performance-stats.ts +0 -40
- package/src/data/transformers/player.ts +0 -109
- package/src/data/transformers/rally-position.ts +0 -24
- package/src/data/transformers/rally.ts +0 -139
- package/src/data/transformers/reception.ts +0 -98
- package/src/data/transformers/role.ts +0 -31
- package/src/data/transformers/score.ts +0 -43
- package/src/data/transformers/season.ts +0 -42
- package/src/data/transformers/serve.ts +0 -100
- package/src/data/transformers/set.ts +0 -98
- package/src/data/transformers/spike.ts +0 -102
- package/src/data/transformers/substitution.ts +0 -42
- package/src/data/transformers/team.ts +0 -45
- package/src/data/transformers/trait.ts +0 -37
- package/src/index.ts +0 -7
- package/src/routing/events.ts +0 -60
- package/src/routing/index.ts +0 -5
- package/src/routing/league.ts +0 -15
- package/src/routing/match.ts +0 -52
- package/src/routing/player.ts +0 -24
- package/src/routing/team.ts +0 -14
- package/src/service/coach/__stubs__/index.ts +0 -46
- package/src/service/coach/coach.test.ts +0 -10
- package/src/service/coach/coach.ts +0 -30
- package/src/service/coach/formation.test.ts +0 -10
- package/src/service/coach/formation.ts +0 -160
- package/src/service/coach/index.ts +0 -2
- package/src/service/country/__stubs__/index.ts +0 -13
- package/src/service/country/country.test.ts +0 -10
- package/src/service/country/country.ts +0 -23
- package/src/service/country/index.ts +0 -1
- package/src/service/event/__stubs__/index.ts +0 -25
- package/src/service/event/block.test.ts +0 -100
- package/src/service/event/block.ts +0 -69
- package/src/service/event/in-play-event.ts +0 -37
- package/src/service/event/libero-replacement.test.ts +0 -37
- package/src/service/event/libero-replacement.ts +0 -25
- package/src/service/event/rally-event.ts +0 -33
- package/src/service/event/reception.test.ts +0 -50
- package/src/service/event/reception.ts +0 -38
- package/src/service/event/score.test.ts +0 -29
- package/src/service/event/score.ts +0 -22
- package/src/service/event/serve.test.ts +0 -50
- package/src/service/event/serve.ts +0 -39
- package/src/service/event/set.test.ts +0 -50
- package/src/service/event/set.ts +0 -38
- package/src/service/event/spike.test.ts +0 -64
- package/src/service/event/spike.ts +0 -46
- package/src/service/event/substitution.ts +0 -16
- package/src/service/index.ts +0 -17
- package/src/service/league/index.ts +0 -3
- package/src/service/league/league.ts +0 -112
- package/src/service/league/season.ts +0 -41
- package/src/service/league/standing.ts +0 -82
- package/src/service/main.ts +0 -52
- package/src/service/match/__stubs__/index.ts +0 -119
- package/src/service/match/court-position.test.ts +0 -73
- package/src/service/match/court-position.ts +0 -46
- package/src/service/match/court-target.test.ts +0 -39
- package/src/service/match/court-target.ts +0 -30
- package/src/service/match/index.ts +0 -6
- package/src/service/match/match-set.test.ts +0 -174
- package/src/service/match/match-set.ts +0 -140
- package/src/service/match/match-team.test.ts +0 -16
- package/src/service/match/match-team.ts +0 -13
- package/src/service/match/match.test.ts +0 -80
- package/src/service/match/match.ts +0 -63
- package/src/service/match/rally.test.ts +0 -94
- package/src/service/match/rally.ts +0 -79
- package/src/service/player/__stubs__/index.ts +0 -1433
- package/src/service/player/index.ts +0 -5
- package/src/service/player/performance-stats.test.ts +0 -24
- package/src/service/player/performance-stats.ts +0 -47
- package/src/service/player/player.test.ts +0 -51
- package/src/service/player/player.ts +0 -101
- package/src/service/player/role.test.ts +0 -29
- package/src/service/player/role.ts +0 -33
- package/src/service/player/stats.test.ts +0 -23
- package/src/service/player/stats.ts +0 -29
- package/src/service/player/trait.test.ts +0 -10
- package/src/service/player/trait.ts +0 -124
- package/src/service/team/__stubs__/index.ts +0 -290
- package/src/service/team/index.ts +0 -1
- package/src/service/team/team.test.ts +0 -30
- package/src/service/team/team.ts +0 -45
- package/src/service/utils/enum-utils.test.ts +0 -10
- package/src/service/utils/enum-utils.ts +0 -6
- package/src/service/utils/index.ts +0 -4
- package/src/service/utils/object-utils.ts +0 -1
- package/src/service/utils/rng-utils.test.ts +0 -32
- package/src/service/utils/rng-utils.ts +0 -41
- package/src/service/utils/string-utils.test.ts +0 -28
- package/src/service/utils/string-utils.ts +0 -13
- package/src/service/utils/testing-utils.ts +0 -2
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { performance } from './__stubs__'
|
|
3
|
-
|
|
4
|
-
describe('PerformanceStats Test Module', () => {
|
|
5
|
-
test('Should instantiate object properly', () => {
|
|
6
|
-
expect(performance.serve).toBe(6)
|
|
7
|
-
expect(performance.setting).toBe(1)
|
|
8
|
-
expect(performance.pass).toBe(11)
|
|
9
|
-
expect(performance.reception).toBe(2)
|
|
10
|
-
expect(performance.spike).toBe(7)
|
|
11
|
-
expect(performance.backAttack).toBe(3)
|
|
12
|
-
expect(performance.jump).toBe(10)
|
|
13
|
-
expect(performance.block).toBe(4)
|
|
14
|
-
expect(performance.awareness).toBe(5)
|
|
15
|
-
expect(performance.defense).toBe(8)
|
|
16
|
-
expect(performance.stamina).toBe(11)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test('Should print all stats properly', () => {
|
|
20
|
-
const expected: string = 'serve: 6, pass: 11, setting: 1, reception: 2, spike: 7, backAttack: 3, jump: 10, block: 4, awareness: 5, defense: 8, stamina: 11'
|
|
21
|
-
|
|
22
|
-
expect(performance.toString()).toBe(expected)
|
|
23
|
-
})
|
|
24
|
-
})
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { getKeys } from '../utils'
|
|
2
|
-
|
|
3
|
-
export interface PerformanceStatsOpts {
|
|
4
|
-
readonly setting: number
|
|
5
|
-
readonly pass: number
|
|
6
|
-
readonly reception: number
|
|
7
|
-
readonly spike: number
|
|
8
|
-
readonly backAttack: number
|
|
9
|
-
readonly jump: number
|
|
10
|
-
readonly block: number
|
|
11
|
-
readonly awareness: number
|
|
12
|
-
readonly serve: number
|
|
13
|
-
readonly defense: number
|
|
14
|
-
readonly stamina: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class PerformanceStats {
|
|
18
|
-
readonly setting: number
|
|
19
|
-
readonly pass: number
|
|
20
|
-
readonly reception: number
|
|
21
|
-
readonly spike: number
|
|
22
|
-
readonly backAttack: number
|
|
23
|
-
readonly jump: number
|
|
24
|
-
readonly block: number
|
|
25
|
-
readonly awareness: number
|
|
26
|
-
readonly serve: number
|
|
27
|
-
readonly defense: number
|
|
28
|
-
readonly stamina: number
|
|
29
|
-
|
|
30
|
-
constructor (opts: PerformanceStatsOpts) {
|
|
31
|
-
this.serve = opts.serve
|
|
32
|
-
this.pass = opts.pass
|
|
33
|
-
this.setting = opts.setting
|
|
34
|
-
this.reception = opts.reception
|
|
35
|
-
this.spike = opts.spike
|
|
36
|
-
this.backAttack = opts.backAttack
|
|
37
|
-
this.jump = opts.jump
|
|
38
|
-
this.block = opts.block
|
|
39
|
-
this.awareness = opts.awareness
|
|
40
|
-
this.defense = opts.defense
|
|
41
|
-
this.stamina = opts.stamina
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
toString (): string {
|
|
45
|
-
return getKeys(this).map(key => `${key as string}: ${this[key] as number}`).join(', ')
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { Player } from './player'
|
|
3
|
-
import { Role } from './role'
|
|
4
|
-
import { libero, player, players } from './__stubs__'
|
|
5
|
-
import { country } from '../country/__stubs__'
|
|
6
|
-
|
|
7
|
-
describe('Player Test Module', () => {
|
|
8
|
-
test('Should instantiate object properly', () => {
|
|
9
|
-
expect(player.id).toBe('622c36dc-f2d2-44b3-a744-667ea53218b7')
|
|
10
|
-
expect(player.roles).toEqual([Role.SETTER, Role.OPPOSITE_HITTER])
|
|
11
|
-
expect(player.name.first).toEqual( 'Francisco')
|
|
12
|
-
expect(player.name.last).toEqual( 'Farias')
|
|
13
|
-
expect(player.stats).toEqual({
|
|
14
|
-
serve: 6,
|
|
15
|
-
setting: 1,
|
|
16
|
-
reception: 2,
|
|
17
|
-
spike: 7,
|
|
18
|
-
backAttack: 3,
|
|
19
|
-
jump: 10,
|
|
20
|
-
block: 4,
|
|
21
|
-
awareness: 5,
|
|
22
|
-
defense: 8,
|
|
23
|
-
stamina: 11,
|
|
24
|
-
pass: 11
|
|
25
|
-
})
|
|
26
|
-
})
|
|
27
|
-
test('Should sort players according to Role Score', () => {
|
|
28
|
-
const sortedArrays = {
|
|
29
|
-
single: [...players].sort(Player.sortPlayers([Role.LIBERO])),
|
|
30
|
-
multiple: [...players].sort(Player.sortPlayers([Role.MIDDLE_BLOCKER, Role.SETTER])),
|
|
31
|
-
all: [...players].sort(Player.sortPlayers(Role.getRoles()))
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const expected = {
|
|
35
|
-
single: [players[2], players[0], players[1]],
|
|
36
|
-
multiple: [players[1], players[2], players[0]],
|
|
37
|
-
all: [players[2], players[1], players[0]]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
expect(sortedArrays.single).toStrictEqual(expected.single)
|
|
41
|
-
expect(sortedArrays.multiple).toStrictEqual(expected.multiple)
|
|
42
|
-
expect(sortedArrays.all).toStrictEqual(expected.all)
|
|
43
|
-
})
|
|
44
|
-
// canPlayLibero Tests
|
|
45
|
-
test('Should return false when player does not have the Libero role', () => {
|
|
46
|
-
expect(player.canPlayLibero()).toBe(false)
|
|
47
|
-
})
|
|
48
|
-
test('Should return true when player has the Libero role', () => {
|
|
49
|
-
expect(libero.canPlayLibero()).toBe(true)
|
|
50
|
-
})
|
|
51
|
-
})
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { PerformanceStats } from './performance-stats'
|
|
2
|
-
import { Role } from './role'
|
|
3
|
-
import { validateUUID } from '../utils'
|
|
4
|
-
import { Trait } from './trait'
|
|
5
|
-
import { Country } from '../country'
|
|
6
|
-
import { GeneralStat } from './stats'
|
|
7
|
-
|
|
8
|
-
export interface Stat {
|
|
9
|
-
name: GeneralStat
|
|
10
|
-
value: number
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface PlayerOpts {
|
|
14
|
-
readonly id: string
|
|
15
|
-
readonly name: Name
|
|
16
|
-
readonly country: Country
|
|
17
|
-
readonly stats: PerformanceStats
|
|
18
|
-
readonly roles: Role[]
|
|
19
|
-
readonly traits: Trait[]
|
|
20
|
-
readonly jerseyNumber: number
|
|
21
|
-
readonly team?: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface Name {
|
|
25
|
-
first: string
|
|
26
|
-
last: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export class Player {
|
|
30
|
-
readonly id: string
|
|
31
|
-
readonly name: Name
|
|
32
|
-
readonly country: Country
|
|
33
|
-
readonly stats: PerformanceStats
|
|
34
|
-
readonly roles: Role[]
|
|
35
|
-
readonly traits: Trait[]
|
|
36
|
-
readonly jerseyNumber: number
|
|
37
|
-
readonly team?: string
|
|
38
|
-
readonly generalStats: Stat[]
|
|
39
|
-
|
|
40
|
-
constructor ({ id, name, country, stats, roles, traits, jerseyNumber, team }: PlayerOpts) {
|
|
41
|
-
validateUUID(id)
|
|
42
|
-
|
|
43
|
-
this.id = id
|
|
44
|
-
this.name = name
|
|
45
|
-
this.country = country
|
|
46
|
-
this.stats = stats
|
|
47
|
-
this.roles = roles
|
|
48
|
-
this.traits = traits
|
|
49
|
-
this.jerseyNumber = jerseyNumber
|
|
50
|
-
this.team = team
|
|
51
|
-
this.generalStats = GeneralStat.getStats()
|
|
52
|
-
.map(stat => ({
|
|
53
|
-
name: stat,
|
|
54
|
-
value: GeneralStat.calculateScore(stats, stat)
|
|
55
|
-
}))
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Used as a base sorting function for players
|
|
59
|
-
public static sortPlayers (roles: Role[]): (p1: Player, p2: Player) => number {
|
|
60
|
-
return (p1: Player, p2: Player) => roles.reduce((x, role) => {
|
|
61
|
-
const p2Score = Role.calculateScore(p2.stats, role)
|
|
62
|
-
const p1Score = Role.calculateScore(p1.stats, role)
|
|
63
|
-
|
|
64
|
-
return x + p2Score - p1Score
|
|
65
|
-
}, 0)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
public canPlayLibero (): boolean {
|
|
69
|
-
return this.roles.includes(Role.LIBERO)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public static compareStats (p1: Player, p2: Player): number {
|
|
73
|
-
const compareFn = (acc: number, current: Stat): number => {
|
|
74
|
-
let x = current.value
|
|
75
|
-
|
|
76
|
-
switch (current.name) {
|
|
77
|
-
case GeneralStat.ATTACK:
|
|
78
|
-
x *= 0.35
|
|
79
|
-
break
|
|
80
|
-
case GeneralStat.DEFENSE:
|
|
81
|
-
x *= 0.35
|
|
82
|
-
break
|
|
83
|
-
case GeneralStat.SERVE:
|
|
84
|
-
x *= 0.2
|
|
85
|
-
break
|
|
86
|
-
case GeneralStat.PHYSICAL:
|
|
87
|
-
x *= 0.1
|
|
88
|
-
break
|
|
89
|
-
default:
|
|
90
|
-
x *= 0
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return acc + x
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const s1: number = p1.generalStats.reduce(compareFn, 0)
|
|
97
|
-
const s2: number = p2.generalStats.reduce(compareFn, 0)
|
|
98
|
-
|
|
99
|
-
return s2 - s1
|
|
100
|
-
}
|
|
101
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { Role } from './role'
|
|
3
|
-
import { performanceStats, roles } from './__stubs__'
|
|
4
|
-
|
|
5
|
-
describe('Role Test Module', () => {
|
|
6
|
-
// getRoles Test
|
|
7
|
-
test('Should return an array with all the Roles', () => {
|
|
8
|
-
expect(Role.getRoles().sort()).toEqual(roles.sort())
|
|
9
|
-
})
|
|
10
|
-
// calculateScore Tests
|
|
11
|
-
test('Should calculate Score for SETTER Role', () => {
|
|
12
|
-
expect(Role.calculateScore(performanceStats, Role.SETTER)).toBe(39)
|
|
13
|
-
})
|
|
14
|
-
test('Should calculate Score for OPPOSITE_HITTER Role', () => {
|
|
15
|
-
expect(Role.calculateScore(performanceStats, Role.OPPOSITE_HITTER)).toBe(50)
|
|
16
|
-
})
|
|
17
|
-
test('Should calculate Score for OUTSIDE_HITTER Role', () => {
|
|
18
|
-
expect(Role.calculateScore(performanceStats, Role.OUTSIDE_HITTER)).toBe(51)
|
|
19
|
-
})
|
|
20
|
-
test('Should calculate Score for MIDDLE_BLOCKER Role', () => {
|
|
21
|
-
expect(Role.calculateScore(performanceStats, Role.MIDDLE_BLOCKER)).toBe(53)
|
|
22
|
-
})
|
|
23
|
-
test('Should calculate Score for LIBERO Role', () => {
|
|
24
|
-
expect(Role.calculateScore(performanceStats, Role.LIBERO)).toBe(52)
|
|
25
|
-
})
|
|
26
|
-
test('Should calculate Score for DEFENSIVE_SPECIALIST Role', () => {
|
|
27
|
-
expect(Role.calculateScore(performanceStats, Role.DEFENSIVE_SPECIALIST)).toBe(53)
|
|
28
|
-
})
|
|
29
|
-
})
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import roleWeights from '../../../data/formula/role.formula.json'
|
|
2
|
-
import { PerformanceStats } from './performance-stats'
|
|
3
|
-
|
|
4
|
-
export enum Role {
|
|
5
|
-
SETTER = 'Setter',
|
|
6
|
-
LIBERO = 'Libero',
|
|
7
|
-
OUTSIDE_HITTER = 'Outside Hitter',
|
|
8
|
-
OPPOSITE_HITTER = 'Opposite Hitter',
|
|
9
|
-
MIDDLE_BLOCKER = 'Middle Blocker',
|
|
10
|
-
DEFENSIVE_SPECIALIST = 'Defensive Specialist'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
14
|
-
export namespace Role {
|
|
15
|
-
const ROLES: Role[] = [Role.LIBERO, Role.SETTER, Role.OPPOSITE_HITTER, Role.OUTSIDE_HITTER, Role.MIDDLE_BLOCKER,
|
|
16
|
-
Role.DEFENSIVE_SPECIALIST]
|
|
17
|
-
|
|
18
|
-
export function getRoles (): Role[] {
|
|
19
|
-
return [...ROLES]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function calculateScore (stats: PerformanceStats, role: Role): number {
|
|
23
|
-
const weights = roleWeights.find(r => r.role === role)
|
|
24
|
-
|
|
25
|
-
if (weights == null) throw new Error('COULD_NOT_FIND_ROLE_WEIGHT')
|
|
26
|
-
|
|
27
|
-
const score = Object.entries(weights.weight)
|
|
28
|
-
.reduce((score, [key, value]) =>
|
|
29
|
-
score + ((stats as any)[key] * (weights.weight as any)[key]), 0)
|
|
30
|
-
|
|
31
|
-
return Math.round(score)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { GeneralStat } from './stats'
|
|
3
|
-
import { performanceStats, stats } from './__stubs__'
|
|
4
|
-
|
|
5
|
-
describe('Stat Test Module', () => {
|
|
6
|
-
// getStats Test
|
|
7
|
-
test('Should return an array with all the Stats', () => {
|
|
8
|
-
expect(GeneralStat.getStats().sort()).toEqual(stats.sort())
|
|
9
|
-
})
|
|
10
|
-
// calculateScore Tests
|
|
11
|
-
test('Should calculate Score for ATTACK Stat', () => {
|
|
12
|
-
expect(GeneralStat.calculateScore(performanceStats, GeneralStat.ATTACK)).toBe(49)
|
|
13
|
-
})
|
|
14
|
-
test('Should calculate Score for DEFENSE Stat', () => {
|
|
15
|
-
expect(GeneralStat.calculateScore(performanceStats, GeneralStat.DEFENSE)).toBe(60)
|
|
16
|
-
})
|
|
17
|
-
test('Should calculate Score for SERVE Stat', () => {
|
|
18
|
-
expect(GeneralStat.calculateScore(performanceStats, GeneralStat.SERVE)).toBe(20)
|
|
19
|
-
})
|
|
20
|
-
test('Should calculate Score for PHYSICAL Stat', () => {
|
|
21
|
-
expect(GeneralStat.calculateScore(performanceStats, GeneralStat.PHYSICAL)).toBe(58)
|
|
22
|
-
})
|
|
23
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import stats from '../../../data/formula/stat.formula.json'
|
|
2
|
-
import { PerformanceStats } from './performance-stats'
|
|
3
|
-
|
|
4
|
-
export enum GeneralStat {
|
|
5
|
-
ATTACK = 'Attack',
|
|
6
|
-
DEFENSE = 'Defense',
|
|
7
|
-
SERVE = 'Serve',
|
|
8
|
-
PHYSICAL = 'Physical'
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
12
|
-
export namespace GeneralStat {
|
|
13
|
-
const STATS: GeneralStat[] = [GeneralStat.ATTACK, GeneralStat.DEFENSE, GeneralStat.SERVE, GeneralStat.PHYSICAL]
|
|
14
|
-
|
|
15
|
-
export function getStats (): GeneralStat[] {
|
|
16
|
-
return [...STATS]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function calculateScore (performanceStats: PerformanceStats, statName: GeneralStat): number {
|
|
20
|
-
const weights = stats.find(s => s.statName === statName)
|
|
21
|
-
|
|
22
|
-
if (weights == null) throw new Error('COULD_NOT_FIND_ROLE_WEIGHT')
|
|
23
|
-
|
|
24
|
-
const score: number = Object.entries(weights.weight)
|
|
25
|
-
.reduce((score, [key, value]) => score + ((performanceStats as any)[key] * value), 0)
|
|
26
|
-
|
|
27
|
-
return Math.round(score)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { Trait } from './trait'
|
|
3
|
-
|
|
4
|
-
// TODO
|
|
5
|
-
describe('Trait Test Module', () => {
|
|
6
|
-
// getTraits Test
|
|
7
|
-
test('Should return an array with all the Traits', () => {
|
|
8
|
-
expect(Trait.VIGOROUS.name).toEqual('Vigorous')
|
|
9
|
-
})
|
|
10
|
-
})
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { Role } from './role'
|
|
2
|
-
import { GeneralStat } from './stats'
|
|
3
|
-
import { PerformanceStats } from './performance-stats'
|
|
4
|
-
|
|
5
|
-
interface TraitProps {
|
|
6
|
-
readonly name: string
|
|
7
|
-
readonly roles: Role[]
|
|
8
|
-
readonly modifier: number
|
|
9
|
-
readonly chance: number
|
|
10
|
-
readonly statThreshold: number
|
|
11
|
-
readonly stat: GeneralStat
|
|
12
|
-
readonly weight: number
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class Trait {
|
|
16
|
-
static readonly MASTER_MIND: Trait = new Trait({
|
|
17
|
-
name: 'Master Mind',
|
|
18
|
-
roles: [Role.SETTER],
|
|
19
|
-
modifier: 1.25,
|
|
20
|
-
chance: 0.15,
|
|
21
|
-
statThreshold: 80,
|
|
22
|
-
stat: GeneralStat.ATTACK,
|
|
23
|
-
weight: 10
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
static readonly MOVING_WALL: Trait = new Trait({
|
|
27
|
-
name: 'Moving Wall',
|
|
28
|
-
roles: [Role.MIDDLE_BLOCKER, Role.DEFENSIVE_SPECIALIST],
|
|
29
|
-
modifier: 1,
|
|
30
|
-
chance: 1,
|
|
31
|
-
statThreshold: 75,
|
|
32
|
-
stat: GeneralStat.DEFENSE,
|
|
33
|
-
weight: 5
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
static readonly MARKSMAN: Trait = new Trait({
|
|
37
|
-
name: 'Marksman',
|
|
38
|
-
roles: [Role.OUTSIDE_HITTER, Role.OPPOSITE_HITTER, Role.SETTER],
|
|
39
|
-
modifier: 1,
|
|
40
|
-
chance: 0.33,
|
|
41
|
-
statThreshold: 75,
|
|
42
|
-
stat: GeneralStat.ATTACK,
|
|
43
|
-
weight: 5
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
static readonly METEOR_SERVE: Trait = new Trait({
|
|
47
|
-
name: 'Meteor Serve',
|
|
48
|
-
roles: [Role.OUTSIDE_HITTER, Role.OPPOSITE_HITTER, Role.SETTER, Role.DEFENSIVE_SPECIALIST, Role.MIDDLE_BLOCKER],
|
|
49
|
-
modifier: 1.33,
|
|
50
|
-
chance: 0.25,
|
|
51
|
-
statThreshold: 75,
|
|
52
|
-
stat: GeneralStat.SERVE,
|
|
53
|
-
weight: 10
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
static readonly VIGOROUS: Trait = new Trait({
|
|
57
|
-
name: 'Vigorous',
|
|
58
|
-
roles: [],
|
|
59
|
-
modifier: 1,
|
|
60
|
-
statThreshold: 60,
|
|
61
|
-
chance: 0.5,
|
|
62
|
-
stat: GeneralStat.PHYSICAL,
|
|
63
|
-
weight: 1
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
static readonly GUARDIAN: Trait = new Trait({
|
|
67
|
-
name: 'Guardian',
|
|
68
|
-
roles: [Role.DEFENSIVE_SPECIALIST, Role.LIBERO],
|
|
69
|
-
chance: 0.33,
|
|
70
|
-
statThreshold: 75,
|
|
71
|
-
modifier: 1.2,
|
|
72
|
-
stat: GeneralStat.DEFENSE,
|
|
73
|
-
weight: 10
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
readonly name: string
|
|
77
|
-
readonly roles: Role[]
|
|
78
|
-
readonly modifier: number
|
|
79
|
-
readonly chance: number
|
|
80
|
-
readonly statThreshold: number
|
|
81
|
-
readonly stat: GeneralStat
|
|
82
|
-
readonly weight: number
|
|
83
|
-
|
|
84
|
-
private constructor ({ name, roles, modifier, chance, statThreshold, stat, weight }: TraitProps) {
|
|
85
|
-
this.name = name
|
|
86
|
-
this.roles = roles
|
|
87
|
-
this.modifier = modifier
|
|
88
|
-
this.chance = chance
|
|
89
|
-
this.statThreshold = statThreshold
|
|
90
|
-
this.stat = stat
|
|
91
|
-
this.weight = weight
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
static getTraits (): Trait[] {
|
|
95
|
-
return [Trait.GUARDIAN, Trait.MARKSMAN, Trait.METEOR_SERVE, Trait.VIGOROUS, Trait.MOVING_WALL, Trait.MASTER_MIND]
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
static assignTraitsToPlayer (roles: Role[], performanceStats: PerformanceStats): Trait[] {
|
|
99
|
-
const qualifiedTraits: Trait[] = this.getTraits().filter(trait => {
|
|
100
|
-
return (trait.roles.length < 1 || trait.roles.some(role => roles.includes(role))) &&
|
|
101
|
-
GeneralStat.calculateScore(performanceStats, trait.stat) >= trait.statThreshold
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
const random: number = Math.random()
|
|
105
|
-
let traitCount: number
|
|
106
|
-
|
|
107
|
-
switch (true) {
|
|
108
|
-
case random > 0.9:
|
|
109
|
-
traitCount = 3
|
|
110
|
-
break
|
|
111
|
-
case random > 0.75:
|
|
112
|
-
traitCount = 2
|
|
113
|
-
break
|
|
114
|
-
case random > 0.4:
|
|
115
|
-
traitCount = 1
|
|
116
|
-
break
|
|
117
|
-
default:
|
|
118
|
-
traitCount = 0
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return qualifiedTraits.sort((t1, t2) => t2.weight - t1.weight)
|
|
122
|
-
.slice(0, traitCount)
|
|
123
|
-
}
|
|
124
|
-
}
|