Economy checks: the consumer walk follows upkeep edges; pin upkeep into a consumer good and a role filler
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8e6fd43d23
commit
da067a34a2
2 changed files with 22 additions and 3 deletions
|
|
@ -411,7 +411,7 @@ public static class EconomyChecks
|
|||
// A processed good owes a consumer use when it is shared (rulings consumer-demand-shared-only, draw-is-one-use). Its uses are
|
||||
// the gear or hull roles, and the rounds some weapon draws, that the goods downstream of it (itself included) fill or are; a
|
||||
// good used as upkeep is shared too. Shared means two or more such uses, or upkeep. A shared good must lead, through the
|
||||
// chain, into a consumer good or a role one names. A good whose every use is one gear role is exempt like its final assembly.
|
||||
// chain (an input edge or an upkeep edge), into a consumer good or a role one names. A good whose every use is one gear role is exempt like its final assembly.
|
||||
// Derived from the recipe graph on every check; depth and distance play no part. Raw goods and the gate count for nothing.
|
||||
public static List<EconomyFault> ConsumerDemand(CultCache catalog)
|
||||
{
|
||||
|
|
@ -424,7 +424,7 @@ public static class EconomyChecks
|
|||
.SelectMany(r => Recipes.RolesOf(catalog.Get(r.Output))).Select(role => role.Name), StringComparer.Ordinal);
|
||||
var upkeep = new HashSet<string>(recipes.Values.SelectMany(r => r.Upkeep).Select(c => c.Commodity.Key.Value), StringComparer.Ordinal);
|
||||
var takenBy = recipes.Values.Where(IsCommodityRecipe)
|
||||
.SelectMany(r => r.Inputs.Select(input => (Input: input.Commodity.Key.Value, Output: r.Output.Key.Value)))
|
||||
.SelectMany(r => r.Inputs.Concat(r.Upkeep).Select(input => (Input: input.Commodity.Key.Value, Output: r.Output.Key.Value)))
|
||||
.ToLookup(edge => edge.Input, edge => edge.Output, StringComparer.Ordinal);
|
||||
var faults = new List<EconomyFault>();
|
||||
foreach (var key in recipes.Keys.OrderBy(k => k, StringComparer.Ordinal))
|
||||
|
|
|
|||
|
|
@ -383,13 +383,32 @@ public sealed class EconomyChecksTests
|
|||
// Fuel is upkeep itself; coke is shared because a good it leads into is.
|
||||
var faults = EconomyChecks.ConsumerDemand(f.Cache);
|
||||
Assert.Equal(new[] { "recipe:commodity:coke", "recipe:commodity:fuel" }, faults.Select(x => x.Record));
|
||||
Assert.Contains("'fuel' leads into upkeep but no use leads into a consumer good.", faults[1].Message);
|
||||
Assert.Contains("'fuel' leads into Plate and upkeep but no use leads into a consumer good.", faults[1].Message);
|
||||
|
||||
f.Good("pot", roles: new[] { ("Casing", 1) });
|
||||
f.EditRecipe("commodity:fuel", r => r.Fills.Add("Casing"));
|
||||
Assert.Empty(EconomyChecks.ConsumerDemand(f.Cache));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConsumerDemandFollowsUpkeepIntoAConsumerGoodAndIntoAFillerOfItsRole()
|
||||
{
|
||||
using var f = new EconomyFixture();
|
||||
f.Good("ore");
|
||||
f.Good("coolant", inputs: new[] { ("ore", 1) });
|
||||
Assert.Equal(new[] { "recipe:commodity:coolant" }, DemandRecords(f));
|
||||
|
||||
// The refrigerator is a consumer good (a commodity made from roles) that takes coolant as upkeep: coolant leads into it.
|
||||
f.Good("fridge", roles: new[] { ("Casing", 1) }, upkeep: new[] { ("coolant", 1) });
|
||||
Assert.Empty(DemandRecords(f));
|
||||
|
||||
// Upkeep taken by a filler of a consumer role leads into that role the same way.
|
||||
f.EditRecipe("commodity:fridge", r => r.Upkeep.Clear());
|
||||
Assert.Equal(new[] { "recipe:commodity:coolant" }, DemandRecords(f));
|
||||
f.Good("gasket", inputs: new[] { ("ore", 1) }, fills: new[] { "Casing" }, upkeep: new[] { ("coolant", 1) });
|
||||
Assert.Empty(DemandRecords(f));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConsumerDemandCountsADrawnRoundAsOneUse()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue