use super::Wife;
#[allow(clippy::excessive_precision)]
fn ett_erf(x: f32) -> f32 {
let exp = |x| std::f32::consts::E.powf(x);
const A1: f32 = 0.254829592;
const A2: f32 = -0.284496736;
const A3: f32 = 1.421413741;
const A4: f32 = -1.453152027;
const A5: f32 = 1.061405429;
const P: f32 = 0.3275911;
let sign = if x < 0.0 { -1.0 } else { 1.0 };
let x = x.abs();
let t = 1.0 / (1.0 + P * x);
let y = 1.0 - (((((A5 * t + A4) * t) + A3) * t + A2) * t + A1) * t * exp(-x * x);
sign * y
}
pub struct Wife3;
impl Wife3 {
const INNER_MINE_HIT_WEIGHT: f32 = -7.0;
const INNER_HOLD_DROP_WEIGHT: f32 = -4.5;
const INNER_MISS_WEIGHT: f32 = -5.5;
fn calc_inner(deviation: f32, judge: &crate::Judge) -> f32 {
const J_POW: f32 = 0.75;
const MAX_POINTS: f32 = 2.0;
let ts = judge.timing_scale;
let ridic = 5.0 * ts;
let max_boo_weight = 180.0 * ts;
let maxms = (deviation * 1000.0).abs();
if maxms <= ridic {
return MAX_POINTS;
}
let zero = 65.0 * ts.powf(J_POW);
let dev = 22.7 * ts.powf(J_POW);
if maxms <= zero {
MAX_POINTS * ett_erf((zero - maxms) / dev)
} else if maxms <= max_boo_weight {
(maxms - zero) * Self::INNER_MISS_WEIGHT / (max_boo_weight - zero)
} else {
Self::INNER_MISS_WEIGHT
}
}
}
impl Wife for Wife3 {
const MINE_HIT_WEIGHT: f32 = Self::INNER_MINE_HIT_WEIGHT / 2.0;
const HOLD_DROP_WEIGHT: f32 = Self::INNER_HOLD_DROP_WEIGHT / 2.0;
const MISS_WEIGHT: f32 = Self::INNER_MISS_WEIGHT / 2.0;
fn calc_deviation(deviation: f32, judge: &crate::Judge) -> f32 {
Self::calc_inner(deviation, judge) / 2.0 }
}