From ce027737389ed80521807750a148db53108ae062 Mon Sep 17 00:00:00 2001 From: ZHU MINCHAO <48154958+MinchaoZhu@users.noreply.github.com> Date: Tue, 3 Nov 2026 21:53:00 +0800 Subject: [PATCH] Move black market random-detail constants into Tuning Co-Authored-By: Claude Sonnet 5.5 --- src/Decentralized.Domain/BlackMarket.cs | 2 +- src/Decentralized.Domain/BmOrders.cs | 22 +++++++++++----------- src/Decentralized.Domain/Tuning.cs | 6 ++++++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Decentralized.Domain/BlackMarket.cs b/src/Decentralized.Domain/BlackMarket.cs index 460dabe..5234f58 100644 --- a/src/Decentralized.Domain/BlackMarket.cs +++ b/src/Decentralized.Domain/BlackMarket.cs @@ -112,7 +112,7 @@ namespace Decentralized.Domain RefreshedDay = day; Offers.Clear(); foreach (var g in Roll(StockCount(rep), day, rep, rng, value, PriceOf)) - Offers.Add(new BmOffer { Item = g.Item, Kind = g.Kind, Level = g.Level, Price = g.Price, Model = g.Model, FakeOf = g.FakeOf, Health = g.Health, Qty = g.Kind != GoodKind.Contraband || g.Level == 3 ? 1 : rng.Range(1, 3) }); + Offers.Add(new BmOffer { Item = g.Item, Kind = g.Kind, Level = g.Level, Price = g.Price, Model = g.Model, FakeOf = g.FakeOf, Health = g.Health, Qty = g.Kind != GoodKind.Contraband || g.Level == 3 ? 1 : rng.Range(1, Tuning.BmSpotQtyMax) }); return true; } diff --git a/src/Decentralized.Domain/BmOrders.cs b/src/Decentralized.Domain/BmOrders.cs index 147fc5b..131152b 100644 --- a/src/Decentralized.Domain/BmOrders.cs +++ b/src/Decentralized.Domain/BmOrders.cs @@ -123,7 +123,7 @@ namespace Decentralized.Domain private static List AllEntries() => Merchants.Table.Values.SelectMany(x => x).GroupBy(x => x.Id).Select(g => g.First()).ToList(); - private static string[] HighGpus => Hardware.Specs.Values.Where(x => !x.Asic && !x.Scrap && x.Tier >= 3).Select(x => x.Model).ToArray(); + private static string[] HighGpus => Hardware.Specs.Values.Where(x => !x.Asic && !x.Scrap && x.Tier >= Tuning.BmEliteGpuTier).Select(x => x.Model).ToArray(); /// 商家类型对应的货(含货种、库存),违禁品按声望放开等级。个人卖家什么都卖、每件各自定价;尖端店铺只卖贵货。 private List MerchantGoods(int idx, BmSeller s, int day, int rep, Rng rng, Func value) @@ -139,14 +139,14 @@ namespace Decentralized.Domain int qty = s.Type == MerchantType.Bulk ? rng.Range(Tuning.BmBulkQtyMin, Tuning.BmBulkQtyMax) : s.Type == MerchantType.Elite ? rng.Range(1, Tuning.BmEliteQtyMax) : s.Type == MerchantType.Personal ? rng.Range(1, Tuning.BmPersonalQtyMax) - : s.Type == MerchantType.GpuNew ? rng.Range(Math.Max(1, Tuning.BmQtyMin - 1), Tuning.BmQtyMax - 2) : rng.Range(Tuning.BmQtyMin, Tuning.BmQtyMax); - double factor = s.Type == MerchantType.Personal ? F(rng, Tuning.BmPersonalFactorMin, Tuning.BmPersonalFactorMax) : s.Factor * F(rng, 0.97, 1.03); + : s.Type == MerchantType.GpuNew ? rng.Range(Math.Max(1, Tuning.BmQtyMin - Tuning.BmNewGpuQtyMinCut), Tuning.BmQtyMax - Tuning.BmNewGpuQtyMaxCut) : rng.Range(Tuning.BmQtyMin, Tuning.BmQtyMax); + double factor = s.Type == MerchantType.Personal ? F(rng, Tuning.BmPersonalFactorMin, Tuning.BmPersonalFactorMax) : s.Factor * F(rng, 1 - Tuning.BmPriceJitter, 1 + Tuning.BmPriceJitter); BmListing l = null; - bool eliteGpu = s.Type == MerchantType.Elite && rng.Chance(0.4); - bool personalGpu = s.Type == MerchantType.Personal && rng.Chance(0.15); + bool eliteGpu = s.Type == MerchantType.Elite && rng.Chance(Tuning.BmEliteGpuChance); + bool personalGpu = s.Type == MerchantType.Personal && rng.Chance(Tuning.BmPersonalGpuChance); if (gpuKind || eliteGpu || personalGpu) { - bool fresh = s.Type == MerchantType.GpuNew || eliteGpu || (personalGpu && rng.Chance(0.3)); + bool fresh = s.Type == MerchantType.GpuNew || eliteGpu || (personalGpu && rng.Chance(Tuning.BmPersonalGpuNew)); var pool = eliteGpu ? HighGpus : gpus; var c = UsedDealers.Card(pool, fresh ? 0 : Tuning.BmGpuFake, 0, rng); if (fresh) c.Health = 100; @@ -193,21 +193,21 @@ namespace Decentralized.Domain bool personal = t == MerchantType.Personal; bool scam = rng.Chance(personal ? Tuning.BmPersonalScam : Tuning.BmScamSellerShare); // 骗子多半是新号,也有刷过好评的老号;个人卖家都是新号 - bool fresh = personal || (scam ? rng.Chance(0.6) : rng.Chance(0.25)); + bool fresh = personal || (scam ? rng.Chance(Tuning.BmScamFresh) : rng.Chance(Tuning.BmHonestFresh)); double lo = t == MerchantType.Elite ? Tuning.BmFactorEliteMin : t == MerchantType.GpuNew ? Tuning.BmFactorNewMin : t == MerchantType.GpuUsed ? Tuning.BmFactorUsedMin : t == MerchantType.Bulk ? Tuning.BmFactorBulkMin : Tuning.BmFactorMin; double hi = t == MerchantType.Elite ? Tuning.BmFactorEliteMax : t == MerchantType.GpuNew ? Tuning.BmFactorNewMax : t == MerchantType.GpuUsed ? Tuning.BmFactorUsedMax : t == MerchantType.Bulk ? Tuning.BmFactorBulkMax : Tuning.BmFactorMax; var s = new BmSeller { Name = "0x" + rng.NextUInt().ToString("x8").Substring(0, 6), Scam = scam, Type = t, Factor = personal ? 1.0 : F(rng, lo, hi), - Trades = fresh ? rng.Range(0, 12) : rng.Range(25, 220), - Rating = scam && !fresh ? rng.Range(94, 99) : fresh ? rng.Range(70, 100) : rng.Range(90, 99), + Trades = fresh ? rng.Range(0, Tuning.BmFreshTradesMax) : rng.Range(Tuning.BmOldTradesMin, Tuning.BmOldTradesMax), + Rating = scam && !fresh ? rng.Range(Tuning.BmScamOldRatingMin, Tuning.BmScamOldRatingMax) : fresh ? rng.Range(Tuning.BmFreshRatingMin, Tuning.BmFreshRatingMax) : rng.Range(Tuning.BmOldRatingMin, Tuning.BmOldRatingMax), }; Sellers.Add(s); - if (scam && rng.Chance(0.5)) Forum.Add("scam:" + s.Name); + if (scam && rng.Chance(Tuning.BmForumScamHint)) Forum.Add("scam:" + s.Name); } for (int i = 0; i < Sellers.Count; i++) Catalog.AddRange(MerchantGoods(i, Sellers[i], day, rep, rng, value)); - if (RugChance > Tuning.BmRugBase * 3) Forum.Add("rug"); + if (RugChance > Tuning.BmRugBase * Tuning.BmForumRugFactor) Forum.Add("rug"); } /// 目录里全部货按订单价算的总值(信用点),用来核对每周周转量。 diff --git a/src/Decentralized.Domain/Tuning.cs b/src/Decentralized.Domain/Tuning.cs index 8c0d7b3..4c3808c 100644 --- a/src/Decentralized.Domain/Tuning.cs +++ b/src/Decentralized.Domain/Tuning.cs @@ -98,6 +98,12 @@ namespace Decentralized.Domain /// 订单被截获时变成受控交付的概率;每晚某个近期卖家落网的概率。 public const double BmHoneypotBase = 0.01, BmHoneypotPerSecRep = 0.0004, BmHoneypotMax = 0.06, BmControlled = 0.35, BmSellerBust = 0.008; public const int BmHoneypotDays = 6, BmTrapDelay = 4; + /// 商家货架的随机细节:现货每种的库存上限、每件价格的随机抖动(±)、全新矿卡的库存比常规少多少;尖端店铺里卖显卡的概率与显卡档次下限; + /// 个人卖家里卖显卡的概率与其中全新的比例;骗子 / 诚实卖家是新号(成交少、好评随意)的概率;新号与老号的成交数、好评范围;论坛点名骗子的概率; + /// 托管资金推高跑路概率超过基础的几倍时论坛出现"提币变慢"。 + public const int BmSpotQtyMax = 3, BmNewGpuQtyMinCut = 1, BmNewGpuQtyMaxCut = 2, BmEliteGpuTier = 3; + public const double BmPriceJitter = 0.03, BmEliteGpuChance = 0.4, BmPersonalGpuChance = 0.15, BmPersonalGpuNew = 0.3, BmScamFresh = 0.6, BmHonestFresh = 0.25, BmForumScamHint = 0.5, BmForumRugFactor = 3; + public const int BmFreshTradesMax = 12, BmOldTradesMin = 25, BmOldTradesMax = 220, BmScamOldRatingMin = 94, BmScamOldRatingMax = 99, BmFreshRatingMin = 70, BmFreshRatingMax = 100, BmOldRatingMin = 90, BmOldRatingMax = 99; /// 追查记罪证:记入的比例(货款 × 比例)、同一次蜜罐(或一次落网)累计最多记多少。 public const double BmTrapShare = 0.4, BmTrapWindowCap = 400; /// 货架上除违禁品外的两类货:高科技物品(需中档声望)和显卡的出现概率、加价(在现货溢价 / 订单价之外再加),显卡里夹假卡的比例、是全新卡(成色 100、封条完好、不会是假卡)的概率。