Refactor JunctionFiller logic to improve eligibility and rolling mechanics
Updated the JunctionFiller class to adjust the eligibility criteria for junction elements, ensuring that the roll for chance is determined after the selection of a variant. Enhanced the Passes method to exclude the rolling logic, which now occurs in a separate Rolls method. This change clarifies the flow of decision-making in junctions and ensures that the chance of the selected variant is accurately represented. Additionally, introduced new tests to validate the updated rolling behavior and its impact on junction processing.
This commit is contained in:
@@ -101,10 +101,12 @@ public static class JunctionFiller
|
||||
|
||||
var (history, random, items) = run;
|
||||
|
||||
var eligible = junction
|
||||
.Elements.Where(e => Passes(e, cursor, placement, history, random))
|
||||
.ToList();
|
||||
var chosen = ResolveChoices(eligible, random);
|
||||
// Жребий бросается после схлопывания развилки, а не вместе с остальными условиями: из пяти
|
||||
// заставок с шансом 60 % каждая бросала бы свой кубик, и «заставка в шести случаях из
|
||||
// десяти» превращалось бы в «какая-нибудь заставка почти всегда». Развилка — это один
|
||||
// выбор, значит и жребий у неё один.
|
||||
var eligible = junction.Elements.Where(e => Passes(e, cursor, placement, history)).ToList();
|
||||
var chosen = ResolveChoices(eligible, random).Where(e => Rolls(e, random)).ToList();
|
||||
|
||||
var available = limit - cursor;
|
||||
if (junction.MaxTotal is { } cap && cap < available)
|
||||
@@ -134,13 +136,15 @@ public static class JunctionFiller
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/// <summary>Проходит ли врезка по своим условиям: смена шоу, интервал, окно суток, жребий.</summary>
|
||||
/// <summary>
|
||||
/// Проходит ли врезка по своим условиям: смена шоу, интервал, окно суток, круглый час. Жребий
|
||||
/// сюда не входит — он бросается после развилки (см. <see cref="Rolls"/>).
|
||||
/// </summary>
|
||||
private static bool Passes(
|
||||
PlanningJunctionElement element,
|
||||
DateTimeOffset cursor,
|
||||
JunctionPlacement placement,
|
||||
JunctionHistory history,
|
||||
IRandomSource random
|
||||
JunctionHistory history
|
||||
)
|
||||
{
|
||||
if (element.OnlyOnElementChange && !placement.ElementChanged)
|
||||
@@ -155,14 +159,19 @@ public static class JunctionFiller
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NearHour(element, cursor, placement.ChannelOffset))
|
||||
return false;
|
||||
|
||||
// Жребий берётся из того же источника, что и весь прогон: он зависит от координат генерации,
|
||||
// поэтому пересборка хвоста не перетасовывает врезки на каждое применение.
|
||||
return element.Chance >= 100 || random.Next(100) < Math.Max(0, element.Chance);
|
||||
return NearHour(element, cursor, placement.ChannelOffset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выпал ли жребий этой врезке. У развилки жребий один на всю метку: бросает уже выбранный
|
||||
/// вариант, и его шанс — это шанс всей развилки.
|
||||
///
|
||||
/// Источник — тот же, что и у всего прогона: он зависит от координат генерации, поэтому
|
||||
/// пересборка хвоста не перетасовывает врезки на каждое применение.
|
||||
/// </summary>
|
||||
private static bool Rolls(PlanningJunctionElement element, IRandomSource random) =>
|
||||
element.Chance >= 100 || random.Next(100) < Math.Max(0, element.Chance);
|
||||
|
||||
/// <summary>
|
||||
/// Рядом ли момент с круглым часом. Сигнал точного времени — «пик-пик-пик» — тем и ценен, что
|
||||
/// звучит в :00, поэтому врезка с допуском ставится только в его окрестности, а не «когда-нибудь
|
||||
|
||||
Reference in New Issue
Block a user