Files
probably-decentralized/src/Decentralized.Domain/Rng.cs
T
ZHU MINCHAOandClaude Opus 5.5 ce3bed1467 Domain core: seeded RNG, asset registry, wallets, AMM pairs, mining
Pure logic layer with no game references: xoshiro128** RNG with savable
state, asset registry (PSC, CRC, CRT, CRA, SPARK, Ponero), wallets whose
taint and cost basis move with transfers, constant-product pools with
nightly reversion, and mining (Probidia/PMD GPUs, RatDigg ASICs, network
hash response, halving, wear and sudden death). 35 checks pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 08:52:32 +08:00

62 lines
2.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
namespace Decentralized.Domain
{
/// <summary>
/// 带种子、状态可存档的随机数(xoshiro128**)。游戏自己的 RNG 不带种子;mod 的事件、行情、暴毙都用这个,
/// 状态随存档保存,读档后结果不变,测试也能复现。
/// </summary>
public sealed class Rng
{
public uint S0, S1, S2, S3;
public Rng() : this(1) { }
public Rng(ulong seed)
{
// SplitMix64 展开种子
ulong z = seed;
ulong Next()
{
z += 0x9E3779B97F4A7C15UL;
ulong x = z;
x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9UL;
x = (x ^ (x >> 27)) * 0x94D049BB133111EBUL;
return x ^ (x >> 31);
}
ulong a = Next(), b = Next();
S0 = (uint)a; S1 = (uint)(a >> 32); S2 = (uint)b; S3 = (uint)(b >> 32);
if ((S0 | S1 | S2 | S3) == 0) S0 = 1;
}
private static uint Rotl(uint x, int k) => (x << k) | (x >> (32 - k));
public uint NextUInt()
{
uint result = Rotl(S1 * 5, 7) * 9;
uint t = S1 << 9;
S2 ^= S0; S3 ^= S1; S1 ^= S2; S0 ^= S3;
S2 ^= t;
S3 = Rotl(S3, 11);
return result;
}
/// <summary>[0, 1)</summary>
public double NextDouble() => (NextUInt() >> 8) * (1.0 / (1 << 24));
public bool Chance(double p) => NextDouble() < p;
/// <summary>[min, max],含两端。</summary>
public int Range(int min, int max) => min + (int)(NextDouble() * (max - min + 1));
public double Range(double min, double max) => min + NextDouble() * (max - min);
/// <summary>标准正态(Box–Muller)。</summary>
public double Gauss()
{
double u1 = 1.0 - NextDouble(), u2 = NextDouble();
return Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Cos(2.0 * Math.PI * u2);
}
}
}