volleyballsimtypes 0.0.510 → 0.0.511
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/dist/cjs/src/service/match/rally-metrics.d.ts +1 -0
- package/dist/cjs/src/service/match/rally-metrics.js +3 -1
- package/dist/cjs/src/service/match/rally-metrics.test.js +22 -0
- package/dist/esm/src/service/match/rally-metrics.d.ts +1 -0
- package/dist/esm/src/service/match/rally-metrics.js +4 -2
- package/dist/esm/src/service/match/rally-metrics.test.js +23 -1
- package/package.json +1 -1
|
@@ -14,7 +14,9 @@ function isServiceError(rally) {
|
|
|
14
14
|
// engine scores a second spike as a transition). This counts first-ball kills and the block errors forced
|
|
15
15
|
// on that first attack, and excludes service-error sideouts (no spike) and dig-and-transition rallies (2+).
|
|
16
16
|
function spikeCount(rally) {
|
|
17
|
-
|
|
17
|
+
// An attack is a SPIKE, or a SET whose type is DUMP (the setter attacking on the second ball). Counting the
|
|
18
|
+
// dump matches the report builder's attack test, so a first-ball sideout won on a dump is not dropped.
|
|
19
|
+
return rally.events.reduce((n, e) => (e.eventType === event_1.EventTypeEnum.SPIKE || (e.eventType === event_1.EventTypeEnum.SET && e.type === event_1.SetTypeEnum.DUMP)) ? n + 1 : n, 0);
|
|
18
20
|
}
|
|
19
21
|
// The setter's zone after (rotationIndex - 1) rotations from their start zone, using the engine's own
|
|
20
22
|
// rotatePosition (each rotation moves a player one zone: 2->1, 1->6, ...). null when no setter.
|
|
@@ -90,3 +90,25 @@ describe('computeRallyMetrics() first ball sideout', () => {
|
|
|
90
90
|
expect(fm.total.home.modFbsoPct).toBe(0);
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
|
+
// The positional engine emits a setter DUMP as a SET event (type DUMP), not a SPIKE. A first-ball sideout won
|
|
94
|
+
// on a dump is still a first attack and must count as an FBSO. (Regression: spikeCount used to count only SPIKE.)
|
|
95
|
+
const dumpEv = () => ({ eventType: event_1.EventTypeEnum.SET, type: event_1.SetTypeEnum.DUMP, failure: 0 });
|
|
96
|
+
// serving H, A ; winners A, A (A 2 - H 0). A sides out on rally 0 via a single setter dump (no spike).
|
|
97
|
+
const dumpSet = {
|
|
98
|
+
homePoints: 0,
|
|
99
|
+
awayPoints: 2,
|
|
100
|
+
homeSetterStartZone: null,
|
|
101
|
+
awaySetterStartZone: null,
|
|
102
|
+
rallies: [
|
|
103
|
+
{ servingTeamId: HOME, events: [serveEv(), dumpEv()] }, // A sideout on a dump -> A FBSO
|
|
104
|
+
{ servingTeamId: AWAY, events: [serveEv()] } // A breakpoint (A serving) -> not a reception win
|
|
105
|
+
]
|
|
106
|
+
};
|
|
107
|
+
const dm = (0, rally_metrics_1.computeRallyMetrics)([dumpSet], HOME, AWAY);
|
|
108
|
+
describe('computeRallyMetrics() first ball sideout - setter dump', () => {
|
|
109
|
+
it('counts a first-ball sideout won on a setter dump (SET type DUMP), not just a spike', () => {
|
|
110
|
+
expect(dm.total.away.receptions).toBe(1);
|
|
111
|
+
expect(dm.total.away.fbsoWins).toBe(1);
|
|
112
|
+
expect(dm.total.away.fbsoPct).toBeCloseTo(100, 5);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventTypeEnum } from '../event';
|
|
1
|
+
import { EventTypeEnum, SetTypeEnum } from '../event';
|
|
2
2
|
import { rotatePosition } from './court-position';
|
|
3
3
|
function newAcc() {
|
|
4
4
|
return { serves: 0, breakpointWins: 0, receptions: 0, sideoutWins: 0, serviceErrorsReceived: 0, fbsoWins: 0, rotations: new Map() };
|
|
@@ -11,7 +11,9 @@ function isServiceError(rally) {
|
|
|
11
11
|
// engine scores a second spike as a transition). This counts first-ball kills and the block errors forced
|
|
12
12
|
// on that first attack, and excludes service-error sideouts (no spike) and dig-and-transition rallies (2+).
|
|
13
13
|
function spikeCount(rally) {
|
|
14
|
-
|
|
14
|
+
// An attack is a SPIKE, or a SET whose type is DUMP (the setter attacking on the second ball). Counting the
|
|
15
|
+
// dump matches the report builder's attack test, so a first-ball sideout won on a dump is not dropped.
|
|
16
|
+
return rally.events.reduce((n, e) => (e.eventType === EventTypeEnum.SPIKE || (e.eventType === EventTypeEnum.SET && e.type === SetTypeEnum.DUMP)) ? n + 1 : n, 0);
|
|
15
17
|
}
|
|
16
18
|
// The setter's zone after (rotationIndex - 1) rotations from their start zone, using the engine's own
|
|
17
19
|
// rotatePosition (each rotation moves a player one zone: 2->1, 1->6, ...). null when no setter.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computeRallyMetrics } from './rally-metrics';
|
|
2
|
-
import { EventTypeEnum } from '../event';
|
|
2
|
+
import { EventTypeEnum, SetTypeEnum } from '../event';
|
|
3
3
|
const serve = (failure = 0) => ({
|
|
4
4
|
events: [{ eventType: EventTypeEnum.SERVE, failure }]
|
|
5
5
|
});
|
|
@@ -88,3 +88,25 @@ describe('computeRallyMetrics() first ball sideout', () => {
|
|
|
88
88
|
expect(fm.total.home.modFbsoPct).toBe(0);
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
|
+
// The positional engine emits a setter DUMP as a SET event (type DUMP), not a SPIKE. A first-ball sideout won
|
|
92
|
+
// on a dump is still a first attack and must count as an FBSO. (Regression: spikeCount used to count only SPIKE.)
|
|
93
|
+
const dumpEv = () => ({ eventType: EventTypeEnum.SET, type: SetTypeEnum.DUMP, failure: 0 });
|
|
94
|
+
// serving H, A ; winners A, A (A 2 - H 0). A sides out on rally 0 via a single setter dump (no spike).
|
|
95
|
+
const dumpSet = {
|
|
96
|
+
homePoints: 0,
|
|
97
|
+
awayPoints: 2,
|
|
98
|
+
homeSetterStartZone: null,
|
|
99
|
+
awaySetterStartZone: null,
|
|
100
|
+
rallies: [
|
|
101
|
+
{ servingTeamId: HOME, events: [serveEv(), dumpEv()] }, // A sideout on a dump -> A FBSO
|
|
102
|
+
{ servingTeamId: AWAY, events: [serveEv()] } // A breakpoint (A serving) -> not a reception win
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
const dm = computeRallyMetrics([dumpSet], HOME, AWAY);
|
|
106
|
+
describe('computeRallyMetrics() first ball sideout - setter dump', () => {
|
|
107
|
+
it('counts a first-ball sideout won on a setter dump (SET type DUMP), not just a spike', () => {
|
|
108
|
+
expect(dm.total.away.receptions).toBe(1);
|
|
109
|
+
expect(dm.total.away.fbsoWins).toBe(1);
|
|
110
|
+
expect(dm.total.away.fbsoPct).toBeCloseTo(100, 5);
|
|
111
|
+
});
|
|
112
|
+
});
|