]> git.sesse.net Git - pkanalytics/commitdiff
Count time on offense and on defense.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 21 May 2023 21:17:34 +0000 (23:17 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 21 May 2023 21:21:37 +0000 (23:21 +0200)
ultimate.js

index 9ed8936f79d41f4d0487e82741b46e3ca75f7d2a..5c176e0deeb7309369e69b0c151942f0c7f4d000 100644 (file)
@@ -9,20 +9,27 @@ fetch('ultimate.json')
    .then(response => response.json())
    .then(response => { global_json = response; process_matches(global_json); });
 
-function attribute_player_time(player, to, from) {
+function attribute_player_time(player, to, from, offense) {
+       let delta_time;
        if (player.on_field_since > from) {
                // Player came in while play happened (without a stoppage!?).
-               player.playing_time_ms += to - player.on_field_since;
+               delta_time = to - player.on_field_since;
        } else {
-               player.playing_time_ms += to - from;
+               delta_time = to - from;
+       }
+       player.playing_time_ms += delta_time;
+       if (offense === true) {
+               player.offensive_playing_time_ms += delta_time;
+       } else if (offense === false) {
+               player.defensive_playing_time_ms += delta_time;
        }
 }
 
-function take_off_field(player, t, live_since) {
+function take_off_field(player, t, live_since, offense) {
        if (live_since === null) {
                // Play isn't live, so nothing to do.
        } else {
-               attribute_player_time(player, t, live_since);
+               attribute_player_time(player, t, live_since, offense);
        }
        if (player.on_field_since !== null) {  // Just a safeguard; out without in should never happen.
                player.field_time_ms += t - player.on_field_since;
@@ -158,6 +165,8 @@ function process_matches(json) {
                        'interceptions': 0,
                        'points_played': 0,
                        'playing_time_ms': 0,
+                       'offensive_playing_time_ms': 0,
+                       'defensive_playing_time_ms': 0,
                        'field_time_ms': 0,
 
                        // For efficiency.
@@ -185,6 +194,8 @@ function process_matches(json) {
        players['globals'] = {
                'points_played': 0,
                'playing_time_ms': 0,
+               'offensive_playing_time_ms': 0,
+               'defensive_playing_time_ms': 0,
                'field_time_ms': 0,
 
                'offensive_points_completed': 0,
@@ -200,7 +211,7 @@ function process_matches(json) {
                let handler = null;
                let prev_handler = null;
                let live_since = null;
-               let offense = null;
+               let offense = null;  // True/false/null (unknown).
                let puller = null;
                let pull_started = null;
                let last_pull_was_ours = null;  // Effectively whether we're playing an O or D point (not affected by turnovers).
@@ -220,7 +231,7 @@ function process_matches(json) {
                        if (type === 'in' && p.on_field_since === null) {
                                p.on_field_since = t;
                        } else if (type === 'out') {
-                               take_off_field(p, t, live_since);
+                               take_off_field(p, t, live_since, offense);
                        }
 
                        // Liveness management
@@ -242,7 +253,7 @@ function process_matches(json) {
                                                p.last_point_seen = point_num;
                                                ++p.points_played;
                                        }
-                                       attribute_player_time(p, t, live_since);
+                                       attribute_player_time(p, t, live_since, offense);
 
                                        if (type !== 'stoppage') {
                                                if (last_pull_was_ours === true) {  // D point.
@@ -276,6 +287,11 @@ function process_matches(json) {
                                }
                                if (live_since !== null) {
                                        globals.playing_time_ms += t - live_since;
+                                       if (offense === true) {
+                                               globals.offensive_playing_time_ms += t - live_since;
+                                       } else if (offense === false) {
+                                               globals.defensive_playing_time_ms += t - live_since;
+                                       }
                                }
 
                                live_since = null;
@@ -317,12 +333,31 @@ function process_matches(json) {
                                puller = pull_started = null;
                        }
 
-                       // Offense/defense management (TODO: use it for actual counting)
+                       // Offense/defense management
+                       let last_offense = offense;
                        if (type === 'set_defense' || type === 'goal' || type === 'throwaway' || type === 'drop') {
                                offense = false;
                        } else if (type === 'set_offense' || type === 'their_goal' || type === 'their_throwaway' || type === 'defense' || type === 'interception') {
                                offense = true;
                        }
+                       if (last_offense !== offense && live_since !== null) {
+                               // Switched offense/defense status, so attribute this drive as needed,
+                               // and update live_since to take that into account.
+                               for (const [q,p] of Object.entries(players)) {
+                                       if (p.on_field_since === null) {
+                                               continue;
+                                       }
+                                       attribute_player_time(p, t, live_since, last_offense);
+                               }
+                               globals.playing_time_ms += t - live_since;
+                               if (offense === true) {
+                                       globals.offensive_playing_time_ms += t - live_since;
+                               } else if (offense === false) {
+                                       globals.defensive_playing_time_ms += t - live_since;
+                               }
+                               live_since = t;
+                       }
+
                        if (type === 'pull') {
                                last_pull_was_ours = true;
                        } else if (type === 'their_pull') {
@@ -403,6 +438,11 @@ function process_matches(json) {
                }
                if (live_since !== null && last_goal !== null) {
                        globals.playing_time_ms += last_goal - live_since;
+                       if (offense === true) {
+                               globals.offensive_playing_time_ms += last_goal - live_since;
+                       } else if (offense === false) {
+                               globals.defensive_playing_time_ms += last_goal - live_since;
+                       }
                }
        }
 
@@ -741,6 +781,8 @@ function make_table_playing_time(players) {
                add_th(header, 'Player');
                add_th(header, 'Points played');
                add_th(header, 'Time played');
+               add_th(header, 'O time');
+               add_th(header, 'D time');
                add_th(header, 'Time on field');
                add_th(header, 'O points');
                add_th(header, 'D points');
@@ -753,6 +795,8 @@ function make_table_playing_time(players) {
                add_3cell(row, p.name, 'name');  // TODO: number?
                add_3cell(row, p.points_played);
                add_3cell(row, Math.floor(p.playing_time_ms / 60000) + ' min');
+               add_3cell(row, Math.floor(p.offensive_playing_time_ms / 60000) + ' min');
+               add_3cell(row, Math.floor(p.defensive_playing_time_ms / 60000) + ' min');
                add_3cell(row, Math.floor(p.field_time_ms / 60000) + ' min');
                add_3cell(row, p.offensive_points_completed);
                add_3cell(row, p.defensive_points_completed);
@@ -765,6 +809,8 @@ function make_table_playing_time(players) {
        add_3cell(row, '');
        add_3cell(row, globals.points_played);
        add_3cell(row, Math.floor(globals.playing_time_ms / 60000) + ' min');
+       add_3cell(row, Math.floor(globals.offensive_playing_time_ms / 60000) + ' min');
+       add_3cell(row, Math.floor(globals.defensive_playing_time_ms / 60000) + ' min');
        add_3cell(row, Math.floor(globals.field_time_ms / 60000) + ' min');
        add_3cell(row, globals.offensive_points_completed);
        add_3cell(row, globals.defensive_points_completed);