X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ultimate.js;h=292534f23dd1f25293c4dad28133d1e0cd4f08bb;hb=3f7cd86babde664f9395477bb02de95d4c42d8f8;hp=e9b0d801db0490bd13df4f3c484c553aa44f2e27;hpb=605df45786d9848550f3559cea85a24edb4dcb63;p=pkanalytics diff --git a/ultimate.js b/ultimate.js index e9b0d80..292534f 100644 --- a/ultimate.js +++ b/ultimate.js @@ -241,6 +241,7 @@ function calc_stats(json, filters) { let our_score = 0; let their_score = 0; + let between_points = true; let handler = null; let handler_got_by_interception = false; // Only relevant if handler !== null. let prev_handler = null; @@ -252,6 +253,8 @@ function calc_stats(json, filters) { let point_num = 0; let game_started = null; let last_goal = null; + let current_predominant_gender = null; + let current_num_players_on_field = null; // The last used formations of the given kind, if any; they may be reused // when the point starts, if nothing else is set. @@ -309,14 +312,56 @@ function calc_stats(json, filters) { keep = keep_event(players, formations_used_this_point, last_pull_was_ours, filters); // Recompute after in/out. + if (match['gender_rule_a']) { + if (type === 'restart' && !between_points) { + let predominant_gender = find_predominant_gender(players); + let num_players_on_field = find_num_players_on_field(players); + if (predominant_gender !== current_predominant_gender && current_predominant_gender !== null) { + console.log(match['description'] + ' ' + format_time(t) + ': Stoppage changed predominant gender from ' + current_predominant_gender + ' to ' + predominant_gender); + } + if (num_players_on_field !== current_num_players_on_field && current_num_players_on_field !== null) { + console.log(match['description'] + ' ' + format_time(t) + ': Stoppage changed number of players on field from ' + current_num_players_on_field + ' to ' + num_players_on_field); + } + current_predominant_gender = predominant_gender; + current_num_players_on_field = num_players_on_field; + } else if (type === 'pull' || type === 'their_pull') { + let predominant_gender = find_predominant_gender(players); + let num_players_on_field = find_num_players_on_field(players); + let changed = (predominant_gender !== current_predominant_gender); + if (point_num !== 0) { + let should_change = (point_num % 4 == 1 || point_num % 4 == 3); // ABBA changes on 1 and 3. + if (changed && !should_change) { + console.log(match['description'] + ' ' + format_time(t) + ': Gender ratio should have stayed the same, changed to predominance of ' + predominant_gender); + } else if (!changed && should_change) { + console.log(match['description'] + ' ' + format_time(t) + ': Gender ratio should have changed, remained predominantly ' + predominant_gender); + } + if (num_players_on_field !== current_num_players_on_field && current_num_players_on_field !== null) { + console.log(match['description'] + ' ' + format_time(t) + ': Number of players on field changed from ' + current_num_players_on_field + ' to ' + num_players_on_field); + } + } + current_predominant_gender = predominant_gender; + current_num_players_on_field = num_players_on_field; + } + } + if (match['gender_pull_rule']) { + if (type === 'pull') { + if (current_predominant_gender !== null && + p.gender !== current_predominant_gender) { + console.log(match['description'] + ' ' + format_time(t) + ': ' + p.name + ' pulled, should have been ' + current_predominant_gender); + } + } + } + // Liveness management if (type === 'pull' || type === 'their_pull' || type === 'restart') { live_since = t; + between_points = false; } else if (type === 'catch' && last_pull_was_ours === null) { // Someone forgot to add the pull, so we'll need to wing it. console.log(match['description'] + ' ' + format_time(t) + ': Missing pull on ' + our_score + '\u2013' + their_score + '; pretending to have one.'); live_since = t; last_pull_was_ours = !offense; + between_points = false; } else if (type === 'goal' || type === 'their_goal' || type === 'stoppage') { for (const [q,p] of Object.entries(players)) { if (p.on_field_since === null) { @@ -381,8 +426,10 @@ function calc_stats(json, filters) { // Score management if (type === 'goal') { ++our_score; + between_points = true; } else if (type === 'their_goal') { ++their_score; + between_points = true; } // Point count management @@ -1780,7 +1827,8 @@ function keep_match(match_id, filters) { return true; } -function find_gender_ratio_code(players) { +// Returns a map of e.g. F => 4, M => 3. +function find_gender_ratio(players) { let map = {}; for (const [q,p] of Object.entries(players)) { if (p.on_field_since === null) { @@ -1796,6 +1844,11 @@ q } else { ++map[gender]; } } + return map; +} + +function find_gender_ratio_code(players) { + let map = find_gender_ratio(players); let all_genders = Array.from(Object.keys(map)).sort( (a,b) => { if (map[a] !== map[b]) { @@ -1820,6 +1873,31 @@ q } else { return code; } +// null if none (e.g., if playing 3–3). +function find_predominant_gender(players) { + let max = 0; + let predominant_gender = null; + for (const [gender, num] of Object.entries(find_gender_ratio(players))) { + if (num > max) { + max = num; + predominant_gender = gender; + } else if (num == max) { + predominant_gender = null; // At least two have the same. + } + } + return predominant_gender; +} + +function find_num_players_on_field(players) { + let num = 0; + for (const [q,p] of Object.entries(players)) { + if (p.on_field_since !== null) { + ++num; + } + } + return num; +} + function filter_passes(players, formations_used_this_point, last_pull_was_ours, filter) { if (filter.type === 'player_any') { for (const p of Array.from(filter.elements)) {