Separate sync query to reduce complexity
This commit is contained in:
parent
c70fc7506a
commit
e16b0be447
|
@ -95,34 +95,6 @@ pub fn update_last_sync(connection: &Connection, dataset: &str, sync: u64) -> sq
|
||||||
.try_for_each(|x| x.map(|_| ()))
|
.try_for_each(|x| x.map(|_| ()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Score calculation
|
|
||||||
|
|
||||||
/// Calculate the collective expected score for each team.
|
|
||||||
fn expected_scores(ratings: &Teams<&mut f64>) -> Vec<f64> {
|
|
||||||
let qs: Vec<f64> = ratings
|
|
||||||
.into_iter()
|
|
||||||
.map(|es| 10_f64.powf(es.iter().map(|x| **x).sum::<f64>() / es.len() as f64 / 400.0))
|
|
||||||
.collect();
|
|
||||||
let sumq: f64 = qs.iter().sum();
|
|
||||||
qs.into_iter().map(|q| q / sumq).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adjust the ratings of each player based on who won.
|
|
||||||
fn adjust_ratings(ratings: Teams<&mut f64>, winner: usize) {
|
|
||||||
let exp_scores = expected_scores(&ratings);
|
|
||||||
|
|
||||||
ratings
|
|
||||||
.into_iter()
|
|
||||||
.zip(exp_scores.into_iter())
|
|
||||||
.enumerate()
|
|
||||||
.for_each(|(i, (es, exp_sc))| {
|
|
||||||
let len = es.len() as f64;
|
|
||||||
let score = f64::from(winner == i);
|
|
||||||
es.into_iter()
|
|
||||||
.for_each(|e| *e += 40.0 * (score - exp_sc) / len);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Database Updating
|
// Database Updating
|
||||||
|
|
||||||
pub fn add_players(
|
pub fn add_players(
|
||||||
|
@ -186,28 +158,3 @@ pub fn update_ratings(
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> sqlite::Result<()> {
|
|
||||||
let players_data = results.teams;
|
|
||||||
add_players(connection, dataset, &players_data)?;
|
|
||||||
|
|
||||||
let mut elos = get_ratings(connection, dataset, &players_data)?;
|
|
||||||
adjust_ratings(
|
|
||||||
elos.iter_mut()
|
|
||||||
.map(|v| v.iter_mut().map(|x| &mut x.1).collect())
|
|
||||||
.collect(),
|
|
||||||
results.winner,
|
|
||||||
);
|
|
||||||
update_ratings(connection, dataset, elos)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_from_tournament(
|
|
||||||
connection: &Connection,
|
|
||||||
dataset: &str,
|
|
||||||
results: TournamentData,
|
|
||||||
) -> sqlite::Result<()> {
|
|
||||||
results
|
|
||||||
.sets
|
|
||||||
.into_iter()
|
|
||||||
.try_for_each(|set| update_from_set(connection, dataset, set))
|
|
||||||
}
|
|
||||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -9,6 +9,8 @@ mod queries;
|
||||||
use queries::*;
|
use queries::*;
|
||||||
mod datasets;
|
mod datasets;
|
||||||
use datasets::*;
|
use datasets::*;
|
||||||
|
mod sync;
|
||||||
|
use sync::*;
|
||||||
|
|
||||||
/// ## CLI Structs
|
/// ## CLI Structs
|
||||||
|
|
||||||
|
@ -162,27 +164,5 @@ fn sync(datasets: Vec<String>, all: bool, auth_token: Option<String>) {
|
||||||
|
|
||||||
for dataset in datasets {
|
for dataset in datasets {
|
||||||
let last_sync = get_last_sync(&connection, &dataset).unwrap().unwrap();
|
let last_sync = get_last_sync(&connection, &dataset).unwrap().unwrap();
|
||||||
|
|
||||||
let results = run_query::<TournamentSets, _>(
|
|
||||||
TournamentSetsVars {
|
|
||||||
last_query: Timestamp(last_sync),
|
|
||||||
game_id: VideogameId(1),
|
|
||||||
tournament: 1,
|
|
||||||
set_page: 1,
|
|
||||||
set_pagesize: 50,
|
|
||||||
event_limit: 9999999,
|
|
||||||
},
|
|
||||||
&auth,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
update_from_tournament(&connection, &dataset, results).unwrap();
|
|
||||||
|
|
||||||
let current_time = SystemTime::now()
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
update_last_sync(&connection, &dataset, current_time).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@ use std::path::Path;
|
||||||
|
|
||||||
pub mod search_games;
|
pub mod search_games;
|
||||||
pub use search_games::*;
|
pub use search_games::*;
|
||||||
pub mod tournament_sets;
|
pub mod tournament_events;
|
||||||
pub use tournament_sets::*;
|
pub use tournament_events::*;
|
||||||
|
pub mod event_sets;
|
||||||
|
pub use event_sets::*;
|
||||||
pub mod player_info;
|
pub mod player_info;
|
||||||
pub use player_info::*;
|
pub use player_info::*;
|
||||||
|
|
||||||
|
@ -47,6 +49,10 @@ pub fn get_auth_token(config_dir: &Path) -> Option<String> {
|
||||||
#[cynic(graphql_type = "ID")]
|
#[cynic(graphql_type = "ID")]
|
||||||
pub struct VideogameId(pub u64);
|
pub struct VideogameId(pub u64);
|
||||||
|
|
||||||
|
#[derive(cynic::Scalar, Debug, Copy, Clone)]
|
||||||
|
#[cynic(graphql_type = "ID")]
|
||||||
|
pub struct EventId(pub u64);
|
||||||
|
|
||||||
#[derive(cynic::Scalar, Debug, Copy, Clone)]
|
#[derive(cynic::Scalar, Debug, Copy, Clone)]
|
||||||
#[cynic(graphql_type = "ID")]
|
#[cynic(graphql_type = "ID")]
|
||||||
pub struct EntrantId(pub u64);
|
pub struct EntrantId(pub u64);
|
||||||
|
|
120
src/queries/event_sets.rs
Normal file
120
src/queries/event_sets.rs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
use super::{EntrantId, EventId, PlayerData, PlayerId, QueryUnwrap};
|
||||||
|
use cynic::GraphQlResponse;
|
||||||
|
use schema::schema;
|
||||||
|
|
||||||
|
pub type Teams<T> = Vec<Vec<T>>;
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
#[derive(cynic::QueryVariables, Debug)]
|
||||||
|
pub struct EventSetsVars {
|
||||||
|
pub event: EventId,
|
||||||
|
pub sets_page: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(graphql_type = "Query", variables = "EventSetsVars")]
|
||||||
|
pub struct EventSets {
|
||||||
|
#[arguments(id: $event)]
|
||||||
|
event: Option<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(variables = "EventSetsVars")]
|
||||||
|
struct Event {
|
||||||
|
#[arguments(page: $sets_page, perPage: 11)]
|
||||||
|
sets: Option<SetConnection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct SetConnection {
|
||||||
|
#[cynic(flatten)]
|
||||||
|
nodes: Vec<Set>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct Set {
|
||||||
|
#[arguments(includeByes: true)]
|
||||||
|
#[cynic(flatten)]
|
||||||
|
slots: Vec<SetSlot>,
|
||||||
|
winner_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct SetSlot {
|
||||||
|
entrant: Option<Entrant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct Entrant {
|
||||||
|
id: Option<EntrantId>,
|
||||||
|
#[cynic(flatten)]
|
||||||
|
participants: Vec<Participant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct Participant {
|
||||||
|
player: Option<Player>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct Player {
|
||||||
|
id: Option<PlayerId>,
|
||||||
|
gamer_tag: Option<String>,
|
||||||
|
prefix: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap
|
||||||
|
|
||||||
|
pub struct SetData {
|
||||||
|
teams: Teams<PlayerData>,
|
||||||
|
winner: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryUnwrap<EventSetsVars> for EventSets {
|
||||||
|
type Unwrapped = Vec<SetData>;
|
||||||
|
|
||||||
|
// This might be the most spaghetti code I've ever written
|
||||||
|
fn unwrap_response(response: GraphQlResponse<EventSets>) -> Option<Vec<SetData>> {
|
||||||
|
Some(
|
||||||
|
response
|
||||||
|
.data?
|
||||||
|
.event?
|
||||||
|
.sets?
|
||||||
|
.nodes
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|set| {
|
||||||
|
let winner_id = set.winner_id?;
|
||||||
|
let winner = set.slots.iter().position(|slot| {
|
||||||
|
slot.entrant
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.id)
|
||||||
|
.map(|id| id.0 == winner_id as u64)
|
||||||
|
.unwrap_or(false)
|
||||||
|
})?;
|
||||||
|
let teams = set
|
||||||
|
.slots
|
||||||
|
.into_iter()
|
||||||
|
.map(|slot| {
|
||||||
|
slot.entrant?
|
||||||
|
.participants
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| {
|
||||||
|
let p_ = p.player?;
|
||||||
|
Some(PlayerData {
|
||||||
|
id: p_.id?,
|
||||||
|
name: p_.gamer_tag,
|
||||||
|
prefix: p_.prefix,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.try_collect()
|
||||||
|
})
|
||||||
|
.try_collect()?;
|
||||||
|
Some(SetData { teams, winner })
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
88
src/queries/tournament_events.rs
Normal file
88
src/queries/tournament_events.rs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
use super::QueryUnwrap;
|
||||||
|
use super::{EventId, Timestamp, VideogameId};
|
||||||
|
use cynic::GraphQlResponse;
|
||||||
|
use schema::schema;
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
#[derive(cynic::QueryVariables, Debug)]
|
||||||
|
pub struct TournamentEventsVars {
|
||||||
|
// HACK: This should really be an optional variable, but there seems to be a
|
||||||
|
// server-side bug that completely breaks everything when this isn't passed.
|
||||||
|
// We can use a dummy value of 1 when we don't want to filter by time.
|
||||||
|
pub last_query: Timestamp,
|
||||||
|
pub game_id: VideogameId,
|
||||||
|
pub page: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(graphql_type = "Query", variables = "TournamentEventsVars")]
|
||||||
|
pub struct TournamentEvents {
|
||||||
|
#[arguments(query: {
|
||||||
|
page: $page,
|
||||||
|
perPage: 300,
|
||||||
|
sortBy: "endAt asc",
|
||||||
|
filter: {
|
||||||
|
past: true,
|
||||||
|
afterDate: $last_query,
|
||||||
|
videogameIds: [$game_id],
|
||||||
|
}})]
|
||||||
|
tournaments: Option<TournamentConnection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(variables = "TournamentEventsVars")]
|
||||||
|
struct TournamentConnection {
|
||||||
|
#[cynic(flatten)]
|
||||||
|
nodes: Vec<Tournament>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(variables = "TournamentEventsVars")]
|
||||||
|
struct Tournament {
|
||||||
|
name: Option<String>,
|
||||||
|
#[arguments(limit: 99999, filter: { videogameId: [$game_id] })]
|
||||||
|
#[cynic(flatten)]
|
||||||
|
events: Vec<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
#[cynic(variables = "TournamentEventsVars")]
|
||||||
|
struct Event {
|
||||||
|
id: Option<EventId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TournamentData {
|
||||||
|
pub name: String,
|
||||||
|
pub events: Vec<EventId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryUnwrap<TournamentEventsVars> for TournamentEvents {
|
||||||
|
type Unwrapped = Vec<TournamentData>;
|
||||||
|
|
||||||
|
fn unwrap_response(response: GraphQlResponse<TournamentEvents>) -> Option<Vec<TournamentData>> {
|
||||||
|
Some(
|
||||||
|
response
|
||||||
|
.data?
|
||||||
|
.tournaments?
|
||||||
|
.nodes
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|tour| {
|
||||||
|
Some(TournamentData {
|
||||||
|
name: tour.name?,
|
||||||
|
events: tour
|
||||||
|
.events
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|event| event.id)
|
||||||
|
.collect(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,169 +0,0 @@
|
||||||
use super::{EntrantId, PlayerData, PlayerId, QueryUnwrap, Timestamp, VideogameId};
|
|
||||||
use cynic::GraphQlResponse;
|
|
||||||
use schema::schema;
|
|
||||||
|
|
||||||
pub type Teams<T> = Vec<Vec<T>>;
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
|
|
||||||
#[derive(cynic::QueryVariables, Debug)]
|
|
||||||
pub struct TournamentSetsVars {
|
|
||||||
// HACK: This should really be an optional variable, but there seems to be a
|
|
||||||
// server-side bug that completely breaks everything when this isn't passed.
|
|
||||||
// We can use a dummy value of 1 when we don't want to filter by time.
|
|
||||||
pub last_query: Timestamp,
|
|
||||||
pub game_id: VideogameId,
|
|
||||||
|
|
||||||
pub tournament: i32,
|
|
||||||
pub event_limit: i32,
|
|
||||||
pub set_page: i32,
|
|
||||||
pub set_pagesize: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
#[cynic(graphql_type = "Query", variables = "TournamentSetsVars")]
|
|
||||||
pub struct TournamentSets {
|
|
||||||
#[arguments(query: {
|
|
||||||
page: $tournament,
|
|
||||||
perPage: 1,
|
|
||||||
sortBy: "endAt asc",
|
|
||||||
filter: {
|
|
||||||
past: true,
|
|
||||||
afterDate: $last_query,
|
|
||||||
videogameIds: [$game_id],
|
|
||||||
}})]
|
|
||||||
tournaments: Option<TournamentConnection>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
#[cynic(variables = "TournamentSetsVars")]
|
|
||||||
struct TournamentConnection {
|
|
||||||
#[cynic(flatten)]
|
|
||||||
nodes: Vec<Tournament>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
#[cynic(variables = "TournamentSetsVars")]
|
|
||||||
struct Tournament {
|
|
||||||
name: Option<String>,
|
|
||||||
#[arguments(limit: $event_limit, filter: { videogameId: [$game_id] })]
|
|
||||||
#[cynic(flatten)]
|
|
||||||
events: Vec<Event>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
#[cynic(variables = "TournamentSetsVars")]
|
|
||||||
struct Event {
|
|
||||||
#[arguments(page: $set_page, perPage: $set_pagesize)]
|
|
||||||
sets: Option<SetConnection>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
struct SetConnection {
|
|
||||||
#[cynic(flatten)]
|
|
||||||
nodes: Vec<Set>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
struct Set {
|
|
||||||
#[arguments(includeByes: true)]
|
|
||||||
#[cynic(flatten)]
|
|
||||||
slots: Vec<SetSlot>,
|
|
||||||
winner_id: Option<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
struct SetSlot {
|
|
||||||
entrant: Option<Entrant>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
struct Entrant {
|
|
||||||
id: Option<EntrantId>,
|
|
||||||
#[cynic(flatten)]
|
|
||||||
participants: Vec<Participant>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
struct Participant {
|
|
||||||
player: Option<Player>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(cynic::QueryFragment, Debug)]
|
|
||||||
struct Player {
|
|
||||||
id: Option<PlayerId>,
|
|
||||||
gamer_tag: Option<String>,
|
|
||||||
prefix: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct TournamentData {
|
|
||||||
pub name: String,
|
|
||||||
pub sets: Vec<SetData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct SetData {
|
|
||||||
pub teams: Teams<PlayerData>,
|
|
||||||
pub winner: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl QueryUnwrap<TournamentSetsVars> for TournamentSets {
|
|
||||||
type Unwrapped = TournamentData;
|
|
||||||
|
|
||||||
// This might be the most spaghetti code I've ever written
|
|
||||||
fn unwrap_response(response: GraphQlResponse<TournamentSets>) -> Option<TournamentData> {
|
|
||||||
let tour = response.data?.tournaments?.nodes.into_iter().next()?;
|
|
||||||
let sets = tour
|
|
||||||
.events
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|event| {
|
|
||||||
Some(
|
|
||||||
event
|
|
||||||
.sets?
|
|
||||||
.nodes
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|set| {
|
|
||||||
let winner_id = set.winner_id?;
|
|
||||||
let winner = set.slots.iter().position(|slot| {
|
|
||||||
slot.entrant
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|x| x.id)
|
|
||||||
.map(|id| id.0 == winner_id as u64)
|
|
||||||
.unwrap_or(false)
|
|
||||||
})?;
|
|
||||||
let teams = set
|
|
||||||
.slots
|
|
||||||
.into_iter()
|
|
||||||
.map(|slot| {
|
|
||||||
slot.entrant?
|
|
||||||
.participants
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| {
|
|
||||||
let p_ = p.player?;
|
|
||||||
Some(PlayerData {
|
|
||||||
id: p_.id?,
|
|
||||||
name: p_.gamer_tag,
|
|
||||||
prefix: p_.prefix,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.try_collect()
|
|
||||||
})
|
|
||||||
.try_collect()?;
|
|
||||||
Some(SetData { teams, winner })
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.flatten()
|
|
||||||
.collect();
|
|
||||||
Some(TournamentData {
|
|
||||||
name: tour.name?,
|
|
||||||
sets,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
67
src/sync.rs
Normal file
67
src/sync.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
use crate::datasets::*;
|
||||||
|
use crate::queries::*;
|
||||||
|
use sqlite::*;
|
||||||
|
|
||||||
|
// Score calculation
|
||||||
|
|
||||||
|
/// Calculate the collective expected score for each team.
|
||||||
|
fn expected_scores(ratings: &Teams<&mut f64>) -> Vec<f64> {
|
||||||
|
let qs: Vec<f64> = ratings
|
||||||
|
.into_iter()
|
||||||
|
.map(|es| 10_f64.powf(es.iter().map(|x| **x).sum::<f64>() / es.len() as f64 / 400.0))
|
||||||
|
.collect();
|
||||||
|
let sumq: f64 = qs.iter().sum();
|
||||||
|
qs.into_iter().map(|q| q / sumq).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adjust the ratings of each player based on who won.
|
||||||
|
fn adjust_ratings(ratings: Teams<&mut f64>, winner: usize) {
|
||||||
|
let exp_scores = expected_scores(&ratings);
|
||||||
|
|
||||||
|
ratings
|
||||||
|
.into_iter()
|
||||||
|
.zip(exp_scores.into_iter())
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(i, (es, exp_sc))| {
|
||||||
|
let len = es.len() as f64;
|
||||||
|
let score = f64::from(winner == i);
|
||||||
|
es.into_iter()
|
||||||
|
.for_each(|e| *e += 40.0 * (score - exp_sc) / len);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract set data
|
||||||
|
|
||||||
|
fn get_event_sets(event: EventId, auth: &str) -> Option<Vec<SetData>> {
|
||||||
|
let sets = run_query::<EventSets, _>(EventSetsVars {
|
||||||
|
event,
|
||||||
|
sets_page: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> sqlite::Result<()> {
|
||||||
|
let players_data = results.teams;
|
||||||
|
add_players(connection, dataset, &players_data)?;
|
||||||
|
|
||||||
|
let mut elos = get_ratings(connection, dataset, &players_data)?;
|
||||||
|
adjust_ratings(
|
||||||
|
elos.iter_mut()
|
||||||
|
.map(|v| v.iter_mut().map(|x| &mut x.1).collect())
|
||||||
|
.collect(),
|
||||||
|
results.winner,
|
||||||
|
);
|
||||||
|
update_ratings(connection, dataset, elos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_from_tournament(
|
||||||
|
connection: &Connection,
|
||||||
|
dataset: &str,
|
||||||
|
results: TournamentData,
|
||||||
|
) -> sqlite::Result<()> {
|
||||||
|
results
|
||||||
|
.sets
|
||||||
|
.into_iter()
|
||||||
|
.try_for_each(|set| update_from_set(connection, dataset, set))
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Reference in a new issue