feat: chart-stats scenarios: Gekisou off, every rank, the Perfect play - #1
Merged
Merged
Conversation
- offSeeds: every chart is also measured with Gekisou off, as a solo live (Free Live, Challenge Live) plays: the theoretical best play without Gekisou (every note Perfect at its time), seed 0, the no-skill score, the weights and a check deck on its own generator. A kind whose conditions read the Gekisou state has null weights there; a chart with more than three fevers is measured too. - Ranks: every range carries rankBonusPercents (ranks 1..5 of the song's mission pattern) and every seed rangeWeights[kind][position][range], the range score each measurement run gains, so that a Gekisou live at any ranks follows linearly: the no-skill score exactly (score - sum rankBonus + sum trunc(rangeScore * p(r) / 100)), the weights within two points per range. rankCheck plays the seed's check deck at random ranks through the explicit rank confirmations. A kind whose conditions read the confirmed rank (7012) has no range weights, nor has a chart where a range's bonus can fall inside another range's score frames. - scorePerfect and rangeScorePerfect: one more no-skill play per seed, every Just judged Perfect, for a Just rate between the two. - The Gekisou on numbers and their check decks are unchanged; model gains ranks, perfect and off. - Tests: random ranks against the rank confirmation path (no-skill score exact, a unit weight within two points per range, real decks within the bound), offSeeds against the per-order model, offSeeds of a chart with more than three fevers, kinds on the confirmed rank and on the Gekisou state, the Perfect play. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
chart-stats gains the play scenarios a page needs: Gekisou off (a solo live), a Gekisou live at any ranks, and the Perfect play for a Just rate. The format stays
ournotes-deck.chart-stats/2: fields are only added; every existing number and check deck is unchanged.Changes (
src/chartstats.rs)offSeeds(per chart, one seed): the live with Gekisou off, as Free Live and Challenge Live play it:JudgementStream::theoretical_best(every note Perfect at its time), seed 0,LiveModel::new+run. Same shape as a seed without the range fields:seed,score,weights[kind][position],check. A kind whose conditions read the Gekisou state fails asUnsupportedwithout Gekisou and getsnullweights instead of failing the chart; the off check deck draws only from the other kinds, on its own generator. A chart with more than three fevers (unplayablewith Gekisou) is measured here too.ranges[].rankBonusPercents(ranks 1..5 of the mission pattern;rankBonusPercentstays =[0]) andseeds[].rangeWeights[kind][position][range], the range score each existing measurement run gains per unit of power and factor (no extra runs). The rank bonus istrunc(rangeScore * p / 100), a fixed score in the frame of the range end that changes no factor and no note score, and a later range holds it at both ends of its score, so:score_r = score - sum_i rankBonus_i + sum_i trunc(rangeScore_i * p_i(r_i) / 100)exactly (SeedStats::score_at_ranks);weights_r[kind][k] = weights[kind][k] + sum_i (p_i(r_i) - p_i(1)) / 100 * rangeWeights[kind][k][i], within2 * ranges / POWERper unit of factor (SeedStats::weights_at_ranks).seeds[].rankCheck {ranks, exact, predicted, bound}: the seed's check deck at random ranks throughnew_gekisou_external+queue_gekisou_rank_confirmation; a deviation beyond the bound fails the chart, likecheck.nullrange weights; a chart where a range's bonus frame lies inside another range's score frames (frame(start_j) < frame(end_i) <= frame(end_j), i.e. overlapping ranges) getsrangeWeights: null.seeds[].scorePerfectandseeds[].ranges[].rangeScorePerfect, one more no-skill run per seed on the same play with every Just judged Perfect (Just is only enabled inside the Just-count ranges, so nothing else changes). The Perfect play's rank 1 bonus follows fromrangeScorePerfect.modelgainsranks,perfect,off; the existing keys are unchanged.Cost per chart: +1 run per seed (Perfect play), +1 per seed with ranges (rank check), +1 + kinds x positions + 1 for Gekisou off.
Tests
ranks_follow_linearly_on_the_rank_confirmation_path: with a rank table that moves every rank, random ranks on every seed: the no-skill score from the statistics equals the external rank path exactly; a unit 2000 effect at every position is within 6 points (2 per range); real decks at another power are within the bound; rank 1 everywhere givesscoreandweightsbit for bit.off_seeds_match_the_per_order_model: the Gekisou off no-skill score equals the per-order model's; 40 random decks (life-conditioned skills included) at random powers within the flooring bound of the per-order model.more_than_three_fevers_cannot_be_played: such a chart still hasoffSeeds, equal to the per-order model's no-skill score.kinds_on_the_rank_or_the_gekisou_state: a 7012 kind has no range weights, a 7005 kind has no Gekisou off weights and stays out of that check deck.scorePerfect == score, and Gekisou off equals Gekisou on without fevers.cargo fmt --check,cargo clippy --all-targets -- -D warnings,cargo testandcargo test --release: 242 passed, 0 failed (6 ignored, as before).Full TW data through nnnotes
music-data(MetaSekaiLab/nnnotes#5, pinned at this commit; 340 charts, 1376 seeds): every chart measured, every check, off check and rank check within its bound; every old value equal to the file of7e5d84b; at rank 1 everywhere the rank formulas give every seed'sscoreandweightsbit for bit; no kind or chart needed a guard. Expert, no skills: Gekisou off / on median 0.417 (0.211 to 0.633), all rank 5 / all rank 1 median 0.685 (0.610 to 0.782).Generated with Claude Code