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,50 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { Serve, ServeFailure, ServeType } from './serve'
|
|
3
|
-
import { player } from '../player/__stubs__'
|
|
4
|
-
import { CourtTarget } from '../match'
|
|
5
|
-
import { EventType } from './rally-event'
|
|
6
|
-
|
|
7
|
-
describe('Serve Test Module', () => {
|
|
8
|
-
let serve: Serve
|
|
9
|
-
let failed: Serve
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
serve = new Serve({
|
|
13
|
-
score: 60,
|
|
14
|
-
id: '622c36dc-f2d2-44b3-a744-667ea53218b7',
|
|
15
|
-
order: 0,
|
|
16
|
-
player: player,
|
|
17
|
-
target: CourtTarget.OPPONENT_RIGHT_BACK,
|
|
18
|
-
failure: ServeFailure.NO_FAILURE,
|
|
19
|
-
type: ServeType.JUMP_TOPSPIN,
|
|
20
|
-
eventType: EventType.SERVE,
|
|
21
|
-
modifier: 1
|
|
22
|
-
})
|
|
23
|
-
failed = new Serve({
|
|
24
|
-
score: 60,
|
|
25
|
-
id: '622c36dc-f2d2-44b3-a744-667ea53218b7',
|
|
26
|
-
order: 0,
|
|
27
|
-
player: player,
|
|
28
|
-
target: CourtTarget.NO_TARGET,
|
|
29
|
-
failure: ServeFailure.NET,
|
|
30
|
-
type: ServeType.UNDERHAND,
|
|
31
|
-
eventType: EventType.SERVE,
|
|
32
|
-
modifier: 1
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
test('Should instantiate object properly', () => {
|
|
37
|
-
expect(serve.target).toBe(CourtTarget.OPPONENT_RIGHT_BACK)
|
|
38
|
-
expect(serve.type).toBe(ServeType.JUMP_TOPSPIN)
|
|
39
|
-
expect(serve.eventType).toBe(EventType.SERVE)
|
|
40
|
-
expect(serve.player.id).toBe(player.id)
|
|
41
|
-
expect(serve.failure).toBe(ServeFailure.NO_FAILURE)
|
|
42
|
-
expect(failed.failure).toBe(ServeFailure.NET)
|
|
43
|
-
expect(serve.modifier).toBe(1)
|
|
44
|
-
})
|
|
45
|
-
// getScore Tests
|
|
46
|
-
test('Should get the correct score for all Serve types', () => {
|
|
47
|
-
expect(Serve.getScore(serve.player.stats, serve.type, 1)).toBe(6)
|
|
48
|
-
expect(Serve.getScore(failed.player.stats, failed.type, 1)).toBe(3)
|
|
49
|
-
})
|
|
50
|
-
})
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { InPlayEvent, InPlayEventOpts } from './in-play-event'
|
|
2
|
-
import { PerformanceStats } from '../player'
|
|
3
|
-
|
|
4
|
-
export enum ServeType {
|
|
5
|
-
UNDERHAND = 0,
|
|
6
|
-
OVERHAND_TOPSPIN = 1,
|
|
7
|
-
OVERHAND_FLOAT = 2,
|
|
8
|
-
JUMP_TOPSPIN = 3,
|
|
9
|
-
JUMP_FLOAT = 4
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export enum ServeFailure {
|
|
13
|
-
NO_FAILURE = 0,
|
|
14
|
-
FAULT = 1,
|
|
15
|
-
MISS = 2,
|
|
16
|
-
NET = 3,
|
|
17
|
-
OUT_OF_BOUNDS = 4
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface ServeOpts extends InPlayEventOpts {
|
|
21
|
-
readonly type: ServeType
|
|
22
|
-
readonly failure: ServeFailure
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export class Serve extends InPlayEvent {
|
|
26
|
-
readonly failure: ServeFailure
|
|
27
|
-
readonly type: ServeType
|
|
28
|
-
|
|
29
|
-
constructor ({ id, order, score, player, target, failure, type, eventType, modifier }: ServeOpts) {
|
|
30
|
-
super({ id, order, score, player, target, eventType, modifier })
|
|
31
|
-
|
|
32
|
-
this.type = type
|
|
33
|
-
this.failure = failure
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
static getScore (stats: PerformanceStats, type: ServeType, modifier: number): number {
|
|
37
|
-
return Serve.calculateScore(stats, 'SERVE', ServeType[type]) * modifier
|
|
38
|
-
}
|
|
39
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { Set, SetFailure, SetType } from './set'
|
|
3
|
-
import { player } from '../player/__stubs__'
|
|
4
|
-
import { CourtTarget } from '../match'
|
|
5
|
-
import { EventType } from './rally-event'
|
|
6
|
-
|
|
7
|
-
describe('Set Test Module', () => {
|
|
8
|
-
let set: Set
|
|
9
|
-
let failed: Set
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
set = new Set({
|
|
13
|
-
score: 60,
|
|
14
|
-
id: '622c36dc-f2d2-44b3-a744-667ea53218b7',
|
|
15
|
-
order: 0,
|
|
16
|
-
player: player,
|
|
17
|
-
target: CourtTarget.OPPONENT_RIGHT_BACK,
|
|
18
|
-
failure: SetFailure.NO_FAILURE,
|
|
19
|
-
type: SetType.OVERHAND,
|
|
20
|
-
eventType: EventType.SET,
|
|
21
|
-
modifier: 1
|
|
22
|
-
})
|
|
23
|
-
failed = new Set({
|
|
24
|
-
score: 60,
|
|
25
|
-
id: '622c36dc-f2d2-44b3-a744-667ea53218b7',
|
|
26
|
-
order: 0,
|
|
27
|
-
player: player,
|
|
28
|
-
target: CourtTarget.NO_TARGET,
|
|
29
|
-
failure: SetFailure.OUT_OF_BOUNDS,
|
|
30
|
-
type: SetType.DUMP,
|
|
31
|
-
eventType: EventType.SET,
|
|
32
|
-
modifier: 1
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
test('Should instantiate object properly', () => {
|
|
37
|
-
expect(set.target).toBe(CourtTarget.OPPONENT_RIGHT_BACK)
|
|
38
|
-
expect(set.type).toBe(SetType.OVERHAND)
|
|
39
|
-
expect(set.eventType).toBe(EventType.SET)
|
|
40
|
-
expect(set.player.id).toBe(player.id)
|
|
41
|
-
expect(set.failure).toBe(SetFailure.NO_FAILURE)
|
|
42
|
-
expect(failed.failure).toBe(SetFailure.OUT_OF_BOUNDS)
|
|
43
|
-
expect(set.modifier).toBe(1)
|
|
44
|
-
})
|
|
45
|
-
// getScore Tests
|
|
46
|
-
test('Should get the correct score for all Set types', () => {
|
|
47
|
-
expect(Set.getScore(set.player.stats, set.type, 1)).toBe(3)
|
|
48
|
-
expect(Set.getScore(failed.player.stats, failed.type, 1)).toBe(6)
|
|
49
|
-
})
|
|
50
|
-
})
|
package/src/service/event/set.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { PerformanceStats } from '../player'
|
|
2
|
-
import { InPlayEvent, InPlayEventOpts } from './in-play-event'
|
|
3
|
-
|
|
4
|
-
export enum SetType {
|
|
5
|
-
OVERHAND = 0,
|
|
6
|
-
UNDERHAND = 1,
|
|
7
|
-
SPIKE = 2,
|
|
8
|
-
DUMP = 3
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export enum SetFailure {
|
|
12
|
-
NO_FAILURE = 0,
|
|
13
|
-
FAULT = 1,
|
|
14
|
-
MISS = 2,
|
|
15
|
-
BAD_PASS = 3,
|
|
16
|
-
OUT_OF_BOUNDS = 4
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface SetOpts extends InPlayEventOpts {
|
|
20
|
-
readonly type: SetType
|
|
21
|
-
readonly failure: SetFailure
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export class Set extends InPlayEvent {
|
|
25
|
-
readonly failure: SetFailure
|
|
26
|
-
readonly type: SetType
|
|
27
|
-
|
|
28
|
-
constructor ({ id, order, score, player, target, failure, type, eventType, modifier }: SetOpts) {
|
|
29
|
-
super({ id, order, score, player, target, eventType, modifier })
|
|
30
|
-
|
|
31
|
-
this.type = type
|
|
32
|
-
this.failure = failure
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
static getScore (stats: PerformanceStats, type: SetType, modifier: number): number {
|
|
36
|
-
return Set.calculateScore(stats, 'SET', SetType[type]) * modifier
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals'
|
|
2
|
-
import { Spike, SpikeFailure, SpikeType } from './spike'
|
|
3
|
-
import { player } from '../player/__stubs__'
|
|
4
|
-
import { CourtTarget } from '../match'
|
|
5
|
-
import { EventType } from './rally-event'
|
|
6
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
7
|
-
|
|
8
|
-
describe('Spike Test Module', () => {
|
|
9
|
-
let spike: Spike
|
|
10
|
-
let failed: Spike
|
|
11
|
-
let backAttack: Spike
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
spike = new Spike({
|
|
15
|
-
id: uuidv4(),
|
|
16
|
-
order: 1,
|
|
17
|
-
player: player,
|
|
18
|
-
target: CourtTarget.OPPONENT_RIGHT_BACK,
|
|
19
|
-
failure: SpikeFailure.NO_FAILURE,
|
|
20
|
-
type: SpikeType.CROSS_SHOT,
|
|
21
|
-
eventType: EventType.SPIKE,
|
|
22
|
-
modifier: 1,
|
|
23
|
-
score: Spike.getScore(player, SpikeType.CROSS_SHOT, 1, false)
|
|
24
|
-
})
|
|
25
|
-
failed = new Spike({
|
|
26
|
-
id: uuidv4(),
|
|
27
|
-
order: 1,
|
|
28
|
-
player: player,
|
|
29
|
-
target: CourtTarget.NO_TARGET,
|
|
30
|
-
failure: SpikeFailure.OUT_OF_BOUNDS,
|
|
31
|
-
type: SpikeType.TIP,
|
|
32
|
-
eventType: EventType.SPIKE,
|
|
33
|
-
modifier: 1,
|
|
34
|
-
score: Spike.getScore(player, SpikeType.TIP, 1, false)
|
|
35
|
-
})
|
|
36
|
-
backAttack = new Spike({
|
|
37
|
-
id: uuidv4(),
|
|
38
|
-
order: 1,
|
|
39
|
-
player: player,
|
|
40
|
-
target: CourtTarget.OPPONENT_RIGHT_BACK,
|
|
41
|
-
failure: SpikeFailure.NO_FAILURE,
|
|
42
|
-
type: SpikeType.CROSS_SHOT,
|
|
43
|
-
eventType: EventType.SPIKE,
|
|
44
|
-
modifier: 1,
|
|
45
|
-
score: Spike.getScore(player, SpikeType.CROSS_SHOT, 1, true)
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('Should instantiate object properly', () => {
|
|
50
|
-
expect(spike.target).toBe(CourtTarget.OPPONENT_RIGHT_BACK)
|
|
51
|
-
expect(spike.type).toBe(SpikeType.CROSS_SHOT)
|
|
52
|
-
expect(spike.eventType).toBe(EventType.SPIKE)
|
|
53
|
-
expect(spike.player.id).toBe(player.id)
|
|
54
|
-
expect(spike.failure).toBe(SpikeFailure.NO_FAILURE)
|
|
55
|
-
expect(failed.failure).toBe(SpikeFailure.OUT_OF_BOUNDS)
|
|
56
|
-
expect(spike.modifier).toBe(1)
|
|
57
|
-
})
|
|
58
|
-
// getScore Tests
|
|
59
|
-
test('Should get the correct score for all Spike types', () => {
|
|
60
|
-
expect(spike.score).toBe(8)
|
|
61
|
-
expect(failed.score).toBe(7)
|
|
62
|
-
expect(backAttack.score).toBe(6.5)
|
|
63
|
-
})
|
|
64
|
-
})
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { InPlayEvent, InPlayEventOpts } from './in-play-event'
|
|
2
|
-
import { Player } from '../player'
|
|
3
|
-
|
|
4
|
-
export enum SpikeType {
|
|
5
|
-
CROSS_SHOT = 0,
|
|
6
|
-
LINE_SHOT = 1,
|
|
7
|
-
TOOL_SHOT = 2,
|
|
8
|
-
TIP = 3,
|
|
9
|
-
DOWN_BALL = 4,
|
|
10
|
-
OVERHAND = 5
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export enum SpikeFailure {
|
|
14
|
-
NO_FAILURE = 0,
|
|
15
|
-
FAULT = 1,
|
|
16
|
-
MISS = 2,
|
|
17
|
-
OUT_OF_BOUNDS = 3,
|
|
18
|
-
NET = 4
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface SpikeOpts extends InPlayEventOpts {
|
|
22
|
-
readonly type: SpikeType
|
|
23
|
-
readonly failure: SpikeFailure
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class Spike extends InPlayEvent {
|
|
27
|
-
readonly failure: SpikeFailure
|
|
28
|
-
readonly type: SpikeType
|
|
29
|
-
|
|
30
|
-
constructor ({ id, order, score, player, target, failure, type, eventType, modifier }: SpikeOpts) {
|
|
31
|
-
super({ id, order, score, player, target, eventType, modifier })
|
|
32
|
-
|
|
33
|
-
this.type = type
|
|
34
|
-
this.failure = failure
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
static getScore (player: Player, type: SpikeType, modifier: number, isBackRow: boolean): number {
|
|
38
|
-
let score: number = Spike.calculateScore(player.stats, 'SPIKE', SpikeType[type])
|
|
39
|
-
|
|
40
|
-
if (![SpikeType.DOWN_BALL, SpikeType.OVERHAND, SpikeType.TIP].includes(type) && isBackRow) {
|
|
41
|
-
score = score * 0.7 + player.stats.backAttack * 0.3
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return score * modifier
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { RallyEvent, RallyEventOpts } from './rally-event'
|
|
2
|
-
import { Player } from '../player'
|
|
3
|
-
|
|
4
|
-
export interface SubstitutionOpts extends RallyEventOpts {
|
|
5
|
-
readonly playerOut: Player
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export class Substitution extends RallyEvent {
|
|
9
|
-
readonly playerOut: Player
|
|
10
|
-
|
|
11
|
-
constructor ({ id, order, playerOut, player, eventType }: SubstitutionOpts) {
|
|
12
|
-
super({ eventType, player, order, id })
|
|
13
|
-
|
|
14
|
-
this.playerOut = playerOut
|
|
15
|
-
}
|
|
16
|
-
}
|
package/src/service/index.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export * from './match'
|
|
2
|
-
export * from './coach'
|
|
3
|
-
export * from './country'
|
|
4
|
-
export * from './team'
|
|
5
|
-
export * from './event/rally-event'
|
|
6
|
-
export * from './event/in-play-event'
|
|
7
|
-
export * from './event/score'
|
|
8
|
-
export * from './event/substitution'
|
|
9
|
-
export * from './event/libero-replacement'
|
|
10
|
-
export * from './event/serve'
|
|
11
|
-
export * from './event/reception'
|
|
12
|
-
export * from './event/set'
|
|
13
|
-
export * from './event/spike'
|
|
14
|
-
export * from './event/block'
|
|
15
|
-
export * from './player'
|
|
16
|
-
export * from './league'
|
|
17
|
-
export * from './utils'
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { Season } from './season'
|
|
2
|
-
import { Country } from '../country'
|
|
3
|
-
import { Team } from '../team'
|
|
4
|
-
import { Match } from '../match'
|
|
5
|
-
import moment, { Moment } from 'moment/moment'
|
|
6
|
-
import { shuffle } from '../utils'
|
|
7
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
8
|
-
|
|
9
|
-
export interface LeagueOpts {
|
|
10
|
-
readonly id: string
|
|
11
|
-
readonly name: string
|
|
12
|
-
readonly country: Country
|
|
13
|
-
readonly seasons: Season[]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class League {
|
|
17
|
-
readonly id: string
|
|
18
|
-
readonly name: string
|
|
19
|
-
readonly seasons: Season[]
|
|
20
|
-
readonly country: Country
|
|
21
|
-
|
|
22
|
-
constructor ({ id, name, country, seasons }: LeagueOpts) {
|
|
23
|
-
this.id = id
|
|
24
|
-
this.name = name
|
|
25
|
-
this.country = country
|
|
26
|
-
this.seasons = seasons
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
newSeason (teams: Team[]): Season {
|
|
30
|
-
const matches: Match[] = League.generateMatches(teams, moment().add(4, 'hour').toDate())
|
|
31
|
-
const season: Season = new Season({
|
|
32
|
-
id: uuidv4(),
|
|
33
|
-
iteration: this.seasons.length,
|
|
34
|
-
teams,
|
|
35
|
-
matches
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
this.seasons.push(season)
|
|
39
|
-
|
|
40
|
-
return season
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
static generateMatches (teams: Team[], baseDate: Date): Match[] {
|
|
44
|
-
const t: Set<string> = new Set(teams.map(x => x.id))
|
|
45
|
-
const date: Moment = moment(baseDate)
|
|
46
|
-
date.startOf('hour')
|
|
47
|
-
|
|
48
|
-
if (t.size !== teams.length) {
|
|
49
|
-
throw new Error('DUPLICATE_TEAMS')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let shuffled: Team[] = shuffle([...teams])
|
|
53
|
-
const l = shuffled.length - 1
|
|
54
|
-
const half = Math.ceil(shuffled.length / 2)
|
|
55
|
-
const matches: Match[] = []
|
|
56
|
-
|
|
57
|
-
// We fix the first team
|
|
58
|
-
let firstTeam: Team = shuffled.shift() as Team
|
|
59
|
-
|
|
60
|
-
if (firstTeam == null) {
|
|
61
|
-
throw new Error('EMPTY_TEAM_ARRAY')
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
let homeRow: Team[]
|
|
65
|
-
let awayRow: Team[]
|
|
66
|
-
|
|
67
|
-
for (let i = 0; i < l; i++) {
|
|
68
|
-
// split array in 2 halves
|
|
69
|
-
const row1: Team[] = shuffled.slice(0, half)
|
|
70
|
-
const row2: Team[] = shuffled.slice(half)
|
|
71
|
-
const scheduledDate = date.add(30, 'minutes').toDate()
|
|
72
|
-
|
|
73
|
-
row2.push(firstTeam)
|
|
74
|
-
|
|
75
|
-
if (i % 2 === 0) {
|
|
76
|
-
homeRow = row1
|
|
77
|
-
awayRow = row2
|
|
78
|
-
} else {
|
|
79
|
-
homeRow = row2
|
|
80
|
-
awayRow = row1
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
for (let j = 0; j < half; j++) {
|
|
84
|
-
matches.push(new Match({
|
|
85
|
-
id: uuidv4(),
|
|
86
|
-
homeTeam: homeRow[j],
|
|
87
|
-
awayTeam: awayRow[j],
|
|
88
|
-
scheduledDate,
|
|
89
|
-
sets: []
|
|
90
|
-
}))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
firstTeam = row2.pop() as Team
|
|
94
|
-
|
|
95
|
-
row1.unshift(row2.shift() as Team)
|
|
96
|
-
row2.push(row1.pop() as Team)
|
|
97
|
-
|
|
98
|
-
shuffled = [...row1, ...row2]
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Generate Inverted matches for home-away pairings
|
|
102
|
-
matches.push(...matches.map(match => new Match({
|
|
103
|
-
id: uuidv4(),
|
|
104
|
-
homeTeam: match.awayTeam,
|
|
105
|
-
awayTeam: match.homeTeam,
|
|
106
|
-
scheduledDate: date.add(30, 'minutes').toDate(),
|
|
107
|
-
sets: []
|
|
108
|
-
})))
|
|
109
|
-
|
|
110
|
-
return matches
|
|
111
|
-
}
|
|
112
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Team } from '../team'
|
|
2
|
-
import { Match } from '../match'
|
|
3
|
-
import { Standing } from './standing'
|
|
4
|
-
|
|
5
|
-
export interface SeasonOpts {
|
|
6
|
-
readonly id: string
|
|
7
|
-
readonly teams: Team[]
|
|
8
|
-
readonly matches: Match[]
|
|
9
|
-
readonly iteration: number
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class Season {
|
|
13
|
-
readonly id: string
|
|
14
|
-
readonly teams: Team[]
|
|
15
|
-
readonly matches: Match[]
|
|
16
|
-
readonly iteration: number
|
|
17
|
-
readonly standings: Standing[]
|
|
18
|
-
|
|
19
|
-
constructor ({ id, iteration, teams, matches }: SeasonOpts) {
|
|
20
|
-
this.id = id
|
|
21
|
-
this.teams = teams
|
|
22
|
-
this.matches = matches
|
|
23
|
-
this.iteration = iteration
|
|
24
|
-
this.standings = this.calculateStandings()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
calculateStandings (): Standing[] {
|
|
28
|
-
return this.teams.map(team => {
|
|
29
|
-
const standing = new Standing({ teamId: team.id })
|
|
30
|
-
|
|
31
|
-
standing.calculateStanding(this.matches)
|
|
32
|
-
|
|
33
|
-
return standing
|
|
34
|
-
}).sort(Standing.sortFn)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get champion (): Team | undefined {
|
|
38
|
-
if (this.matches.every(match => !match.isOver())) return undefined
|
|
39
|
-
return this.teams.find(team => team.id === this.standings[0].teamId)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Match, MatchTeam } from '../match'
|
|
2
|
-
|
|
3
|
-
export interface StandingOpts {
|
|
4
|
-
readonly teamId: string
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export class Standing {
|
|
8
|
-
readonly teamId: string
|
|
9
|
-
won30: number = 0
|
|
10
|
-
won31: number = 0
|
|
11
|
-
won32: number = 0
|
|
12
|
-
lost03: number = 0
|
|
13
|
-
lost13: number = 0
|
|
14
|
-
lost23: number = 0
|
|
15
|
-
pointsWon: number = 0
|
|
16
|
-
pointsLost: number = 0
|
|
17
|
-
points: number = 0
|
|
18
|
-
pointsRatio: number = 0
|
|
19
|
-
setsWon: number = 0
|
|
20
|
-
setsLost: number = 0
|
|
21
|
-
setsRatio: number = 0
|
|
22
|
-
matchesWon: number = 0
|
|
23
|
-
matchesLost: number = 0
|
|
24
|
-
totalMatches: number = 0
|
|
25
|
-
|
|
26
|
-
constructor ({ teamId }: StandingOpts) {
|
|
27
|
-
this.teamId = teamId
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
calculateStanding (matches: Match[]): void {
|
|
31
|
-
matches = matches.filter(match => match.homeTeam.id === this.teamId || match.awayTeam.id === this.teamId)
|
|
32
|
-
.filter(match => match.isOver())
|
|
33
|
-
|
|
34
|
-
let teamSide: MatchTeam
|
|
35
|
-
let otherSide: MatchTeam
|
|
36
|
-
let teamScore: string
|
|
37
|
-
let otherScore: string
|
|
38
|
-
|
|
39
|
-
for (const match of matches) {
|
|
40
|
-
if (this.teamId === match.homeTeam.id) {
|
|
41
|
-
teamSide = MatchTeam.HOME
|
|
42
|
-
otherSide = MatchTeam.AWAY
|
|
43
|
-
} else {
|
|
44
|
-
teamSide = MatchTeam.AWAY
|
|
45
|
-
otherSide = MatchTeam.HOME
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (match.getWinner().id === this.teamId) {
|
|
49
|
-
(this as any)[`won3${match.getTeamSets(otherSide)}`]++
|
|
50
|
-
} else {
|
|
51
|
-
(this as any)[`lost${match.getTeamSets(teamSide)}3`]++
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
teamScore = `${teamSide === MatchTeam.HOME ? 'home' : 'away'}Score`
|
|
55
|
-
otherScore = `${otherSide === MatchTeam.HOME ? 'home' : 'away'}Score`
|
|
56
|
-
|
|
57
|
-
for (const set of match.sets) {
|
|
58
|
-
this.pointsWon += (set as any)[teamScore] as number
|
|
59
|
-
this.pointsLost += (set as any)[otherScore] as number
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.points = (this.won30 + this.won31) * 3 + this.won32 * 2 + this.lost23
|
|
64
|
-
this.pointsRatio = this.pointsWon / this.pointsLost
|
|
65
|
-
this.setsWon = (this.won32 + this.won31 + this.won30) * 3 + this.lost23 * 2 + this.lost13
|
|
66
|
-
this.setsLost = (this.lost03 + this.lost13 + this.lost23) * 3 + this.won32 * 2 + this.won31
|
|
67
|
-
this.setsRatio = this.setsWon / this.setsLost
|
|
68
|
-
this.matchesWon = this.won32 + this.won31 + this.won30
|
|
69
|
-
this.matchesLost = this.lost03 + this.lost13 + this.lost23
|
|
70
|
-
this.totalMatches = this.matchesWon + this.matchesLost
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
static sortFn (standingA: Standing, standingB: Standing): number {
|
|
74
|
-
if (standingB.points > standingA.points) return 1
|
|
75
|
-
else if (standingA.points > standingB.points) return -1
|
|
76
|
-
else if (standingB.setsRatio > standingA.setsRatio) return 1
|
|
77
|
-
else if (standingA.setsRatio > standingB.setsRatio) return -1
|
|
78
|
-
else if (standingB.pointsRatio > standingA.pointsRatio) return 1
|
|
79
|
-
else if (standingA.pointsRatio > standingB.pointsRatio) return -1
|
|
80
|
-
else return 0
|
|
81
|
-
}
|
|
82
|
-
}
|
package/src/service/main.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import weights from '../../data/formula/role.formula.json'
|
|
2
|
-
import events from '../../data/formula/event.formula.json'
|
|
3
|
-
import stats from '../../data/formula/stat.formula.json'
|
|
4
|
-
|
|
5
|
-
export function validateRoleFormulas (): void {
|
|
6
|
-
console.log('---------------------------------------------------')
|
|
7
|
-
console.log('Starting Role-Weight validation process:')
|
|
8
|
-
console.log('---------------------------------------------------')
|
|
9
|
-
|
|
10
|
-
weights.forEach(({ role, weight }) => {
|
|
11
|
-
const val: number = Object.values(weight).reduce((a, b) => a + b, 0)
|
|
12
|
-
console.log(`Weight sum for ${role} is ${val}`)
|
|
13
|
-
if (val !== 1.0 && (Math.abs(1.0 - val) > 0.0001)) throw new Error(`Invalid weight sum for ${role}`)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
console.log('---------------------------------------------------')
|
|
17
|
-
console.log('Role-Weight validation finished successfully!')
|
|
18
|
-
console.log('---------------------------------------------------')
|
|
19
|
-
console.log('Starting Events validation process:')
|
|
20
|
-
console.log('---------------------------------------------------')
|
|
21
|
-
|
|
22
|
-
Object.keys(events).forEach((event) => {
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
Object.entries(events[event]).forEach(([type, formula]: [type: string, formula: any]) => {
|
|
25
|
-
let val: number = 0
|
|
26
|
-
|
|
27
|
-
Object.entries(formula as { [key: string]: number })
|
|
28
|
-
.forEach(([key, value]) => {
|
|
29
|
-
if (key === 'penalty') return
|
|
30
|
-
val += value
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
console.log(`Weight sum for ${event}|${type} is ${val}`)
|
|
34
|
-
if (val !== 1.0 && (Math.abs(1.0 - val) > 0.0001)) throw new Error(`Invalid weight sum for ${event}|${type}: ${val} | ${1.0 - val}`)
|
|
35
|
-
})
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
console.log('---------------------------------------------------')
|
|
39
|
-
console.log('Events validation finished successfully!')
|
|
40
|
-
console.log('---------------------------------------------------')
|
|
41
|
-
console.log('Starting Stat validation process:')
|
|
42
|
-
console.log('---------------------------------------------------')
|
|
43
|
-
|
|
44
|
-
stats.forEach(({ statName, weight }) => {
|
|
45
|
-
const val: number = Object.values(weight).reduce((a, b) => a + b, 0)
|
|
46
|
-
console.log(`Weight sum for ${statName} is ${val}`)
|
|
47
|
-
if (val !== 1.0 && (Math.abs(1.0 - val) > 0.0001)) throw new Error(`Invalid weight sum for ${statName}`)
|
|
48
|
-
})
|
|
49
|
-
console.log('---------------------------------------------------')
|
|
50
|
-
console.log('Stat validation finished successfully!')
|
|
51
|
-
console.log('---------------------------------------------------')
|
|
52
|
-
}
|