From 7a960fbf75a145f30e34f5f803062d91afb81165 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 20 Jul 2023 12:19:00 +0200 Subject: [PATCH] Split away getting d-ed from drops. --- events.cpp | 6 ++++-- main.cpp | 27 +++++++++++++++++---------- mainwindow.ui | 2 +- ultimate.js | 19 ++++++++++++++----- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/events.cpp b/events.cpp index 0a50f3b..88b0d4a 100644 --- a/events.cpp +++ b/events.cpp @@ -79,6 +79,8 @@ QVariant EventsModel::data(const QModelIndex &index, int role) const type = "On defense"; } else if (type == "Catch") { type = "Catch/take"; + } else if (type == "Was d") { + type = "Was d-ed"; } return QString::fromUtf8(type); @@ -403,7 +405,7 @@ EventsModel::Status EventsModel::get_status_at(uint64_t t) num_touches = 0; time_spent_in_stoppage = 0; } - if (e.type == "drop" || e.type == "throwaway") { + if (e.type == "drop" || e.type == "was_d" || e.type == "throwaway") { set_defense(); num_touches = 0; } @@ -521,7 +523,7 @@ void EventsModel::set_formation_at(uint64_t t, bool offense, unsigned formation) e.type == "stoppage" || e.type == "reset" || e.type == "set_defense" || e.type == "set_offense" || e.type == "throwaway" || e.type == "their_throwaway" || - e.type == "drop" || e.type == "defense" || e.type == "interception" || + e.type == "drop" || e.type == "was_d" || e.type == "defense" || e.type == "interception" || e.type == "pull" || e.type == "pull_landed" || e.type == "pull_oob" || e.type == "their_pull" || e.type == "formation_offense" || e.type == "formation_defense") { backdate_point = e.t + 1; diff --git a/main.cpp b/main.cpp index 560a9a6..ac9b554 100644 --- a/main.cpp +++ b/main.cpp @@ -140,12 +140,14 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players, connect(ui->goal, &QPushButton::clicked, [this]() { set_current_event_type("goal"); }); connect(ui->offensive_soft_plus, &QPushButton::clicked, [this]() { set_current_event_type("offensive_soft_plus"); }); connect(ui->offensive_soft_minus, &QPushButton::clicked, [this]() { set_current_event_type("offensive_soft_minus"); }); - connect(ui->pull, &QPushButton::clicked, [this, events]() { + connect(ui->pull_or_was_d, &QPushButton::clicked, [this, events]() { EventsModel::Status s = events->get_status_at(ui->video->get_position()); if (s.pull_state == EventsModel::Status::SHOULD_PULL) { set_current_event_type("pull"); } else if (s.pull_state == EventsModel::Status::PULL_IN_AIR) { insert_noplayer_event("pull_landed"); + } else if (s.pull_state == EventsModel::Status::NOT_PULLING) { + set_current_event_type("was_d"); } }); @@ -410,7 +412,7 @@ void MainWindow::update_action_buttons(uint64_t t) ui->goal->setEnabled(false); ui->offensive_soft_plus->setEnabled(false); ui->offensive_soft_minus->setEnabled(false); - ui->pull->setEnabled(false); + ui->pull_or_was_d->setEnabled(false); ui->interception->setEnabled(false); ui->their_throwaway->setEnabled(false); ui->our_defense->setEnabled(false); @@ -425,15 +427,15 @@ void MainWindow::update_action_buttons(uint64_t t) } // Defaults for pull-related buttons. - ui->pull->setText("Pull (&p)"); + ui->pull_or_was_d->setText("Pull (&p)"); ui->their_pull->setText("Their pull (&p)"); - ui->pull->setShortcut(QCoreApplication::translate("MainWindow", "P", nullptr)); + ui->pull_or_was_d->setShortcut(QCoreApplication::translate("MainWindow", "P", nullptr)); ui->their_pull->setShortcut(QCoreApplication::translate("MainWindow", "P", nullptr)); ui->throwaway->setText("Throwaway (&t)"); ui->throwaway->setShortcut(QCoreApplication::translate("MainWindow", "T", nullptr)); if (s.pull_state == EventsModel::Status::SHOULD_PULL) { - ui->pull->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player); + ui->pull_or_was_d->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player); ui->their_pull->setEnabled(s.attack_state == EventsModel::Status::OFFENSE); ui->catch_->setEnabled(false); @@ -452,15 +454,15 @@ void MainWindow::update_action_buttons(uint64_t t) } if (s.pull_state == EventsModel::Status::PULL_IN_AIR) { if (s.attack_state == EventsModel::Status::DEFENSE) { - ui->pull->setText("Pull landed (&p)"); - ui->pull->setShortcut(QCoreApplication::translate("MainWindow", "P", nullptr)); - ui->pull->setEnabled(true); + ui->pull_or_was_d->setText("Pull landed (&p)"); + ui->pull_or_was_d->setShortcut(QCoreApplication::translate("MainWindow", "P", nullptr)); + ui->pull_or_was_d->setEnabled(true); ui->throwaway->setText("Pull OOB (&t)"); ui->throwaway->setShortcut(QCoreApplication::translate("MainWindow", "T", nullptr)); ui->throwaway->setEnabled(true); } else { - ui->pull->setEnabled(false); + ui->pull_or_was_d->setEnabled(false); ui->throwaway->setEnabled(false); } ui->their_pull->setEnabled(false); // We don't track their pull landings; only by means of catch etc. @@ -479,13 +481,18 @@ void MainWindow::update_action_buttons(uint64_t t) return; } + // Not pulling, so reuse the pull button for got d-ed. + ui->pull_or_was_d->setText("Was d-ed (&z)"); + ui->pull_or_was_d->setShortcut(QCoreApplication::translate("MainWindow", "Z", nullptr)); + ui->pull_or_was_d->setEnabled(true); + ui->catch_->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); ui->throwaway->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); ui->drop->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); ui->goal->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); ui->offensive_soft_plus->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); ui->offensive_soft_minus->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); - ui->pull->setEnabled(false); + ui->pull_or_was_d->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player); // Was d-ed. ui->interception->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player); ui->their_throwaway->setEnabled(s.attack_state == EventsModel::Status::DEFENSE); diff --git a/mainwindow.ui b/mainwindow.ui index 85e0f1d..207d0c5 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -106,7 +106,7 @@ - + Pull (&p) diff --git a/ultimate.js b/ultimate.js index 22ff78b..0100f6a 100644 --- a/ultimate.js +++ b/ultimate.js @@ -164,6 +164,7 @@ function process_matches(json, filters) { 'num_throws': 0, 'throwaways': 0, 'drops': 0, + 'was_ds': 0, 'defenses': 0, 'interceptions': 0, @@ -392,7 +393,7 @@ function process_matches(json, filters) { // Offense/defense management let last_offense = offense; - if (type === 'set_defense' || type === 'goal' || type === 'throwaway' || type === 'drop') { + if (type === 'set_defense' || type === 'goal' || type === 'throwaway' || type === 'drop' || type === 'was_d') { offense = false; } else if (type === 'set_offense' || type === 'their_goal' || type === 'their_throwaway' || type === 'defense' || type === 'interception') { offense = true; @@ -506,6 +507,9 @@ function process_matches(json, filters) { } else if (type === 'drop') { if (keep) ++p.drops; handler = prev_handler = null; + } else if (type === 'was_d') { + if (keep) ++p.was_ds; + handler = prev_handler = null; } else if (type === 'defense') { if (keep) ++p.defenses; } else if (type === 'interception') { @@ -521,7 +525,7 @@ function process_matches(json, filters) { } else if (type !== 'in' && type !== 'out' && type !== 'pull' && type !== 'their_goal' && type !== 'stoppage' && type !== 'restart' && type !== 'unknown' && type !== 'set_defense' && type !== 'goal' && type !== 'throwaway' && - type !== 'drop' && type !== 'set_offense' && type !== 'their_goal' && + type !== 'drop' && type !== 'was_d' && type !== 'set_offense' && type !== 'their_goal' && type !== 'pull' && type !== 'pull_landed' && type !== 'pull_oob' && type !== 'their_pull' && type !== 'their_throwaway' && type !== 'defense' && type !== 'interception' && type !== 'formation_offense' && type !== 'formation_defense') { @@ -728,7 +732,7 @@ function make_table_general(players) { for (const [q,p] of Object.entries(players)) { if (q === 'globals') continue; let row = document.createElement('tr'); - let pm = p.goals + p.assists + p.hockey_assists + p.defenses - p.throwaways - p.drops; + let pm = p.goals + p.assists + p.hockey_assists + p.defenses - p.throwaways - p.drops - p.was_ds; let soft_pm = p.offensive_soft_plus + p.defensive_soft_plus - p.offensive_soft_minus - p.defensive_soft_minus; let o_efficiency = make_efficiency_ci(p.offensive_points_won, p.offensive_points_completed, z); let d_efficiency = make_efficiency_ci(p.defensive_points_won, p.defensive_points_completed, z); @@ -770,6 +774,7 @@ function make_table_offense(players) { add_th(header, '%OK'); add_th(header, 'Catches'); add_th(header, 'Drops'); + add_th(header, 'D-ed'); add_th(header, '%OK'); add_th(header, 'Soft +/-', 6); rows.push(header); @@ -779,10 +784,11 @@ function make_table_offense(players) { let throwaways = 0; let catches = 0; let drops = 0; + let was_ds = 0; for (const [q,p] of Object.entries(players)) { if (q === 'globals') continue; let throw_ok = make_binomial_ci(p.num_throws - p.throwaways, p.num_throws, z); - let catch_ok = make_binomial_ci(p.catches, p.catches + p.drops, z); + let catch_ok = make_binomial_ci(p.catches, p.catches + p.drops + p.was_ds, z); throw_ok.format = 'percentage'; catch_ok.format = 'percentage'; @@ -801,6 +807,7 @@ function make_table_offense(players) { add_3cell_ci(row, throw_ok); add_3cell(row, p.catches); add_3cell(row, p.drops); + add_3cell(row, p.was_ds); add_3cell_ci(row, catch_ok); add_3cell(row, '+' + p.offensive_soft_plus); add_3cell(row, '-' + p.offensive_soft_minus); @@ -810,11 +817,12 @@ function make_table_offense(players) { throwaways += p.throwaways; catches += p.catches; drops += p.drops; + was_ds += p.was_ds; } // Globals. let throw_ok = make_binomial_ci(num_throws - throwaways, num_throws, z); - let catch_ok = make_binomial_ci(catches, catches + drops, z); + let catch_ok = make_binomial_ci(catches, catches + drops + was_ds, z); throw_ok.format = 'percentage'; catch_ok.format = 'percentage'; throw_ok.desired = 0.9; @@ -830,6 +838,7 @@ function make_table_offense(players) { add_3cell_ci(row, throw_ok); add_3cell(row, catches); add_3cell(row, drops); + add_3cell(row, was_ds); add_3cell_ci(row, catch_ok); add_3cell(row, ''); add_3cell(row, ''); -- 2.39.2