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:
@@ -21,6 +21,22 @@ public class JunctionFillerTests
|
||||
public int Next(int maxExclusive) => Math.Max(0, maxExclusive - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Считает броски жребия. Жребий — единственный, кто спрашивает сотню, поэтому по этому числу
|
||||
/// его и отличаем от выбора внутри развилки, который спрашивает сумму весов.
|
||||
/// </summary>
|
||||
private sealed class CountingRandom : IRandomSource
|
||||
{
|
||||
public int Rolls { get; private set; }
|
||||
|
||||
public int Next(int maxExclusive)
|
||||
{
|
||||
if (maxExclusive == 100)
|
||||
Rolls++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static PlanningUnit Unit(double minutes, Guid? showId = null, int index = 0) =>
|
||||
new(Guid.NewGuid(), TimeSpan.FromMinutes(minutes), showId ?? Guid.NewGuid(), index);
|
||||
|
||||
@@ -318,6 +334,43 @@ public class JunctionFillerTests
|
||||
Assert.DoesNotContain(byLast.Items, i => i.Kind == PlannedItemKind.Ad);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Choice_RollsChanceOnce_ForTheWholeFork()
|
||||
{
|
||||
// Три заставки в одной развилке — это один выбор, а не три независимых. Бросок жребия
|
||||
// на каждую превратил бы «показать в 60 % случаев» в «показать хоть какую-то почти всегда».
|
||||
var element = Series(2, 20, out _);
|
||||
var fork = new PlanningJunction(
|
||||
Guid.NewGuid(),
|
||||
[
|
||||
Ads(1, chance: 60, choiceKey: "fork"),
|
||||
Ads(1, chance: 60, choiceKey: "fork"),
|
||||
Ads(1, chance: 60, choiceKey: "fork"),
|
||||
]
|
||||
);
|
||||
|
||||
var random = new CountingRandom();
|
||||
Run(Slot(element, 2, between: fork), random);
|
||||
|
||||
Assert.Equal(1, random.Rolls);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Choice_TakesChanceOfThePickedVariant()
|
||||
{
|
||||
// Жребий бросает уже выбранный вариант: у него шанс ноль — значит развилка молчит целиком,
|
||||
// а не подставляет вместо него соседа с сотней.
|
||||
var element = Series(2, 20, out _);
|
||||
var fork = new PlanningJunction(
|
||||
Guid.NewGuid(),
|
||||
[Ads(1, chance: 0, choiceKey: "fork"), Ads(1, chance: 100, choiceKey: "fork")]
|
||||
);
|
||||
|
||||
var result = Run(Slot(element, 2, between: fork), new FirstAlways());
|
||||
|
||||
Assert.DoesNotContain(result.Items, i => i.Kind == PlannedItemKind.Ad);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MaxTotal_CapsJunctionLength()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user