From 5b094cb9378a8d2057848f3573154312705951ca Mon Sep 17 00:00:00 2001 From: nicidob Date: Sun, 19 Dec 2021 16:10:11 -0500 Subject: [PATCH 1/7] pca-based rookies and linear progs from real data --- .../core/player/developSeason.basketball.ts | 227 +++--------------- .../core/player/genRatings.basketball.ts | 171 +++++++------ 2 files changed, 129 insertions(+), 269 deletions(-) diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index 94b7281dd9..2f872c29d6 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -5,198 +5,36 @@ import type { RatingKey, } from "../../../common/types.basketball"; -type RatingFormula = { - ageModifier: (age: number) => number; - changeLimits: (age: number) => [number, number]; -}; - -const shootingFormula: RatingFormula = { - ageModifier: (age: number) => { - // Reverse most of the age-related decline in calcBaseChange - if (age <= 27) { - return 0; - } - - if (age <= 29) { - return 0.5; - } - - if (age <= 31) { - return 1.5; - } - - return 2; - }, - changeLimits: () => [-3, 13], -}; -const iqFormula: RatingFormula = { - ageModifier: (age: number) => { - if (age <= 21) { - return 4; - } - - if (age <= 23) { - return 3; - } - - // Reverse most of the age-related decline in calcBaseChange - if (age <= 27) { - return 0; - } - - if (age <= 29) { - return 0.5; - } - - if (age <= 31) { - return 1.5; - } - - return 2; - }, - changeLimits: age => { - if (age >= 24) { - return [-3, 9]; - } - - // For 19: [-3, 32] - // For 23: [-3, 12] - return [-3, 7 + 5 * (24 - age)]; - }, -}; -const ratingsFormulas: Record, RatingFormula> = { - stre: { - ageModifier: () => 0, - changeLimits: () => [-Infinity, Infinity], - }, - spd: { - ageModifier: (age: number) => { - if (age <= 27) { - return 0; - } - - if (age <= 30) { - return -2; - } - - if (age <= 35) { - return -3; - } - - if (age <= 40) { - return -4; - } - - return -8; - }, - changeLimits: () => [-12, 2], - }, - jmp: { - ageModifier: (age: number) => { - if (age <= 26) { - return 0; - } - - if (age <= 30) { - return -3; - } - - if (age <= 35) { - return -4; - } - - if (age <= 40) { - return -5; - } - - return -10; - }, - changeLimits: () => [-12, 2], - }, - endu: { - ageModifier: (age: number) => { - if (age <= 23) { - return random.uniform(0, 9); - } - - if (age <= 30) { - return 0; - } - - if (age <= 35) { - return -2; - } - - if (age <= 40) { - return -4; - } - - return -8; - }, - changeLimits: () => [-11, 19], - }, - dnk: { - ageModifier: (age: number) => { - // Like shootingForumla, except for old players - if (age <= 27) { - return 0; - } - - return 0.5; - }, - changeLimits: () => [-3, 13], - }, - ins: shootingFormula, - ft: shootingFormula, - fg: shootingFormula, - tp: shootingFormula, - oiq: iqFormula, - diq: iqFormula, - drb: { - ageModifier: shootingFormula.ageModifier, - changeLimits: () => [-2, 5], - }, - pss: { - ageModifier: shootingFormula.ageModifier, - changeLimits: () => [-2, 5], - }, - reb: { - ageModifier: shootingFormula.ageModifier, - changeLimits: () => [-2, 5], - }, +// (age coefficient, age offset) for mean, than std. dev. +const ratingsFormulas: Record, Array> = { + diq: [0.06, -1.098, 0.0, -0.011], + dnk: [0.029, -0.923, -0.008, 0.342], + drb: [0.064, -1.472, 0.0, 0.0], + endu: [-0.464, 12.505, 0.04, -0.873], + fg: [-0.005, 0.362, -0.004, 0.583], + ft: [0.025, -0.217, 0.003, 0.533], + ins: [0.016, -0.652, -0.034, 1.956], + jmp: [-0.166, 3.191, 0.074, -1.511], + oiq: [-0.042, 1.451, -0.0, 0.014], + pss: [0.04, -0.81, -0.001, 0.064], + reb: [0.045, -1.114, -0.0, 0.004], + spd: [-0.111, 2.399, 0.047, -0.983], + stre: [-0.039, 1.018, 0.001, -0.013], + tp: [0.095, -2.109, -0.009, 1.092], }; const calcBaseChange = (age: number, coachingRank: number): number => { let val: number; - if (age <= 21) { - val = 2; - } else if (age <= 25) { - val = 1; - } else if (age <= 27) { - val = 0; - } else if (age <= 29) { - val = -1; - } else if (age <= 31) { - val = -2; - } else if (age <= 34) { - val = -3; - } else if (age <= 40) { - val = -4; - } else if (age <= 43) { - val = -5; - } else { - val = -6; - } + const base_coef = [-0.174, 4.475, -0.001, 3.455]; - // Noise - if (age <= 23) { - val += helpers.bound(random.realGauss(0, 5), -4, 20); - } else if (age <= 25) { - val += helpers.bound(random.realGauss(0, 5), -4, 10); - } else { - val += helpers.bound(random.realGauss(0, 3), -2, 4); - } + val = base_coef[0] * age + base_coef[1]; + const std_base = base_coef[2] * age + base_coef[3]; + val += helpers.bound( + random.realGauss(0, 0.05 + Math.max(0, std_base)), + -5, + 15, + ); // Modulate by coaching. g.get("numActiveTeams") doesn't exist when upgrading DB, but that doesn't matter if (g.hasOwnProperty("numActiveTeams")) { @@ -230,20 +68,21 @@ const developSeason = ( ratings.hgt += 1; } } + const age_bounds = helpers.bound(age, 19, 50); - const baseChange = calcBaseChange(age, coachingRank); + const baseChange = calcBaseChange(age_bounds, coachingRank); for (const key of helpers.keys(ratingsFormulas)) { - const ageModifier = ratingsFormulas[key].ageModifier(age); - const changeLimits = ratingsFormulas[key].changeLimits(age); + const ageModifier = + ratingsFormulas[key][0] * age_bounds + ratingsFormulas[key][1]; + const ageStd = + ratingsFormulas[key][2] * age_bounds + ratingsFormulas[key][3]; ratings[key] = limitRating( ratings[key] + - helpers.bound( - (baseChange + ageModifier) * random.uniform(0.4, 1.4), - changeLimits[0], - changeLimits[1], - ), + baseChange + + ageModifier + + helpers.bound(random.realGauss(0, 0.05 + Math.max(0, ageStd)), -5, 5), ); } }; diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index e6fa9ac499..a614e9ef4f 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -66,87 +66,108 @@ const genRatings = ( const hgt = heightToRating(wingspanAdjust); heightInInches = Math.round(heightInInches); // Pick type of player (point, wing, or big) based on height - const randType = Math.random(); - let type: keyof typeof typeFactors; + const pca_comp = [ + [ + -0.03352406, 0.12346389, -0.35794756, -0.15434998, -0.3113007, -0.2962055, + 0.34777623, 0.12785922, -0.3111465, -0.11403359, -0.36446682, 0.13955043, + -0.30497047, 0.06144027, -0.38837135, + ], + [ + 0.28366816, 0.30712998, 0.17298037, 0.23822004, 0.03453123, -0.02717308, + 0.16869372, 0.47707278, 0.09103202, 0.21353549, 0.23247957, 0.39476818, + 0.05918039, 0.45708638, -0.06589692, + ], + [ + -0.17455344, 0.3758997, -0.30602956, 0.0244445, 0.30912668, 0.26491034, + 0.26718402, 0.00262062, 0.2510174, 0.03160773, -0.51004165, -0.13338444, + 0.1938457, 0.17691812, 0.29330686, + ], + ]; - if (hgt >= 59) { - // 6'10" or taller - if (randType < 0.01) { - type = "point"; - } else if (randType < 0.05) { - type = "wing"; - } else { - type = "big"; - } - } else if (hgt <= 33) { - // 6'3" or shorter - if (randType < 0.1) { - type = "wing"; - } else { - type = "point"; - } - } else { - // eslint-disable-next-line no-lonely-if - if (randType < 0.03) { - type = "point"; - } else if (randType < 0.3) { - type = "big"; - } else { - type = "wing"; - } - } + const pca1 = 1.64 * hgt - 79.1 + random.realGauss(0, 10); + const pca2 = 0.42 * hgt - 20.12 + random.realGauss(0, 10); + const pca3 = 0.29 * hgt - 13.78 + random.realGauss(0, 10); - // Tall players are less talented, and all tend towards dumb and can't shoot because they are rookies const rawRatings = { - stre: 37, - spd: 40, - jmp: 40, - endu: 17, - ins: 27, - dnk: 27, - ft: 32, - fg: 32, - tp: 32, - oiq: 22, - diq: 22, - drb: 37, - pss: 37, - reb: 37, + diq: + 41.5 + + pca1 * pca_comp[0][0] + + pca2 * pca_comp[1][0] + + pca3 * pca_comp[2][0], + dnk: + 46.8 + + pca1 * pca_comp[0][1] + + pca2 * pca_comp[1][1] + + pca3 * pca_comp[2][1], + drb: + 59.2 + + pca1 * pca_comp[0][2] + + pca2 * pca_comp[1][2] + + pca3 * pca_comp[2][2], + endu: + 35.3 + + pca1 * pca_comp[0][3] + + pca2 * pca_comp[1][3] + + pca3 * pca_comp[2][3], + fg: + 42.9 + + pca1 * pca_comp[0][4] + + pca2 * pca_comp[1][4] + + pca3 * pca_comp[2][4], + ft: + 43.0 + + pca1 * pca_comp[0][5] + + pca2 * pca_comp[1][5] + + pca3 * pca_comp[2][5], + hgt: + 48.1 + + pca1 * pca_comp[0][6] + + pca2 * pca_comp[1][6] + + pca3 * pca_comp[2][6], + ins: + 40.8 + + pca1 * pca_comp[0][7] + + pca2 * pca_comp[1][7] + + pca3 * pca_comp[2][7], + jmp: + 50.7 + + pca1 * pca_comp[0][8] + + pca2 * pca_comp[1][8] + + pca3 * pca_comp[2][8], + oiq: + 40.8 + + pca1 * pca_comp[0][9] + + pca2 * pca_comp[1][9] + + pca3 * pca_comp[2][9], + pss: + 46.1 + + pca1 * pca_comp[0][10] + + pca2 * pca_comp[1][10] + + pca3 * pca_comp[2][10], + reb: + 48.3 + + pca1 * pca_comp[0][11] + + pca2 * pca_comp[1][11] + + pca3 * pca_comp[2][11], + spd: + 51.2 + + pca1 * pca_comp[0][12] + + pca2 * pca_comp[1][12] + + pca3 * pca_comp[2][12], + stre: + 46.9 + + pca1 * pca_comp[0][13] + + pca2 * pca_comp[1][13] + + pca3 * pca_comp[2][13], + tp: + 44.3 + + pca1 * pca_comp[0][14] + + pca2 * pca_comp[1][14] + + pca3 * pca_comp[2][14], }; - // For correlation across ratings, to ensure some awesome players, but athleticism and skill are independent to - // ensure there are some who are elite in one but not the other - const factorAthleticism = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const factorShooting = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const factorSkill = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const factorIns = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const athleticismRatings = ["stre", "spd", "jmp", "endu", "dnk"]; - const shootingRatings = ["ft", "fg", "tp"]; - const skillRatings = ["oiq", "diq", "drb", "pss", "reb"]; // ins purposely left out - for (const key of helpers.keys(rawRatings)) { - const typeFactor = typeFactors[type].hasOwnProperty(key) - ? typeFactors[type][key] - : 1; - let factor = factorIns; - - if (athleticismRatings.includes(key)) { - factor = factorAthleticism; - } else if (shootingRatings.includes(key)) { - factor = factorShooting; - } else if (skillRatings.includes(key)) { - factor = factorSkill; - } - - // For TypeScript - // https://github.com/microsoft/TypeScript/issues/21732 - if (typeFactor === undefined) { - throw new Error("Should never happen"); - } - - rawRatings[key] = limitRating( - factor * typeFactor * random.realGauss(rawRatings[key], 3), - ); + rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.5, 1.2)); } const ratings = { From 76f0d4a47d69cd55057546935a708fec0b1301c5 Mon Sep 17 00:00:00 2001 From: nicidob Date: Mon, 20 Dec 2021 12:20:09 -0500 Subject: [PATCH 2/7] log-space models so everything is a multiplier, and fine-tuned coefficients --- .../core/player/developSeason.basketball.ts | 54 ++++++++++--------- .../core/player/genRatings.basketball.ts | 6 +-- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index 2f872c29d6..2946337f8a 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -7,36 +7,36 @@ import type { // (age coefficient, age offset) for mean, than std. dev. const ratingsFormulas: Record, Array> = { - diq: [0.06, -1.098, 0.0, -0.011], - dnk: [0.029, -0.923, -0.008, 0.342], - drb: [0.064, -1.472, 0.0, 0.0], - endu: [-0.464, 12.505, 0.04, -0.873], - fg: [-0.005, 0.362, -0.004, 0.583], - ft: [0.025, -0.217, 0.003, 0.533], - ins: [0.016, -0.652, -0.034, 1.956], - jmp: [-0.166, 3.191, 0.074, -1.511], - oiq: [-0.042, 1.451, -0.0, 0.014], - pss: [0.04, -0.81, -0.001, 0.064], - reb: [0.045, -1.114, -0.0, 0.004], - spd: [-0.111, 2.399, 0.047, -0.983], - stre: [-0.039, 1.018, 0.001, -0.013], - tp: [0.095, -2.109, -0.009, 1.092], + diq: [0.0026, -0.058, -0.0, 0.0006], + dnk: [0.0021, -0.0556, -0.0004, 0.0115], + drb: [0.0031, -0.0764, 0.0, 0.0], + endu: [-0.0146, 0.392, 0.0025, -0.0572], + fg: [0.0012, -0.0254, -0.0004, 0.0275], + ft: [0.002, -0.0463, -0.0011, 0.0523], + ins: [0.0008, -0.029, 0.0005, 0.016], + jmp: [-0.0058, 0.1244, 0.0068, -0.1686], + oiq: [-0.0004, 0.0183, -0.0001, 0.0018], + pss: [0.0023, -0.0551, -0.0, 0.0002], + reb: [0.0023, -0.0617, -0.0, 0.0002], + spd: [-0.0022, 0.043, 0.0015, -0.0368], + stre: [-0.0001, -0.0, 0.0, 0.0], + tp: [0.0028, -0.0686, -0.0017, 0.0524], }; const calcBaseChange = (age: number, coachingRank: number): number => { let val: number; - const base_coef = [-0.174, 4.475, -0.001, 3.455]; + const base_coef = [-0.0047, 0.1225, 0.0006, 0.0421]; val = base_coef[0] * age + base_coef[1]; const std_base = base_coef[2] * age + base_coef[3]; - val += helpers.bound( - random.realGauss(0, 0.05 + Math.max(0, std_base)), - -5, - 15, + const std_noise = helpers.bound( + random.realGauss(0, Math.max(0.00001, std_base)), + -0.05, + 0.25, ); + val += std_noise; - // Modulate by coaching. g.get("numActiveTeams") doesn't exist when upgrading DB, but that doesn't matter if (g.hasOwnProperty("numActiveTeams")) { const numActiveTeams = g.get("numActiveTeams"); if (numActiveTeams > 1) { @@ -47,7 +47,6 @@ const calcBaseChange = (age: number, coachingRank: number): number => { } } } - return val; }; @@ -78,12 +77,17 @@ const developSeason = ( const ageStd = ratingsFormulas[key][2] * age_bounds + ratingsFormulas[key][3]; + const ageChange = + ageModifier + + helpers.bound( + random.realGauss(0, Math.max(0.00001, ageStd)), + -0.05, + 0.25, + ); ratings[key] = limitRating( - ratings[key] + - baseChange + - ageModifier + - helpers.bound(random.realGauss(0, 0.05 + Math.max(0, ageStd)), -5, 5), + Math.exp(Math.log(Math.max(0.1, ratings[key])) + baseChange + ageChange), ); + //console.log(baseChange,ageChange); } }; diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index a614e9ef4f..2c60e19df7 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -84,9 +84,9 @@ const genRatings = ( ], ]; - const pca1 = 1.64 * hgt - 79.1 + random.realGauss(0, 10); - const pca2 = 0.42 * hgt - 20.12 + random.realGauss(0, 10); - const pca3 = 0.29 * hgt - 13.78 + random.realGauss(0, 10); + const pca1 = 1.64 * hgt - 79.1 + random.realGauss(0, 14.3); + const pca2 = 0.42 * hgt - 20.12 + random.realGauss(0, 16.2); + const pca3 = 0.29 * hgt - 13.78 + random.realGauss(0, 9.2); const rawRatings = { diq: From d61023bd8208afd51f3ae657214e5d2ff9a064e8 Mon Sep 17 00:00:00 2001 From: nicidob Date: Tue, 21 Dec 2021 19:16:01 -0500 Subject: [PATCH 3/7] rebalanced so the top end works okay --- .../core/player/developSeason.basketball.ts | 40 ++++--- .../core/player/genRatings.basketball.ts | 101 +++++------------- 2 files changed, 47 insertions(+), 94 deletions(-) diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index 2946337f8a..fa02946516 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -7,33 +7,33 @@ import type { // (age coefficient, age offset) for mean, than std. dev. const ratingsFormulas: Record, Array> = { - diq: [0.0026, -0.058, -0.0, 0.0006], - dnk: [0.0021, -0.0556, -0.0004, 0.0115], - drb: [0.0031, -0.0764, 0.0, 0.0], - endu: [-0.0146, 0.392, 0.0025, -0.0572], - fg: [0.0012, -0.0254, -0.0004, 0.0275], - ft: [0.002, -0.0463, -0.0011, 0.0523], - ins: [0.0008, -0.029, 0.0005, 0.016], - jmp: [-0.0058, 0.1244, 0.0068, -0.1686], - oiq: [-0.0004, 0.0183, -0.0001, 0.0018], - pss: [0.0023, -0.0551, -0.0, 0.0002], - reb: [0.0023, -0.0617, -0.0, 0.0002], - spd: [-0.0022, 0.043, 0.0015, -0.0368], - stre: [-0.0001, -0.0, 0.0, 0.0], - tp: [0.0028, -0.0686, -0.0017, 0.0524], + diq: [0.0023, -0.0524, -0.0, 0.0003], + dnk: [0.0018, -0.0465, -0.0003, 0.0091], + drb: [0.0026, -0.0648, 0.0, 0.0], + endu: [-0.012, 0.3214, 0.0016, -0.0357], + fg: [0.0011, -0.0236, -0.0004, 0.0191], + ft: [0.0018, -0.0396, -0.0007, 0.0285], + ins: [0.0005, -0.0197, 0.0003, 0.0108], + jmp: [-0.0051, 0.1082, 0.0041, -0.102], + oiq: [-0.0003, 0.0137, -0.0, 0.0014], + pss: [0.0019, -0.046, -0.0, 0.0001], + reb: [0.0019, -0.0506, -0.0, 0.0001], + spd: [-0.002, 0.0402, 0.001, -0.0252], + stre: [-0.0001, -0.0001, 0.0, 0.0], + tp: [0.0024, -0.0596, -0.0012, 0.0385], }; const calcBaseChange = (age: number, coachingRank: number): number => { let val: number; - const base_coef = [-0.0047, 0.1225, 0.0006, 0.0421]; + const base_coef = [-0.0039, 0.1018, 0.0003, 0.0266]; val = base_coef[0] * age + base_coef[1]; const std_base = base_coef[2] * age + base_coef[3]; const std_noise = helpers.bound( random.realGauss(0, Math.max(0.00001, std_base)), -0.05, - 0.25, + 0.35, ); val += std_noise; @@ -79,13 +79,9 @@ const developSeason = ( const ageChange = ageModifier + - helpers.bound( - random.realGauss(0, Math.max(0.00001, ageStd)), - -0.05, - 0.25, - ); + helpers.bound(random.realGauss(0, Math.max(0.00001, ageStd)), -0.2, 0.3); ratings[key] = limitRating( - Math.exp(Math.log(Math.max(0.1, ratings[key])) + baseChange + ageChange), + Math.exp(Math.log(Math.max(1, ratings[key])) + baseChange + ageChange), ); //console.log(baseChange,ageChange); } diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index 2c60e19df7..a44281d83b 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -2,46 +2,7 @@ import genFuzz from "./genFuzz"; import heightToRating from "./heightToRating"; import limitRating from "./limitRating"; import { helpers, random } from "../../util"; -import type { - PlayerRatings, - RatingKey, -} from "../../../common/types.basketball"; - -const typeFactors: Record< - "point" | "wing" | "big", - Partial> -> = { - point: { - jmp: 1.65, - spd: 1.65, - drb: 1.5, - pss: 1.5, - ft: 1.4, - fg: 1.4, - tp: 1.4, - oiq: 1.2, - endu: 1.4, - }, - wing: { - drb: 1.2, - dnk: 1.5, - jmp: 1.4, - spd: 1.4, - ft: 1.2, - fg: 1.2, - tp: 1.2, - }, - big: { - stre: 1.2, - ins: 1.6, - dnk: 1.5, - reb: 1.4, - ft: 0.8, - fg: 0.8, - tp: 0.8, - diq: 1.2, - }, -}; +import type { PlayerRatings } from "../../../common/types.basketball"; /** * Generate initial ratings for a newly-created player. @@ -68,106 +29,102 @@ const genRatings = ( const pca_comp = [ [ - -0.03352406, 0.12346389, -0.35794756, -0.15434998, -0.3113007, -0.2962055, - 0.34777623, 0.12785922, -0.3111465, -0.11403359, -0.36446682, 0.13955043, - -0.30497047, 0.06144027, -0.38837135, + -0.04097378, 0.10708854, -0.37189642, -0.16707005, -0.31409436, + -0.29164582, 0.33714843, 0.10838294, -0.31849462, -0.12487201, -0.3799997, + 0.12642711, -0.30714244, 0.03870837, -0.37182716, ], [ - 0.28366816, 0.30712998, 0.17298037, 0.23822004, 0.03453123, -0.02717308, - 0.16869372, 0.47707278, 0.09103202, 0.21353549, 0.23247957, 0.39476818, - 0.05918039, 0.45708638, -0.06589692, + 0.26861978, 0.3138044, 0.15214671, 0.24289334, 0.03620905, -0.02747153, + 0.19318229, 0.47557852, 0.06119868, 0.21228091, 0.20542903, 0.40515214, + 0.03863032, 0.4684178, -0.07482827, ], [ - -0.17455344, 0.3758997, -0.30602956, 0.0244445, 0.30912668, 0.26491034, - 0.26718402, 0.00262062, 0.2510174, 0.03160773, -0.51004165, -0.13338444, - 0.1938457, 0.17691812, 0.29330686, + -0.18922555, 0.35164002, -0.30484948, 0.02890456, 0.30394453, 0.25071532, + 0.28024483, -0.00872483, 0.26769468, 0.02539012, -0.5109063, -0.14047495, + 0.2038116, 0.17138019, 0.29823953, ], ]; - const pca1 = 1.64 * hgt - 79.1 + random.realGauss(0, 14.3); - const pca2 = 0.42 * hgt - 20.12 + random.realGauss(0, 16.2); - const pca3 = 0.29 * hgt - 13.78 + random.realGauss(0, 9.2); + const pca1 = 1.61 * hgt - 77.92 + random.realGauss(0, 18.0); + const pca2 = 0.51 * hgt - 24.93 + random.realGauss(0, 20.0); + const pca3 = 0.29 * hgt - 14.16 + random.realGauss(0, 10.0); const rawRatings = { diq: - 41.5 + + 41.8 + pca1 * pca_comp[0][0] + pca2 * pca_comp[1][0] + pca3 * pca_comp[2][0], dnk: - 46.8 + + 47.6 + pca1 * pca_comp[0][1] + pca2 * pca_comp[1][1] + pca3 * pca_comp[2][1], drb: - 59.2 + + 49.5 + pca1 * pca_comp[0][2] + pca2 * pca_comp[1][2] + pca3 * pca_comp[2][2], endu: - 35.3 + + 34.3 + pca1 * pca_comp[0][3] + pca2 * pca_comp[1][3] + pca3 * pca_comp[2][3], fg: - 42.9 + + 43.1 + pca1 * pca_comp[0][4] + pca2 * pca_comp[1][4] + pca3 * pca_comp[2][4], ft: - 43.0 + + 43.1 + pca1 * pca_comp[0][5] + pca2 * pca_comp[1][5] + pca3 * pca_comp[2][5], - hgt: - 48.1 + - pca1 * pca_comp[0][6] + - pca2 * pca_comp[1][6] + - pca3 * pca_comp[2][6], + hgt: hgt, ins: - 40.8 + + 41.5 + pca1 * pca_comp[0][7] + pca2 * pca_comp[1][7] + pca3 * pca_comp[2][7], jmp: - 50.7 + + 51.6 + pca1 * pca_comp[0][8] + pca2 * pca_comp[1][8] + pca3 * pca_comp[2][8], oiq: - 40.8 + + 40.7 + pca1 * pca_comp[0][9] + pca2 * pca_comp[1][9] + pca3 * pca_comp[2][9], pss: - 46.1 + + 46.4 + pca1 * pca_comp[0][10] + pca2 * pca_comp[1][10] + pca3 * pca_comp[2][10], reb: - 48.3 + + 48.7 + pca1 * pca_comp[0][11] + pca2 * pca_comp[1][11] + pca3 * pca_comp[2][11], spd: - 51.2 + + 51.8 + pca1 * pca_comp[0][12] + pca2 * pca_comp[1][12] + pca3 * pca_comp[2][12], stre: - 46.9 + + 47.6 + pca1 * pca_comp[0][13] + pca2 * pca_comp[1][13] + pca3 * pca_comp[2][13], tp: - 44.3 + + 44.2 + pca1 * pca_comp[0][14] + pca2 * pca_comp[1][14] + pca3 * pca_comp[2][14], }; for (const key of helpers.keys(rawRatings)) { - rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.5, 1.2)); + rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.78, 1.2)); } const ratings = { From 6241422b7546c85414a2010c7985a6652c0c6b50 Mon Sep 17 00:00:00 2001 From: nicidob Date: Tue, 21 Dec 2021 20:08:05 -0500 Subject: [PATCH 4/7] ovr matching --- src/worker/core/player/developSeason.basketball.ts | 1 + src/worker/core/player/genRatings.basketball.ts | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index fa02946516..5e644574f1 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -47,6 +47,7 @@ const calcBaseChange = (age: number, coachingRank: number): number => { } } } + return val; }; diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index a44281d83b..5560f92a3a 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -45,9 +45,9 @@ const genRatings = ( ], ]; - const pca1 = 1.61 * hgt - 77.92 + random.realGauss(0, 18.0); - const pca2 = 0.51 * hgt - 24.93 + random.realGauss(0, 20.0); - const pca3 = 0.29 * hgt - 14.16 + random.realGauss(0, 10.0); + const pca1 = 1.61 * hgt - 77.92 + random.realGauss(0, 15.4); + const pca2 = 0.51 * hgt - 24.93 + random.realGauss(0, 17.7); + const pca3 = 0.29 * hgt - 14.16 + random.realGauss(0, 9.3); const rawRatings = { diq: @@ -124,7 +124,7 @@ const genRatings = ( }; for (const key of helpers.keys(rawRatings)) { - rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.78, 1.2)); + rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.77, 1.23)); } const ratings = { From 8eb0d93c0715272e5e8ed5105c41b5f8442440ed Mon Sep 17 00:00:00 2001 From: nicidob Date: Wed, 12 Jan 2022 22:32:53 -0500 Subject: [PATCH 5/7] tweaks --- .../core/player/developSeason.basketball.ts | 30 +++++------ .../core/player/genRatings.basketball.ts | 54 +++++++++---------- src/worker/core/player/ovr.basketball.ts | 32 +++++------ 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index 5e644574f1..9cf792ea8e 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -7,26 +7,26 @@ import type { // (age coefficient, age offset) for mean, than std. dev. const ratingsFormulas: Record, Array> = { - diq: [0.0023, -0.0524, -0.0, 0.0003], - dnk: [0.0018, -0.0465, -0.0003, 0.0091], - drb: [0.0026, -0.0648, 0.0, 0.0], - endu: [-0.012, 0.3214, 0.0016, -0.0357], - fg: [0.0011, -0.0236, -0.0004, 0.0191], - ft: [0.0018, -0.0396, -0.0007, 0.0285], - ins: [0.0005, -0.0197, 0.0003, 0.0108], - jmp: [-0.0051, 0.1082, 0.0041, -0.102], - oiq: [-0.0003, 0.0137, -0.0, 0.0014], - pss: [0.0019, -0.046, -0.0, 0.0001], - reb: [0.0019, -0.0506, -0.0, 0.0001], - spd: [-0.002, 0.0402, 0.001, -0.0252], - stre: [-0.0001, -0.0001, 0.0, 0.0], - tp: [0.0024, -0.0596, -0.0012, 0.0385], + diq: [0.0025, -0.056, -0.0, 0.0004], + dnk: [0.002, -0.0518, -0.0003, 0.0104], + drb: [0.0029, -0.0716, 0.0, 0.0], + endu: [-0.0135, 0.3619, 0.002, -0.0458], + fg: [0.0012, -0.0256, -0.0004, 0.0233], + ft: [0.0019, -0.0434, -0.0009, 0.039], + ins: [0.0007, -0.0246, 0.0004, 0.0132], + jmp: [-0.0055, 0.1173, 0.0053, -0.1313], + oiq: [-0.0003, 0.0163, -0.0001, 0.0016], + pss: [0.0021, -0.0512, -0.0, 0.0001], + reb: [0.0022, -0.0569, -0.0, 0.0002], + spd: [-0.0021, 0.0422, 0.0012, -0.0301], + stre: [-0.0001, 0.0, 0.0, 0.0], + tp: [0.0026, -0.0652, -0.0015, 0.0464], }; const calcBaseChange = (age: number, coachingRank: number): number => { let val: number; - const base_coef = [-0.0039, 0.1018, 0.0003, 0.0266]; + const base_coef = [-0.0044, 0.1138, 0.0004, 0.0341]; val = base_coef[0] * age + base_coef[1]; const std_base = base_coef[2] * age + base_coef[3]; diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index 5560f92a3a..73706742fc 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -29,102 +29,102 @@ const genRatings = ( const pca_comp = [ [ - -0.04097378, 0.10708854, -0.37189642, -0.16707005, -0.31409436, - -0.29164582, 0.33714843, 0.10838294, -0.31849462, -0.12487201, -0.3799997, - 0.12642711, -0.30714244, 0.03870837, -0.37182716, + -0.03143667, 0.13151142, -0.35923427, -0.14588372, -0.30707702, + -0.2923038, 0.35577568, 0.13378376, -0.30905554, -0.11226255, -0.36662078, + 0.14404827, -0.3010302, 0.06513013, -0.38604742, ], [ - 0.26861978, 0.3138044, 0.15214671, 0.24289334, 0.03620905, -0.02747153, - 0.19318229, 0.47557852, 0.06119868, 0.21228091, 0.20542903, 0.40515214, - 0.03863032, 0.4684178, -0.07482827, + 0.28741613, 0.2948169, 0.18162839, 0.22216108, 0.04010548, -0.02320695, + 0.16749835, 0.4756356, 0.08802667, 0.21357235, 0.24305432, 0.40340626, + 0.05871636, 0.45862335, -0.05236033, ], [ - -0.18922555, 0.35164002, -0.30484948, 0.02890456, 0.30394453, 0.25071532, - 0.28024483, -0.00872483, 0.26769468, 0.02539012, -0.5109063, -0.14047495, - 0.2038116, 0.17138019, 0.29823953, + 0.17881319, -0.36455768, 0.29882076, -0.03616037, -0.3152401, -0.26787323, + -0.27231044, -0.01128095, -0.2439317, -0.03754768, 0.50334144, 0.13699001, + -0.19139023, -0.1869137, -0.30742782, ], ]; - const pca1 = 1.61 * hgt - 77.92 + random.realGauss(0, 15.4); - const pca2 = 0.51 * hgt - 24.93 + random.realGauss(0, 17.7); - const pca3 = 0.29 * hgt - 14.16 + random.realGauss(0, 9.3); + const pca1 = 1.62 * hgt - 78.12 + random.realGauss(0, 13.3); + const pca2 = 0.4 * hgt - 19.41 + random.realGauss(0, 14.9); + const pca3 = -0.28 * hgt + 13.35 + random.realGauss(0, 9.0); const rawRatings = { diq: - 41.8 + + 41.2 + pca1 * pca_comp[0][0] + pca2 * pca_comp[1][0] + pca3 * pca_comp[2][0], dnk: - 47.6 + + 46.6 + pca1 * pca_comp[0][1] + pca2 * pca_comp[1][1] + pca3 * pca_comp[2][1], drb: - 49.5 + + 49.1 + pca1 * pca_comp[0][2] + pca2 * pca_comp[1][2] + pca3 * pca_comp[2][2], endu: - 34.3 + + 32.1 + pca1 * pca_comp[0][3] + pca2 * pca_comp[1][3] + pca3 * pca_comp[2][3], fg: - 43.1 + + 42.3 + pca1 * pca_comp[0][4] + pca2 * pca_comp[1][4] + pca3 * pca_comp[2][4], ft: - 43.1 + + 42.4 + pca1 * pca_comp[0][5] + pca2 * pca_comp[1][5] + pca3 * pca_comp[2][5], hgt: hgt, ins: - 41.5 + + 40.6 + pca1 * pca_comp[0][7] + pca2 * pca_comp[1][7] + pca3 * pca_comp[2][7], jmp: - 51.6 + + 50.1 + pca1 * pca_comp[0][8] + pca2 * pca_comp[1][8] + pca3 * pca_comp[2][8], oiq: - 40.7 + + 39.7 + pca1 * pca_comp[0][9] + pca2 * pca_comp[1][9] + pca3 * pca_comp[2][9], pss: - 46.4 + + 45.8 + pca1 * pca_comp[0][10] + pca2 * pca_comp[1][10] + pca3 * pca_comp[2][10], reb: - 48.7 + + 48.0 + pca1 * pca_comp[0][11] + pca2 * pca_comp[1][11] + pca3 * pca_comp[2][11], spd: - 51.8 + + 50.7 + pca1 * pca_comp[0][12] + pca2 * pca_comp[1][12] + pca3 * pca_comp[2][12], stre: - 47.6 + + 46.3 + pca1 * pca_comp[0][13] + pca2 * pca_comp[1][13] + pca3 * pca_comp[2][13], tp: - 44.2 + + 44.0 + pca1 * pca_comp[0][14] + pca2 * pca_comp[1][14] + pca3 * pca_comp[2][14], }; for (const key of helpers.keys(rawRatings)) { - rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.77, 1.23)); + rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.8, 1.2)); } const ratings = { diff --git a/src/worker/core/player/ovr.basketball.ts b/src/worker/core/player/ovr.basketball.ts index 4af809df14..e39dd8125d 100644 --- a/src/worker/core/player/ovr.basketball.ts +++ b/src/worker/core/player/ovr.basketball.ts @@ -10,22 +10,22 @@ import type { PlayerRatings } from "../../../common/types.basketball"; const ovr = (ratings: PlayerRatings): number => { // See analysis/player-ovr-basketball const r = - 0.159 * (ratings.hgt - 47.5) + - 0.0777 * (ratings.stre - 50.2) + - 0.123 * (ratings.spd - 50.8) + - 0.051 * (ratings.jmp - 48.7) + - 0.0632 * (ratings.endu - 39.9) + - 0.0126 * (ratings.ins - 42.4) + - 0.0286 * (ratings.dnk - 49.5) + - 0.0202 * (ratings.ft - 47.0) + - 0.0726 * (ratings.tp - 47.1) + - 0.133 * (ratings.oiq - 46.8) + - 0.159 * (ratings.diq - 46.7) + - 0.059 * (ratings.drb - 54.8) + - 0.062 * (ratings.pss - 51.3) + - 0.01 * (ratings.fg - 47.0) + - 0.01 * (ratings.reb - 51.4) + - 48.5; + 0.0935 * ratings.diq + + 0.042 * ratings.dnk + + 0.0969 * ratings.drb + + 0.00725 * ratings.endu + + -0.00948 * ratings.fg + + 0.0488 * ratings.ft + + 0.225 * ratings.hgt + + -0.0143 * ratings.ins + + 0.0502 * ratings.jmp + + 0.0974 * ratings.oiq + + 0.0656 * ratings.pss + + 0.0533 * ratings.reb + + 0.156 * ratings.spd + + 0.0962 * ratings.stre + + 0.105 * ratings.tp + + -6.4; // Fudge factor to keep ovr ratings the same as they used to be (back before 2018 ratings rescaling) // +8 at 68 From 7df4fc6af796dc28e266c9e44e34e6e44cc02ab5 Mon Sep 17 00:00:00 2001 From: nicidob Date: Thu, 13 Jan 2022 21:06:00 -0500 Subject: [PATCH 6/7] sqrt-based progs --- .../core/draft/genPlayersWithoutSaving.ts | 2 +- .../core/player/developSeason.basketball.ts | 38 ++++++------- .../core/player/genRatings.basketball.ts | 54 +++++++++---------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/worker/core/draft/genPlayersWithoutSaving.ts b/src/worker/core/draft/genPlayersWithoutSaving.ts index 291426fc69..f1a552f4f6 100644 --- a/src/worker/core/draft/genPlayersWithoutSaving.ts +++ b/src/worker/core/draft/genPlayersWithoutSaving.ts @@ -158,7 +158,7 @@ const genPlayersWithoutSaving = async ( } // Small chance of making top 4 players (in 70 player draft) special - on average, one per draft class - if (existingPlayers.length === 0) { + if (!isSport("basketball") && existingPlayers.length === 0) { const numSpecialPlayerChances = Math.round((4 / 70) * numPlayers); for (let i = 0; i < numSpecialPlayerChances; i++) { diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index 9cf792ea8e..e446ba6bc0 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -7,33 +7,33 @@ import type { // (age coefficient, age offset) for mean, than std. dev. const ratingsFormulas: Record, Array> = { - diq: [0.0025, -0.056, -0.0, 0.0004], - dnk: [0.002, -0.0518, -0.0003, 0.0104], - drb: [0.0029, -0.0716, 0.0, 0.0], - endu: [-0.0135, 0.3619, 0.002, -0.0458], - fg: [0.0012, -0.0256, -0.0004, 0.0233], - ft: [0.0019, -0.0434, -0.0009, 0.039], - ins: [0.0007, -0.0246, 0.0004, 0.0132], - jmp: [-0.0055, 0.1173, 0.0053, -0.1313], - oiq: [-0.0003, 0.0163, -0.0001, 0.0016], - pss: [0.0021, -0.0512, -0.0, 0.0001], - reb: [0.0022, -0.0569, -0.0, 0.0002], - spd: [-0.0021, 0.0422, 0.0012, -0.0301], - stre: [-0.0001, 0.0, 0.0, 0.0], - tp: [0.0026, -0.0652, -0.0015, 0.0464], + diq: [0.008, -0.18, -0.0, 0.0012], + dnk: [0.006, -0.1601, -0.0009, 0.0317], + drb: [0.0087, -0.2156, 0.0, 0.0], + endu: [-0.0398, 1.0722, 0.0029, -0.0604], + fg: [0.0024, -0.0443, -0.0008, 0.054], + ft: [0.0052, -0.1124, -0.0012, 0.0704], + ins: [0.0027, -0.0933, -0.0006, 0.083], + jmp: [-0.0146, 0.2996, 0.0077, -0.1821], + oiq: [-0.0016, 0.0676, -0.0, 0.0012], + pss: [0.0062, -0.1502, -0.0, 0.0001], + reb: [0.0067, -0.1769, -0.0, 0.0006], + spd: [-0.0079, 0.1606, 0.0033, -0.0793], + stre: [-0.0019, 0.0375, 0.0, 0.0], + tp: [0.0079, -0.1909, -0.0025, 0.1013], }; const calcBaseChange = (age: number, coachingRank: number): number => { let val: number; - const base_coef = [-0.0044, 0.1138, 0.0004, 0.0341]; + const base_coef = [-0.0148, 0.3846, -0.0001, 0.1659]; val = base_coef[0] * age + base_coef[1]; const std_base = base_coef[2] * age + base_coef[3]; const std_noise = helpers.bound( random.realGauss(0, Math.max(0.00001, std_base)), - -0.05, - 0.35, + -0.1, + 0.4, ); val += std_noise; @@ -80,9 +80,9 @@ const developSeason = ( const ageChange = ageModifier + - helpers.bound(random.realGauss(0, Math.max(0.00001, ageStd)), -0.2, 0.3); + helpers.bound(random.realGauss(0, Math.max(0.00001, ageStd)), -0.4, 0.5); ratings[key] = limitRating( - Math.exp(Math.log(Math.max(1, ratings[key])) + baseChange + ageChange), + (Math.sqrt(Math.max(1, ratings[key])) + baseChange + ageChange) ** 2, ); //console.log(baseChange,ageChange); } diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index 73706742fc..0fb6ddaf35 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -29,102 +29,102 @@ const genRatings = ( const pca_comp = [ [ - -0.03143667, 0.13151142, -0.35923427, -0.14588372, -0.30707702, - -0.2923038, 0.35577568, 0.13378376, -0.30905554, -0.11226255, -0.36662078, - 0.14404827, -0.3010302, 0.06513013, -0.38604742, + 0.01143473, 0.18681705, -0.302455, -0.11453141, -0.3093686, -0.3117734, + 0.39198348, 0.17170778, -0.33111817, -0.06919178, -0.31790763, 0.1837728, + -0.29564103, 0.12445679, -0.3635497, ], [ - 0.28741613, 0.2948169, 0.18162839, 0.22216108, 0.04010548, -0.02320695, - 0.16749835, 0.4756356, 0.08802667, 0.21357235, 0.24305432, 0.40340626, - 0.05871636, 0.45862335, -0.05236033, + 0.26099068, 0.32022768, 0.22354284, 0.27015418, 0.08270443, 0.06164626, + 0.00622841, 0.517066, 0.07112398, 0.2629814, 0.2984516, 0.3287413, + 0.06890596, 0.3749461, -0.10794741, ], [ - 0.17881319, -0.36455768, 0.29882076, -0.03616037, -0.3152401, -0.26787323, - -0.27231044, -0.01128095, -0.2439317, -0.03754768, 0.50334144, 0.13699001, - -0.19139023, -0.1869137, -0.30742782, + -0.15255773, 0.38756528, -0.26229388, 0.05008439, 0.28697568, 0.2588261, + 0.33136192, 0.01230466, 0.25432152, 0.04441171, -0.4698831, -0.15000868, + 0.22909337, 0.23237176, 0.28194028, ], ]; - const pca1 = 1.62 * hgt - 78.12 + random.realGauss(0, 13.3); - const pca2 = 0.4 * hgt - 19.41 + random.realGauss(0, 14.9); - const pca3 = -0.28 * hgt + 13.35 + random.realGauss(0, 9.0); + const pca1 = 1.72 * hgt - 83.44 + random.realGauss(0, 0.23) - 0.513; + const pca2 = 0.01 * hgt - 0.47 + random.realGauss(0, 23.1) - 14.78; + const pca3 = 0.34 * hgt - 16.39 + random.realGauss(0, 0.975) + 2.4; const rawRatings = { diq: - 41.2 + + 42.1 + pca1 * pca_comp[0][0] + pca2 * pca_comp[1][0] + pca3 * pca_comp[2][0], dnk: - 46.6 + + 46.5 + pca1 * pca_comp[0][1] + pca2 * pca_comp[1][1] + pca3 * pca_comp[2][1], drb: - 49.1 + + 50.5 + pca1 * pca_comp[0][2] + pca2 * pca_comp[1][2] + pca3 * pca_comp[2][2], endu: - 32.1 + + 32.5 + pca1 * pca_comp[0][3] + pca2 * pca_comp[1][3] + pca3 * pca_comp[2][3], fg: - 42.3 + + 42.5 + pca1 * pca_comp[0][4] + pca2 * pca_comp[1][4] + pca3 * pca_comp[2][4], ft: - 42.4 + + 42.5 + pca1 * pca_comp[0][5] + pca2 * pca_comp[1][5] + pca3 * pca_comp[2][5], hgt: hgt, ins: - 40.6 + + 41.1 + pca1 * pca_comp[0][7] + pca2 * pca_comp[1][7] + pca3 * pca_comp[2][7], jmp: - 50.1 + + 51.0 + pca1 * pca_comp[0][8] + pca2 * pca_comp[1][8] + pca3 * pca_comp[2][8], oiq: - 39.7 + + 40.1 + pca1 * pca_comp[0][9] + pca2 * pca_comp[1][9] + pca3 * pca_comp[2][9], pss: - 45.8 + + 47.3 + pca1 * pca_comp[0][10] + pca2 * pca_comp[1][10] + pca3 * pca_comp[2][10], reb: - 48.0 + + 48.7 + pca1 * pca_comp[0][11] + pca2 * pca_comp[1][11] + pca3 * pca_comp[2][11], spd: - 50.7 + + 51.4 + pca1 * pca_comp[0][12] + pca2 * pca_comp[1][12] + pca3 * pca_comp[2][12], stre: - 46.3 + + 47.6 + pca1 * pca_comp[0][13] + pca2 * pca_comp[1][13] + pca3 * pca_comp[2][13], tp: - 44.0 + + 44.9 + pca1 * pca_comp[0][14] + pca2 * pca_comp[1][14] + pca3 * pca_comp[2][14], }; for (const key of helpers.keys(rawRatings)) { - rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.8, 1.2)); + rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.86, 1.19)); } const ratings = { From ef005e59cc6e5152d1620fbad8399b090d7f6471 Mon Sep 17 00:00:00 2001 From: nicidob Date: Mon, 17 Jan 2022 21:37:06 -0500 Subject: [PATCH 7/7] tweak generation with better settings --- .../core/player/genRatings.basketball.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index 0fb6ddaf35..908a232761 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -29,25 +29,25 @@ const genRatings = ( const pca_comp = [ [ - 0.01143473, 0.18681705, -0.302455, -0.11453141, -0.3093686, -0.3117734, - 0.39198348, 0.17170778, -0.33111817, -0.06919178, -0.31790763, 0.1837728, - -0.29564103, 0.12445679, -0.3635497, + 0.01144491, 0.18678923, -0.30245945, -0.11454368, -0.30940279, + -0.31179763, 0.39192477, 0.17167505, -0.33114137, -0.06918906, + -0.31791678, 0.18375956, -0.29565832, 0.12444836, -0.36355192, ], [ - 0.26099068, 0.32022768, 0.22354284, 0.27015418, 0.08270443, 0.06164626, - 0.00622841, 0.517066, 0.07112398, 0.2629814, 0.2984516, 0.3287413, - 0.06890596, 0.3749461, -0.10794741, + 0.26091959, 0.32038081, 0.22341533, 0.27030209, 0.08278275, 0.06169217, + 0.00644845, 0.5170028, 0.07126779, 0.26298184, 0.29825086, 0.32866972, + 0.06902588, 0.37508656, -0.1078734, ], [ - -0.15255773, 0.38756528, -0.26229388, 0.05008439, 0.28697568, 0.2588261, - 0.33136192, 0.01230466, 0.25432152, 0.04441171, -0.4698831, -0.15000868, - 0.22909337, 0.23237176, 0.28194028, + -0.1527201, 0.38744556, -0.26238251, 0.04986639, 0.28690744, 0.25874772, + 0.33139227, 0.01208661, 0.25434695, 0.0442386, -0.46999709, -0.15012807, + 0.22910478, 0.23225618, 0.2819238, ], ]; - const pca1 = 1.72 * hgt - 83.44 + random.realGauss(0, 0.23) - 0.513; - const pca2 = 0.01 * hgt - 0.47 + random.realGauss(0, 23.1) - 14.78; - const pca3 = 0.34 * hgt - 16.39 + random.realGauss(0, 0.975) + 2.4; + const pca1 = 1.72 * hgt - 83.45 + random.realGauss(0, 0.015) - 0.8; + const pca2 = 0.01 * hgt - 0.48 + random.realGauss(0, 22.3) - 11.1; + const pca3 = 0.34 * hgt - 16.39 + random.realGauss(0, 0.19) + 1.8; const rawRatings = { diq: @@ -66,7 +66,7 @@ const genRatings = ( pca2 * pca_comp[1][2] + pca3 * pca_comp[2][2], endu: - 32.5 + + 32.6 + pca1 * pca_comp[0][3] + pca2 * pca_comp[1][3] + pca3 * pca_comp[2][3], @@ -76,7 +76,7 @@ const genRatings = ( pca2 * pca_comp[1][4] + pca3 * pca_comp[2][4], ft: - 42.5 + + 42.6 + pca1 * pca_comp[0][5] + pca2 * pca_comp[1][5] + pca3 * pca_comp[2][5], @@ -92,7 +92,7 @@ const genRatings = ( pca2 * pca_comp[1][8] + pca3 * pca_comp[2][8], oiq: - 40.1 + + 40.2 + pca1 * pca_comp[0][9] + pca2 * pca_comp[1][9] + pca3 * pca_comp[2][9], @@ -124,7 +124,7 @@ const genRatings = ( }; for (const key of helpers.keys(rawRatings)) { - rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.86, 1.19)); + rawRatings[key] = limitRating(rawRatings[key] * random.uniform(0.81, 1.22)); } const ratings = {