volleyballsimtypes 0.0.424 → 0.0.425

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.
@@ -16,7 +16,9 @@ export interface RallyMetricsSet {
16
16
  export interface RotationMetrics {
17
17
  setterZone: number | null;
18
18
  rotation: number;
19
+ serves: number;
19
20
  servePoints: number;
21
+ receptions: number;
20
22
  sideoutPoints: number;
21
23
  points: number;
22
24
  }
@@ -26,17 +26,16 @@ function setterZoneAt(startZone, rotationIndex) {
26
26
  zone = (0, court_position_1.rotatePosition)(zone);
27
27
  return zone;
28
28
  }
29
- function addRotationPoint(acc, setterZone, rotation, kind) {
29
+ // Get (or create) a team's rotation bucket, keyed by setter zone when known (so the total sums by zone
30
+ // across sets), else by the rotation index.
31
+ function rotationEntry(acc, setterZone, rotation) {
30
32
  const key = setterZone != null ? `z${setterZone}` : `r${rotation}`;
31
33
  let entry = acc.rotations.get(key);
32
34
  if (entry == null) {
33
- entry = { setterZone, rotation, servePoints: 0, sideoutPoints: 0 };
35
+ entry = { setterZone, rotation, servePoints: 0, sideoutPoints: 0, serves: 0, receptions: 0 };
34
36
  acc.rotations.set(key, entry);
35
37
  }
36
- if (kind === 'serve')
37
- entry.servePoints++;
38
- else
39
- entry.sideoutPoints++;
38
+ return entry;
40
39
  }
41
40
  // Walk one set, folding its rallies into the home/away accumulators (used for both per-set and total).
42
41
  function accumulateSet(set, homeId, awayId, homeAcc, awayAcc) {
@@ -53,24 +52,27 @@ function accumulateSet(set, homeId, awayId, homeAcc, awayAcc) {
53
52
  const winnerId = i < rallies.length - 1 ? rallies[i + 1].servingTeamId : setWinnerId;
54
53
  const serving = accOf(servingId);
55
54
  const receiving = accOf(receivingId);
56
- const winner = accOf(winnerId);
57
- if (serving == null || receiving == null || winner == null)
55
+ if (serving == null || receiving == null || (winnerId !== servingId && winnerId !== receivingId))
58
56
  continue;
59
57
  serving.serves++;
60
58
  receiving.receptions++;
61
59
  if (isServiceError(rallies[i]))
62
60
  receiving.serviceErrorsReceived++;
63
- const rotIdx = rotation[winnerId];
64
- const zone = setterZoneAt(startZone[winnerId], rotIdx);
61
+ // Per-rotation attempts: both teams play this rally in their current rotation. The point below is
62
+ // attributed to the winner, whose bucket is the same serve (breakpoint) or reception (sideout) entry.
63
+ const serveEntry = rotationEntry(serving, setterZoneAt(startZone[servingId], rotation[servingId]), rotation[servingId]);
64
+ const recEntry = rotationEntry(receiving, setterZoneAt(startZone[receivingId], rotation[receivingId]), rotation[receivingId]);
65
+ serveEntry.serves++;
66
+ recEntry.receptions++;
65
67
  if (winnerId === servingId) {
66
68
  serving.breakpointWins++;
67
- addRotationPoint(winner, zone, rotIdx, 'serve');
69
+ serveEntry.servePoints++;
68
70
  }
69
71
  else {
70
72
  receiving.sideoutWins++;
71
73
  if (spikeCount(rallies[i]) === 1)
72
74
  receiving.fbsoWins++;
73
- addRotationPoint(winner, zone, rotIdx, 'sideout');
75
+ recEntry.sideoutPoints++;
74
76
  }
75
77
  // The sideout winner gains serve, so they rotate (after the point is attributed to their old rotation).
76
78
  if (winnerId === receivingId)
@@ -48,12 +48,12 @@ describe('computeRallyMetrics()', () => {
48
48
  it('per-set rotations labeled by setter zone, split serve vs sideout', () => {
49
49
  expect(m.sets).toHaveLength(1);
50
50
  expect(m.sets[0].home.rotations).toEqual([
51
- { setterZone: 1, rotation: 2, servePoints: 1, sideoutPoints: 0, points: 1 },
52
- { setterZone: 2, rotation: 1, servePoints: 1, sideoutPoints: 1, points: 2 }
51
+ { setterZone: 1, rotation: 2, serves: 1, servePoints: 1, receptions: 0, sideoutPoints: 0, points: 1 },
52
+ { setterZone: 2, rotation: 1, serves: 2, servePoints: 1, receptions: 2, sideoutPoints: 1, points: 2 }
53
53
  ]);
54
54
  expect(m.sets[0].away.rotations).toEqual([
55
- { setterZone: 1, rotation: 1, servePoints: 0, sideoutPoints: 1, points: 1 },
56
- { setterZone: 6, rotation: 2, servePoints: 1, sideoutPoints: 0, points: 1 }
55
+ { setterZone: 1, rotation: 1, serves: 0, servePoints: 0, receptions: 2, sideoutPoints: 1, points: 1 },
56
+ { setterZone: 6, rotation: 2, serves: 2, servePoints: 1, receptions: 1, sideoutPoints: 0, points: 1 }
57
57
  ]);
58
58
  });
59
59
  });
@@ -16,7 +16,9 @@ export interface RallyMetricsSet {
16
16
  export interface RotationMetrics {
17
17
  setterZone: number | null;
18
18
  rotation: number;
19
+ serves: number;
19
20
  servePoints: number;
21
+ receptions: number;
20
22
  sideoutPoints: number;
21
23
  points: number;
22
24
  }
@@ -23,17 +23,16 @@ function setterZoneAt(startZone, rotationIndex) {
23
23
  zone = rotatePosition(zone);
24
24
  return zone;
25
25
  }
26
- function addRotationPoint(acc, setterZone, rotation, kind) {
26
+ // Get (or create) a team's rotation bucket, keyed by setter zone when known (so the total sums by zone
27
+ // across sets), else by the rotation index.
28
+ function rotationEntry(acc, setterZone, rotation) {
27
29
  const key = setterZone != null ? `z${setterZone}` : `r${rotation}`;
28
30
  let entry = acc.rotations.get(key);
29
31
  if (entry == null) {
30
- entry = { setterZone, rotation, servePoints: 0, sideoutPoints: 0 };
32
+ entry = { setterZone, rotation, servePoints: 0, sideoutPoints: 0, serves: 0, receptions: 0 };
31
33
  acc.rotations.set(key, entry);
32
34
  }
33
- if (kind === 'serve')
34
- entry.servePoints++;
35
- else
36
- entry.sideoutPoints++;
35
+ return entry;
37
36
  }
38
37
  // Walk one set, folding its rallies into the home/away accumulators (used for both per-set and total).
39
38
  function accumulateSet(set, homeId, awayId, homeAcc, awayAcc) {
@@ -50,24 +49,27 @@ function accumulateSet(set, homeId, awayId, homeAcc, awayAcc) {
50
49
  const winnerId = i < rallies.length - 1 ? rallies[i + 1].servingTeamId : setWinnerId;
51
50
  const serving = accOf(servingId);
52
51
  const receiving = accOf(receivingId);
53
- const winner = accOf(winnerId);
54
- if (serving == null || receiving == null || winner == null)
52
+ if (serving == null || receiving == null || (winnerId !== servingId && winnerId !== receivingId))
55
53
  continue;
56
54
  serving.serves++;
57
55
  receiving.receptions++;
58
56
  if (isServiceError(rallies[i]))
59
57
  receiving.serviceErrorsReceived++;
60
- const rotIdx = rotation[winnerId];
61
- const zone = setterZoneAt(startZone[winnerId], rotIdx);
58
+ // Per-rotation attempts: both teams play this rally in their current rotation. The point below is
59
+ // attributed to the winner, whose bucket is the same serve (breakpoint) or reception (sideout) entry.
60
+ const serveEntry = rotationEntry(serving, setterZoneAt(startZone[servingId], rotation[servingId]), rotation[servingId]);
61
+ const recEntry = rotationEntry(receiving, setterZoneAt(startZone[receivingId], rotation[receivingId]), rotation[receivingId]);
62
+ serveEntry.serves++;
63
+ recEntry.receptions++;
62
64
  if (winnerId === servingId) {
63
65
  serving.breakpointWins++;
64
- addRotationPoint(winner, zone, rotIdx, 'serve');
66
+ serveEntry.servePoints++;
65
67
  }
66
68
  else {
67
69
  receiving.sideoutWins++;
68
70
  if (spikeCount(rallies[i]) === 1)
69
71
  receiving.fbsoWins++;
70
- addRotationPoint(winner, zone, rotIdx, 'sideout');
72
+ recEntry.sideoutPoints++;
71
73
  }
72
74
  // The sideout winner gains serve, so they rotate (after the point is attributed to their old rotation).
73
75
  if (winnerId === receivingId)
@@ -46,12 +46,12 @@ describe('computeRallyMetrics()', () => {
46
46
  it('per-set rotations labeled by setter zone, split serve vs sideout', () => {
47
47
  expect(m.sets).toHaveLength(1);
48
48
  expect(m.sets[0].home.rotations).toEqual([
49
- { setterZone: 1, rotation: 2, servePoints: 1, sideoutPoints: 0, points: 1 },
50
- { setterZone: 2, rotation: 1, servePoints: 1, sideoutPoints: 1, points: 2 }
49
+ { setterZone: 1, rotation: 2, serves: 1, servePoints: 1, receptions: 0, sideoutPoints: 0, points: 1 },
50
+ { setterZone: 2, rotation: 1, serves: 2, servePoints: 1, receptions: 2, sideoutPoints: 1, points: 2 }
51
51
  ]);
52
52
  expect(m.sets[0].away.rotations).toEqual([
53
- { setterZone: 1, rotation: 1, servePoints: 0, sideoutPoints: 1, points: 1 },
54
- { setterZone: 6, rotation: 2, servePoints: 1, sideoutPoints: 0, points: 1 }
53
+ { setterZone: 1, rotation: 1, serves: 0, servePoints: 0, receptions: 2, sideoutPoints: 1, points: 1 },
54
+ { setterZone: 6, rotation: 2, serves: 2, servePoints: 1, receptions: 1, sideoutPoints: 0, points: 1 }
55
55
  ]);
56
56
  });
57
57
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.424",
3
+ "version": "0.0.425",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",