using AcDream.App.Rendering.Walk;
namespace AcDream.App.Tests.Rendering.Walk;
///
/// S3 chunk 3 (§9.3 T1): +
/// +
/// reproduce frame
/// 2's LC and SC sequences of BOTH OH cathedral captures
/// exactly — order, block membership, and per-block LOD side all pinned in
/// one pass, at the depth the two owner-verified transcripts (S3 §9.1 R2)
/// recorded them.
///
/// Viewer: block f4/18, sq cell (1, 1) (the frame-2 `P`
/// line: x 36.6, y 24.0 — floor(36.6/24)=1, floor(24.0/24)=1).
/// Grid radius (25) — the
/// captured blocks span Chebyshev ring 24 (§9.1 R2 fact i), comfortably
/// inside it. Only the SET of blocks/cells the transcript itself visited is
/// placed on the grid (a real 51×51 window's un-streamed slots stay null
/// exactly the same way in production —
/// skips a null/Outside slot regardless of why it's empty); each block's
/// is set DIRECTLY from the
/// transcript's own LC membership (this test is an ORDER pin, not a second
/// visibility-math proof — that is WalkVisibilityMathTests's
/// job) so is the ONLY production
/// order machinery under test.
///
public sealed class WalkLandCellOrderTests
{
private const int ViewerBlockX = 0xf4;
private const int ViewerBlockY = 0x18;
private const int ViewerSqX = 1;
private const int ViewerSqY = 1;
[Theory]
[InlineData("cathedral-arrival")]
[InlineData("cathedral-leak")]
public void Frame2_ProducedLandCellSequence_MatchesTheCapturedRetailOrderExactly(
string fixtureName)
{
IReadOnlyList frames = WalkOracleTrace.Load(
"docs/research/2026-09-01-overhaul/oh-capture", fixtureName + ".walk");
WalkOracleFrame frame2 = Assert.Single(frames, f => f.Number == 2);
List landCellEvents = frame2.Events
.Where(e => e.Kind is WalkOracleEventKind.LandCell or WalkOracleEventKind.SortCell)
.ToList();
Assert.NotEmpty(landCellEvents);
// Extract the block visit order (first-appearance order = retail's
// OWN far-to-near block sequence) and, per block, its side (from
// the observed SC cell count — every SC-visited block emits
// side² SC turns under AlwaysDrawObjects, R1) and its LC membership.
var blockOrder = new List();
var blockSeen = new HashSet();
var sideByBlock = new Dictionary();
var scCountByBlock = new Dictionary();
var lcMembersByBlock = new Dictionary>();
foreach (WalkOracleEvent e in landCellEvents)
{
uint cellId = e.CellId!.Value;
uint blockPrefix = cellId & 0xFFFF0000u;
uint lodId = cellId & 0xFFFFu;
if (blockSeen.Add(blockPrefix))
{
blockOrder.Add(blockPrefix);
lcMembersByBlock[blockPrefix] = new HashSet();
}
if (e.Kind == WalkOracleEventKind.SortCell)
{
scCountByBlock[blockPrefix] = scCountByBlock.GetValueOrDefault(blockPrefix) + 1;
}
else
{
lcMembersByBlock[blockPrefix].Add(lodId);
}
}
foreach ((uint blockPrefix, int scCount) in scCountByBlock)
{
int side = (int)Math.Round(Math.Sqrt(scCount));
Assert.Equal(scCount, side * side);
sideByBlock[blockPrefix] = side;
// Cross-check against the LOD-by-ring pyramid the ownership
// map's R2 names explicitly (ring 0-1 -> 8, ring 2 -> 4, ring
// 3-4 -> 2, ring >= 5 -> 1) — an independent confirmation that
// the transcript's own per-block cell count matches production's
// ring rule, not just an internally-consistent side count.
int bx = (int)(blockPrefix >> 24) & 0xFF;
int by = (int)(blockPrefix >> 16) & 0xFF;
int ring = Math.Max(Math.Abs(bx - ViewerBlockX), Math.Abs(by - ViewerBlockY));
Assert.Equal(WalkLandscapeAssembler.SideCellCountForRing(ring), side);
}
// Build the synthetic grid: only the transcript-visited blocks are
// populated (production leaves everything else null too), each at
// its REAL grid offset from the viewer block, with the REAL side
// WalkLandscapeAssembler.SideCellCountForRing computed above.
const int midWidth = WalkLandscapeAssembler.GridWidth;
const int midRadius = WalkLandscapeAssembler.MidRadius;
var landscape = new WalkLandscape
{
MidWidth = midWidth,
Blocks = new WalkLandBlock?[midWidth * midWidth],
ViewerBlockX = midRadius,
ViewerBlockY = midRadius,
ViewerCellX = ViewerSqX,
ViewerCellY = ViewerSqY,
};
foreach (uint blockPrefix in blockOrder)
{
int bx = (int)(blockPrefix >> 24) & 0xFF;
int by = (int)(blockPrefix >> 16) & 0xFF;
int gridX = bx - ViewerBlockX + midRadius;
int gridY = by - ViewerBlockY + midRadius;
Assert.InRange(gridX, 0, midWidth - 1);
Assert.InRange(gridY, 0, midWidth - 1);
int side = sideByBlock[blockPrefix];
var block = new WalkLandBlock
{
LandblockId = blockPrefix, SideCellCount = side, MaxZ = 0f, MinZ = 0f,
};
block.EnsureCellArrays();
HashSet lcMembers = lcMembersByBlock[blockPrefix];
for (int cellIndex = 0; cellIndex < side * side; cellIndex++)
{
int coarseX = cellIndex / side;
int coarseY = cellIndex % side;
uint retailLodId = (uint)(coarseX * 8 + coarseY + 1);
block.CellInView[cellIndex] = lcMembers.Contains(retailLodId)
? WalkBoundingType.EntirelyInside
: WalkBoundingType.Outside;
}
block.InView = WalkBoundingType.PartiallyInside; // admitted; never Outside
landscape.Blocks[gridX * midWidth + gridY] = block;
}
// LandWalkOrder.GetBlockOrder + FillCellOrderFarToNear (the ONLY
// production order machinery under test — CheckBlocks is
// deliberately not called; CellInView above is authoritative).
landscape.CalcDrawOrder();
var producedLc = new List();
var producedSc = new List();
for (int i = landscape.BlockDrawCount - 1; i >= 0; i--)
{
WalkLandBlock? block = landscape.Blocks[landscape.BlockDrawList[i]];
if (block is null)
continue;
int cellCount = block.SideCellCount * block.SideCellCount;
for (int k = 0; k < cellCount; k++)
{
int cellIndex = block.DrawArray[k];
int coarseX = cellIndex / block.SideCellCount;
int coarseY = cellIndex % block.SideCellCount;
uint fullId = block.LandblockId | (uint)(coarseX * 8 + coarseY + 1);
if (block.CellInView[cellIndex] != WalkBoundingType.Outside)
producedLc.Add(fullId);
producedSc.Add(fullId); // AlwaysDrawObjects: every cell of an admitted block.
}
}
List expectedLc = landCellEvents
.Where(e => e.Kind == WalkOracleEventKind.LandCell)
.Select(e => e.CellId!.Value)
.ToList();
List expectedSc = landCellEvents
.Where(e => e.Kind == WalkOracleEventKind.SortCell)
.Select(e => e.CellId!.Value)
.ToList();
Assert.Equal(expectedSc, producedSc);
Assert.Equal(expectedLc, producedLc);
}
}