0210c14858
PCG32 seeded RNG; immutable 8x8 GridState with occupancy bitmask; placement legality + anyPlacementExists; simultaneous row/col clears with single-count gem credit; combo scoring with one-move grace; weighted-bag generator with pity bias and depth-3 solvability nudge. All TDD, 51 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
62 lines
1.9 KiB
Dart
62 lines
1.9 KiB
Dart
import 'package:block_seasons/core/rng.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
group('SeededRng', () {
|
|
test('same seed produces identical 1000-draw sequence', () {
|
|
final a = SeededRng(8841273);
|
|
final b = SeededRng(8841273);
|
|
for (var i = 0; i < 1000; i++) {
|
|
expect(a.nextInt(1 << 30), b.nextInt(1 << 30));
|
|
}
|
|
});
|
|
|
|
test('different seeds produce different sequences', () {
|
|
final a = SeededRng(1);
|
|
final b = SeededRng(2);
|
|
final drawsA = List.generate(20, (_) => a.nextInt(1 << 30));
|
|
final drawsB = List.generate(20, (_) => b.nextInt(1 << 30));
|
|
expect(drawsA, isNot(equals(drawsB)));
|
|
});
|
|
|
|
test('nextInt stays within [0, max)', () {
|
|
final rng = SeededRng(42);
|
|
for (final max in [1, 2, 3, 7, 40, 1000]) {
|
|
for (var i = 0; i < 2000; i++) {
|
|
final v = rng.nextInt(max);
|
|
expect(v, inInclusiveRange(0, max - 1));
|
|
}
|
|
}
|
|
});
|
|
|
|
test('nextInt eventually covers every value for small max', () {
|
|
final rng = SeededRng(7);
|
|
final seen = <int>{};
|
|
for (var i = 0; i < 1000; i++) {
|
|
seen.add(rng.nextInt(6));
|
|
}
|
|
expect(seen, {0, 1, 2, 3, 4, 5});
|
|
});
|
|
|
|
test('nextDouble stays within [0, 1)', () {
|
|
final rng = SeededRng(99);
|
|
for (var i = 0; i < 5000; i++) {
|
|
final v = rng.nextDouble();
|
|
expect(v, greaterThanOrEqualTo(0.0));
|
|
expect(v, lessThan(1.0));
|
|
}
|
|
});
|
|
|
|
test('fork creates an independent stream that is deterministic', () {
|
|
final a = SeededRng(123).fork(5);
|
|
final b = SeededRng(123).fork(5);
|
|
final c = SeededRng(123).fork(6);
|
|
final drawsA = List.generate(20, (_) => a.nextInt(1 << 30));
|
|
final drawsB = List.generate(20, (_) => b.nextInt(1 << 30));
|
|
final drawsC = List.generate(20, (_) => c.nextInt(1 << 30));
|
|
expect(drawsA, drawsB);
|
|
expect(drawsA, isNot(equals(drawsC)));
|
|
});
|
|
});
|
|
}
|