From 4159bb3f57ce77b8534dd48b6094d46bec43c74d Mon Sep 17 00:00:00 2001 From: Ryan Kramer Date: Sat, 4 Oct 2025 19:33:16 -0500 Subject: [PATCH 1/2] Claude fixed the known bug, but it seems many other bugs remain... --- .../Generators/Hills/AdamantCliffBuilder.cs | 73 ++++++++++--------- src/Blocktavius.Tests/Test1.cs | 2 +- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/Blocktavius.Core/Generators/Hills/AdamantCliffBuilder.cs b/src/Blocktavius.Core/Generators/Hills/AdamantCliffBuilder.cs index aca1ecd..7aecbb9 100644 --- a/src/Blocktavius.Core/Generators/Hills/AdamantCliffBuilder.cs +++ b/src/Blocktavius.Core/Generators/Hills/AdamantCliffBuilder.cs @@ -697,9 +697,7 @@ public Span GetWritableBuffer(int xStart, int runLength) /// /// Holds the state needed to generate a single run. - /// If we succeed, we recurse. - /// If we cannot, we backtrack to an earlier state and rely on the mutable state - /// of the shared PRNG to explore other possible recursions. + /// Uses exhaustive backtracking instead of random sampling with arbitrary retry limits. /// record struct LayerGenerator(Shared shared, int xStart, int y) { @@ -710,65 +708,74 @@ public bool Execute() return true; } - var runLengths = shared.legalRunLengths; + // Get all valid run lengths that can end at valid positions + // Copy to local variables to avoid struct member access in lambda + var backstop = shared.backstop; + var currentXStart = xStart; + var validRunLengths = shared.legalRunLengths + .Where(len => backstop.CanEndRunAt(currentXStart + len)) + .ToList(); - for (int i = 0; i < 5; i++) + if (validRunLengths.Count == 0) { - if (!ChooseRandomRunLength(ref runLengths, out int runLength)) - { - return false; // no valid run lengths remain - } - if (GenerateRunRecursive(runLength)) - { - return true; - } + return false; } - return false; - } + // Shuffle to maintain randomness in appearance while still being exhaustive + shared.prng.Shuffle(validRunLengths); - private bool ChooseRandomRunLength(ref IImmutableSet runLengths, out int runLength) - { - while (runLengths.Any()) + // Try each valid run length exhaustively + foreach (var runLength in validRunLengths) { - runLength = shared.prng.RandomChoice(runLengths.ToArray()); - if (shared.backstop.CanEndRunAt(xStart + runLength)) + // For the first position, there's no Y adjustment + if (xStart == 0) { - return true; + if (TryGenerateRunWithY(runLength, this.y)) + { + return true; + } } else { - runLengths = runLengths.Remove(runLength); + // Try both Y+1 and Y-1 systematically instead of randomly + int[] yChoices = shared.prng.NextInt32(2) == 0 + ? new[] { this.y + 1, this.y - 1 } + : new[] { this.y - 1, this.y + 1 }; + + foreach (var yChoice in yChoices) + { + if (TryGenerateRunWithY(runLength, yChoice)) + { + return true; + } + } } } - runLength = int.MinValue; return false; } - private bool GenerateRunRecursive(int runLength) + private bool TryGenerateRunWithY(int runLength, int y) { - int y = this.y; - if (xStart > 0) - { - y += shared.prng.RandomChoice(-1, 1); - } - var buffer = shared.GetWritableBuffer(xStart, runLength); + int currentY = y; + + // Try to generate all cells for this run for (int i = 0; i < runLength; i++) { int x = xStart + i; - if (shared.backstop.GetCellForNextLayer(shared.config, x, ref y, shared.LayerId, out var cell)) + if (shared.backstop.GetCellForNextLayer(shared.config, x, ref currentY, shared.LayerId, out var cell)) { buffer[i] = cell; } else { - return false; + return false; // This run doesn't work with this Y } } - var next = new LayerGenerator(shared, xStart + runLength, y); + // Successfully generated this run, try to generate the rest + var next = new LayerGenerator(shared, xStart + runLength, currentY); return next.Execute(); } } diff --git a/src/Blocktavius.Tests/Test1.cs b/src/Blocktavius.Tests/Test1.cs index 39f47a1..ef539c5 100644 --- a/src/Blocktavius.Tests/Test1.cs +++ b/src/Blocktavius.Tests/Test1.cs @@ -52,7 +52,7 @@ public void ExerciseAdamantCliff() var prng = PRNG.Create(new Random()); Console.WriteLine(prng.Serialize()); - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 98765; i++) { var cliff = Core.Generators.Hills.AdamantCliffBuilder.Generate(prng, 100, 60); Assert.IsNotNull(cliff); From 0d0567726b00a99722676bb99e3aaf726ac654fa Mon Sep 17 00:00:00 2001 From: Ryan Kramer Date: Sat, 4 Oct 2025 20:08:26 -0500 Subject: [PATCH 2/2] clarify what this branch fixes --- src/Blocktavius.Tests/Test1.cs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Blocktavius.Tests/Test1.cs b/src/Blocktavius.Tests/Test1.cs index ef539c5..3da5822 100644 --- a/src/Blocktavius.Tests/Test1.cs +++ b/src/Blocktavius.Tests/Test1.cs @@ -52,7 +52,7 @@ public void ExerciseAdamantCliff() var prng = PRNG.Create(new Random()); Console.WriteLine(prng.Serialize()); - for (int i = 0; i < 98765; i++) + for (int i = 0; i < 1000; i++) { var cliff = Core.Generators.Hills.AdamantCliffBuilder.Generate(prng, 100, 60); Assert.IsNotNull(cliff); @@ -60,23 +60,14 @@ public void ExerciseAdamantCliff() } [TestMethod] - public void AdamantCliffKnownBug() + public void AdamantCliffKnownBug() // this particular seed is now fixed { var prng = PRNG.Deserialize("3309110861-16864670-3535033132-2513591414-720943084-1714556781"); - try - { - for (int i = 0; i < 1000; i++) - { - var cliff = Core.Generators.Hills.AdamantCliffBuilder.Generate(prng, 100, 60); - Assert.IsNotNull(cliff); - } - } - catch (Exception) + for (int i = 0; i < 1000; i++) { - Assert.Inconclusive("The known issue in adamant cliff is still present... Fix is not urgent."); - return; + var cliff = Core.Generators.Hills.AdamantCliffBuilder.Generate(prng, 100, 60); + Assert.IsNotNull(cliff); } - Assert.Fail("ATTENTION: Is the bug in Adamant Cliff fixed? Or is it just fixed for this particular seed?"); } [TestMethod]