Black market merchant shelves, bulk discount, bulk merchants, volume-driven taint, list-all
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d35425933c
commit
d6b344f70b
11 files changed
+279
-60
No files matched your search
@@ -591,44 +591,44 @@ internal static class Program
|
||||
Func<string, long> value = id => 200;
|
||||
var bm = new BlackMarket();
|
||||
bm.RefreshOrders(10, 75, new Rng(5), value);
|
||||
Check(bm.Sellers.Count == Tuning.BmSellerCount && bm.Catalog.Count > 0 && bm.Catalog.Where(l => l.Kind == GoodKind.Contraband).All(l => l.Price == 170), "目录:卖家与订单价(基础价 × 0.85)");
|
||||
Check(BlackMarket.Pay(170, PayMode.Escrow) == 170 + 9 && BlackMarket.Pay(170, PayMode.Advance) == 153, "托管多付 5%,提前放款打九折");
|
||||
Check(bm.Sellers.Count >= Tuning.BmMerchantCount && bm.Catalog.Count > 0 && bm.Catalog.All(l => l.Qty > 0 && l.Price >= 1) && bm.Catalog.Where(l => l.Kind != GoodKind.Gpu).All(l => l.Price >= 200 * bm.Sellers[l.Seller].Factor * 0.97 - 1 && l.Price <= 200 * bm.Sellers[l.Seller].Factor * 1.03 + 1), "目录:商家与单价(基础价 × 商家系数)");
|
||||
Check(BlackMarket.Pay(170, PayMode.Escrow) == 170 + 9 && BlackMarket.Pay(170, PayMode.Advance) == 153 && BlackMarket.OrderTotal(100, 5) == 475 && BlackMarket.OrderTotal(100, 10) == 900 && BlackMarket.OrderTotal(100, 4) == 400, "托管多付 5%,提前放款打九折");
|
||||
var good = new BmSeller { Name = "g", Trades = 100, Rating = 95 };
|
||||
var bad = new BmSeller { Name = "b", Trades = 100, Rating = 95, Scam = true };
|
||||
bm.Sellers.Clear(); bm.Sellers.Add(good); bm.Sellers.Add(bad);
|
||||
var lg = new BmListing { Seller = 0, Item = "x", Price = 1000 };
|
||||
var lb = new BmListing { Seller = 1, Item = "x", Price = 1000 };
|
||||
var lg = new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 1000 };
|
||||
var lb = new BmListing { Qty = 99, Seller = 1, Item = "x", Price = 1000 };
|
||||
var w = new Wallet { Address = "t" };
|
||||
w.Add(Assets.CRT, 10000); w.Taint = 4000; w.Basis = 5000;
|
||||
var o = bm.Place(lb, PayMode.Escrow, w, Assets.CRT, 10, price);
|
||||
Check(o != null && Near(w.Get(Assets.CRT), 10000 - 1050, 1e-9) && w.Taint < 4000 && bm.Place(lg, PayMode.Escrow, w, Assets.CRC, 10, price) == null, "托管下单:扣币、污点留在订单上;不收 CRC");
|
||||
var o = bm.Place(lb, 1, PayMode.Escrow, w, Assets.CRT, 10, price);
|
||||
Check(o != null && Near(w.Get(Assets.CRT), 10000 - 1050, 1e-9) && w.Taint < 4000 && bm.Place(lg, 1, PayMode.Escrow, w, Assets.CRC, 10, price) == null, "托管下单:扣币、污点留在订单上;不收 CRC");
|
||||
double tBefore = 4000;
|
||||
var ev = bm.Night(13, false, w, new Rng(1));
|
||||
Check(ev.Any(e => e.Kind == "scam_refund") && Near(w.Get(Assets.CRT), 10000, 1e-6) && Near(w.Taint, tBefore, 1e-6) && Near(w.Basis, 5000, 1e-6), "骗子卖家 + 托管:退款,污点与成本一并还回(不能借退款洗钱)");
|
||||
var o2 = bm.Place(lb, PayMode.Advance, w, Assets.CRT, 20, price);
|
||||
var o2 = bm.Place(lb, 1, PayMode.Advance, w, Assets.CRT, 20, price);
|
||||
var ev2 = bm.Night(23, false, w, new Rng(2));
|
||||
Check(o2.State == OrderState.Lost && Near(w.Get(Assets.CRT), 10000 - 900, 1e-6), "骗子卖家 + 提前放款:钱没了");
|
||||
var o3 = bm.Place(lg, PayMode.Escrow, w, Assets.CRT, 30, price);
|
||||
var o3 = bm.Place(lg, 1, PayMode.Escrow, w, Assets.CRT, 30, price);
|
||||
Check(bm.Night(31, false, w, new Rng(3)).Count == 0 && o3.State == OrderState.Pending, "没到期不动");
|
||||
int ready = 0, lost = 0;
|
||||
for (int i = 0; i < 400; i++)
|
||||
{
|
||||
var t = new BlackMarket(); t.Sellers.Add(good);
|
||||
var ww = new Wallet(); ww.Add(Assets.CRT, 5000);
|
||||
var oo = t.Place(new BmListing { Seller = 0, Item = "x", Price = 100 }, PayMode.Escrow, ww, Assets.CRT, 1, price);
|
||||
var oo = t.Place(new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 100 }, 1, PayMode.Escrow, ww, Assets.CRT, 1, price);
|
||||
t.Night(oo.DueDay, false, ww, new Rng((ulong)i + 7));
|
||||
if (oo.State == OrderState.Ready) ready++; else lost++;
|
||||
}
|
||||
Check(ready > 340 && lost > 10, $"上门:约 {Tuning.BmInterceptDoor:P0} 被截获(跑路另算):到货 {ready},丢失 {lost}");
|
||||
var c = new BlackMarket(); c.Sellers.Add(good);
|
||||
var cw = new Wallet(); cw.Add(Assets.CRT, 5000);
|
||||
var co = c.Place(new BmListing { Seller = 0, Item = "x", Price = 100 }, PayMode.Escrow, cw, Assets.CRT, 1, price);
|
||||
var co = c.Place(new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 100 }, 1, PayMode.Escrow, cw, Assets.CRT, 1, price);
|
||||
c.Night(co.DueDay, true, cw, new Rng(1));
|
||||
Check(co.State == OrderState.Pending && co.DueDay == 5, "镇压期间到期顺延一天");
|
||||
// 蜜罐期间下单会被追查;受控交付签收记罪证、拒签不记
|
||||
var h = new BlackMarket(); h.Sellers.Add(good); h.HoneypotUntil = 12;
|
||||
var hw = new Wallet(); hw.Add(Assets.CRT, 5000);
|
||||
var ho = h.Place(new BmListing { Seller = 0, Item = "x", Price = 100 }, PayMode.Escrow, hw, Assets.CRT, 10, price);
|
||||
var ho = h.Place(new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 100 }, 1, PayMode.Escrow, hw, Assets.CRT, 10, price);
|
||||
Check(h.Traps.Count == 1 && h.Traps[0].Day == 10 + Tuning.BmTrapDelay, "蜜罐期间下单:记一笔追查");
|
||||
Check(h.Night(h.Traps[0].Day, false, hw, new Rng(3)).Any(e => e.Kind == "trap" && Near(e.Amount, ho.Price, 1e-9)) && h.Traps.Count == 0, "追查到期:产生罪证事件");
|
||||
int ctrl = 0;
|
||||
@@ -636,7 +636,7 @@ internal static class Program
|
||||
{
|
||||
var t2 = new BlackMarket(); t2.Sellers.Add(good);
|
||||
var w2 = new Wallet(); w2.Add(Assets.CRT, 5000);
|
||||
var o2b = t2.Place(new BmListing { Seller = 0, Item = "x", Price = 100 }, PayMode.Escrow, w2, Assets.CRT, 1, price);
|
||||
var o2b = t2.Place(new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 100 }, 1, PayMode.Escrow, w2, Assets.CRT, 1, price);
|
||||
t2.Night(o2b.DueDay, false, w2, new Rng((ulong)i + 99), 0);
|
||||
if (o2b.Controlled) ctrl++;
|
||||
}
|
||||
@@ -648,10 +648,10 @@ internal static class Program
|
||||
// 跑路:托管资金多则概率高;跑路后关闭
|
||||
var r = new BlackMarket(); r.Sellers.Add(good);
|
||||
var rw = new Wallet(); rw.Add(Assets.CRT, 1000000);
|
||||
for (int i = 0; i < 20; i++) r.Place(new BmListing { Seller = 0, Item = "x", Price = 10000 }, PayMode.Escrow, rw, Assets.CRT, 1, price);
|
||||
for (int i = 0; i < 20; i++) r.Place(new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 10000 }, 1, PayMode.Escrow, rw, Assets.CRT, 1, price);
|
||||
Check(r.RugChance > BlackMarketTestRug(), "托管资金越多越容易跑路");
|
||||
r.ClosedUntil = 40;
|
||||
Check(r.Closed(40) && !r.Closed(41) && r.Place(new BmListing { Seller = 0, Item = "x", Price = 1 }, PayMode.Escrow, rw, Assets.CRT, 30, price) == null, "关闭期间不能下单");
|
||||
Check(r.Closed(40) && !r.Closed(41) && r.Place(new BmListing { Qty = 99, Seller = 0, Item = "x", Price = 1 }, 1, PayMode.Escrow, rw, Assets.CRT, 30, price) == null, "关闭期间不能下单");
|
||||
});
|
||||
|
||||
Test("黑市出售", () =>
|
||||
@@ -719,6 +719,40 @@ internal static class Program
|
||||
Check(Near(Tuning.PoneroFee, 0.06, 1e-9) && Near(1 - Math.Pow(1 - Tuning.PoneroFee, 2), 0.12, 0.01), "Ponero 一进一出约 12%");
|
||||
});
|
||||
|
||||
Test("黑市商家", () =>
|
||||
{
|
||||
double sum = 0; int bulk = 0, n = 300;
|
||||
var types = new System.Collections.Generic.HashSet<MerchantType>();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var bm = new BlackMarket();
|
||||
bm.RefreshOrders(20, 75, new Rng((ulong)i + 5), id => 250);
|
||||
sum += bm.CatalogValue;
|
||||
if (bm.Sellers.Any(x => x.Type == MerchantType.Bulk)) bulk++;
|
||||
foreach (var s in bm.Sellers) types.Add(s.Type);
|
||||
if (bm.Sellers.Where(x => x.Type != MerchantType.Bulk).Select(x => x.Type).Distinct().Count() != bm.Sellers.Count(x => x.Type != MerchantType.Bulk)) throw new Exception("同类型商家重复");
|
||||
}
|
||||
double avg = sum / n;
|
||||
Check(avg > 8000 && avg < 40000, $"每周货架总值(游戏里实测平均约 1.4 万,这里用统一基础价 250):平均 {avg:0}");
|
||||
Check(bulk > n * 0.15 && bulk < n * 0.35 && types.Count == 7, $"大宗商家约 {Tuning.BmBulkChance:P0} 的周出现:{bulk}/{n};七种类型都出现过");
|
||||
// 批量下单:折扣、库存扣减
|
||||
Func<string, double> price = a => 1;
|
||||
var m = new BlackMarket(); m.Sellers.Add(new BmSeller { Name = "a", Trades = 100, Type = MerchantType.Mods, Factor = 0.8 });
|
||||
var l = new BmListing { Seller = 0, Item = "x", Price = 100, Qty = 8 };
|
||||
m.Catalog.Add(l);
|
||||
var w = new Wallet(); w.Add(Assets.CRT, 5000);
|
||||
var o = m.Place(l, 5, PayMode.Advance, w, Assets.CRT, 1, price);
|
||||
Check(o != null && o.Count == 5 && o.Price == (int)Math.Round(475 * 0.9) && l.Qty == 3 && m.Catalog.Contains(l), "订 5 件:95 折,再按提前放款打折,库存扣 5");
|
||||
Check(m.Place(l, 4, PayMode.Escrow, w, Assets.CRT, 1, price) == null && m.Place(l, 3, PayMode.Escrow, w, Assets.CRT, 1, price) != null && !m.Catalog.Contains(l), "超过库存不能订;订完下架");
|
||||
var bs = new BmSeller { Type = MerchantType.Bulk };
|
||||
Check(bs.Days == Tuning.BmBulkDays && new BmSeller { Type = MerchantType.Mods }.Days == Tuning.BmDoorDays, "大宗商家送货更久");
|
||||
// 出售量推高污点
|
||||
var b2 = new BlackMarket();
|
||||
double v0 = b2.VolumeTaint(10);
|
||||
b2.Sales.Add(new BmSale { State = SaleState.Sold, Proceeds = 14000, PayDay = 12 });
|
||||
Check(Near(v0, 0, 1e-9) && Near(b2.VolumeTaint(10), Tuning.BmVolumeTaintMax, 1e-9) && b2.VolumeTaint(30) == 0, "近 7 天成交额推高污点,过期不算");
|
||||
});
|
||||
|
||||
Console.WriteLine($"\n{_passed} 通过,{_failed} 失败");
|
||||
return _failed == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user