Stage 3: block reward 100, random halving pass-through, RZ800 14kJ, low-tier fakes, tier-mismatch always spotted

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 18:20:30 +08:00
1 parent c9dd900b16
commit 7255befa01
9 files changed
+80 -31

No files matched your search

+34 -14
View File
@@ -89,11 +89,11 @@ internal static class Program
Check(threw, "余额不足时拒绝");
});
Test("挖矿:开局 1 H 每晚约 24.2 信用点;减半在第 90 天", () =>
Test("挖矿:开局 1 H 每晚约 26.9 信用点;减半在第 90 天", () =>
{
var net = new Network();
double perH = net.Mine(1) * Tuning.PscStartPrice;
Check(Near(perH, 24.2, 0.2), $"1 H 每晚约 24.2 信用点(抽成后):{perH:0.00}");
Check(Near(perH, 26.9, 0.2), $"1 H 每晚约 26.9 信用点(抽成后):{perH:0.00}");
for (int d = 1; d <= 89; d++) net.Night(d, 100, 0);
Check(net.Reward == Tuning.BlockReward, "第 89 天还没减半");
net.Night(90, 100, 0);
@@ -261,19 +261,28 @@ internal static class Program
Check(w.AvgBuy("PSC") == null, "清仓后记录清除");
});
Test("市场:减半抬高价格锚(逐日靠拢),减半前一周有预期行情", () =>
Test("市场:减半抬高价格锚(随机幅度,逐日靠拢),减半前一周有预期行情", () =>
{
Check(Near(Market.SupplyTarget(10, Tuning.BlockReward), 1.0, 1e-9), "减半前很远:目标因子 1");
double before = Market.SupplyTarget(89, Tuning.BlockReward), start = Market.SupplyTarget(83, Tuning.BlockReward);
Check(start > 1.0 && before > start && before <= 1 + Tuning.HalvingRamp + 1e-9, $"减半前 7 天逐日抬高,最多 +8%:{start:0.000} → {before:0.000}");
double after = Market.SupplyTarget(91, Tuning.BlockReward / 2);
Check(Near(after, Math.Pow(2, Tuning.HalvingPassThrough), 1e-9), $"减半后目标因子 2^0.6 = {after:0.000}");
var m = new Market();
for (int i = 0; i < 7; i++) m.UpdateSupply(91 + i, Tuning.BlockReward / 2);
Check(m.Supply > 1.0 && m.Supply < after, "逐晚靠拢目标,不一次跳到位");
for (int i = 0; i < 40; i++) m.UpdateSupply(100 + i % 5, Tuning.BlockReward / 2);
Check(Near(m.Supply, after, 0.02), "几十晚后基本到位");
Check(m.Anchor(new MarketEvent[0]) > Tuning.PscStartPrice * 1.4, "锚随之上移");
Check(Near(m.SupplyTarget(10), 1.0, 1e-9), "减半前很远:目标因子 1");
double before = m.SupplyTarget(89), start = m.SupplyTarget(83);
Check(start > 1.0 && before > start && before <= 1 + Tuning.HalvingRamp + 1e-9, $"减半前 7 天逐日抬高,最多 +8%:{start:0.000} → {before:0.000}");
double lo = 1e9, hi = 0;
for (int seed = 1; seed <= 200; seed++)
{
var x = new Market(); x.OnHalving(new Rng((ulong)seed));
lo = Math.Min(lo, x.HalvingLog); hi = Math.Max(hi, x.HalvingLog);
}
Check(lo >= Tuning.HalvingPassMin && hi <= Tuning.HalvingPassMax && hi - lo > 0.5, $"传导指数在区间内且确有变化:{lo:0.00}–{hi:0.00}");
m.OnHalving(new Rng(7UL));
double after = m.SupplyTarget(91);
Check(Near(after, Math.Pow(2, m.HalvingLog), 1e-9), $"减半后目标因子 2^{m.HalvingLog:0.00} = {after:0.000}");
var n = new Market { HalvingLog = m.HalvingLog };
for (int i = 0; i < 7; i++) n.UpdateSupply(91 + i);
Check(n.Supply > 1.0 && n.Supply < after, "逐晚靠拢目标,不一次跳到位");
for (int i = 0; i < 40; i++) n.UpdateSupply(100 + i % 5);
Check(Near(n.Supply, after, 0.02), "几十晚后基本到位");
Check(n.Anchor(new MarketEvent[0]) > Tuning.PscStartPrice * 1.05, "锚随之上移");
});
Test("市场:其他交易对每晚被套利拉向参考价,三角价差收敛", () =>
@@ -406,7 +415,18 @@ internal static class Program
Test("序列号与供电风扇:四档实物特征;序列号按牌子和档次鉴定;指出供电风扇自动改回真实型号", () =>
{
Check(Hardware.FanCount.SequenceEqual(new[] { 1, 2, 3, 3 }) && Hardware.PowerPins.SequenceEqual(new[] { "6", "8", "8", "8+8" }), "低端 6 针单风扇、中端 8 针双风扇、高端 8 针三风扇、旗舰双 8 针三风扇");
Check(Hardware.Specs.Values.Where(x => !x.Asic).All(x => Hardware.Specs.Values.Count(y => !y.Asic && y.Brand == x.Brand && y.Tier == x.Tier) == 1), "每个牌子每个档次只有一个型号");
Check(Hardware.Specs.Values.Where(x => !x.Asic && !x.Scrap).All(x => Hardware.Specs.Values.Count(y => !y.Asic && !y.Scrap && y.Brand == x.Brand && y.Tier == x.Tier) == 1), "每个牌子每个档次只有一个型号(废片不算)");
var rngF = new Rng(99UL); bool lowFake = false, midScrap = false;
for (int i = 0; i < 400; i++)
{
foreach (var c in UsedDealers.Cards(DealerKind.Scammer, 60, rngF))
{
if (c.FakeOf == null) continue;
if (Hardware.Specs[c.Model].Tier == 0 && Hardware.Specs[c.FakeOf].Scrap) lowFake = true;
if (Hardware.Specs[c.Model].Tier > 0 && Hardware.Specs[c.FakeOf].Scrap) midScrap = true;
}
}
Check(lowFake && !midScrap, "低档次的卡也会被冒充(背后是废片),中高档的假卡不用废片");
var real = new Unit { Model = "RZ80", Health = 100, Look = new CardLook { Seed = 7 } };
var t = CardLabels.SerialText(real);
Check(t.StartsWith("MD2-") && CardLabels.Factories("PMD").Contains(int.Parse(t.Substring(4, 2))) && t.Length == 11, $"真卡的序列号:牌子 + 档次码 + 合法工厂码 + 四位流水:{t}");