using System; using System.Collections.Generic; using System.Linq; class ScanCell { public long Id; public int X; public int Y; public double Z; public int Kind; public int State; public string Name; } const int SOL_MIN_X = 4; const int SOL_MAX_X = 9; const int SOL_MIN_Y = 1; const int SOL_MAX_Y = 8; const int PLAY_MIN_X = 8; const int PLAY_MAX_X = 13; const int PLAY_MIN_Y = 14; const int PLAY_MAX_Y = 21; int GetKind(dynamic item) { try { return (int)item.Kind; } catch { return -1; } } int GetState(dynamic item) { try { return int.Parse(item.State?.ToString() ?? "0"); } catch { return 0; } } string GetNameSafe(dynamic item) { try { string n = item.GetName(); return string.IsNullOrWhiteSpace(n) ? "" : n; } catch { return ""; } } bool InRect(int x, int y, int minX, int maxX, int minY, int maxY) { return x >= minX && x <= maxX && y >= minY && y <= maxY; } Log("=== Color State Logger ==="); var all = new List(); foreach (var it in FloorItems) { if (it == null) continue; all.Add(it); } if (all.Count == 0) { Log("ERROR: No floor items."); return; } var solutionRaw = new List(); var playRaw = new List(); foreach (var it in all) { int x = (int)it.Location.X; int y = (int)it.Location.Y; var cell = new ScanCell { Id = (long)it.Id, X = x, Y = y, Z = (double)it.Location.Z, Kind = GetKind(it), State = GetState(it), Name = GetNameSafe(it) }; if (InRect(x, y, SOL_MIN_X, SOL_MAX_X, SOL_MIN_Y, SOL_MAX_Y)) solutionRaw.Add(cell); if (InRect(x, y, PLAY_MIN_X, PLAY_MAX_X, PLAY_MIN_Y, PLAY_MAX_Y)) playRaw.Add(cell); } if (solutionRaw.Count == 0 || playRaw.Count == 0) { Log($"ERROR: Missing board items. Solution={solutionRaw.Count}, Play={playRaw.Count}"); return; } var solKind = solutionRaw.GroupBy(x => x.Kind) .Select(g => new { Kind = g.Key, CoordCount = g.Select(x => x.X + "," + x.Y).Distinct().Count(), Count = g.Count() }) .OrderByDescending(x => x.CoordCount) .ThenByDescending(x => x.Count) .First().Kind; var playKind = playRaw.GroupBy(x => x.Kind) .Select(g => new { Kind = g.Key, CoordCount = g.Select(x => x.X + "," + x.Y).Distinct().Count(), Count = g.Count() }) .OrderByDescending(x => x.CoordCount) .ThenByDescending(x => x.Count) .First().Kind; var solCells = solutionRaw.Where(x => x.Kind == solKind) .GroupBy(x => x.X + "," + x.Y) .Select(g => g.OrderByDescending(x => x.Z).First()) .OrderBy(x => x.Y) .ThenBy(x => x.X) .ToList(); var playCells = playRaw.Where(x => x.Kind == playKind) .GroupBy(x => x.X + "," + x.Y) .Select(g => g.OrderByDescending(x => x.Z).First()) .OrderBy(x => x.Y) .ThenBy(x => x.X) .ToList(); Log($"Solution board kind={solKind} name={solCells.Select(x => x.Name).FirstOrDefault()} cells={solCells.Count}"); Log($"Play board kind={playKind} name={playCells.Select(x => x.Name).FirstOrDefault()} cells={playCells.Count}"); var solStates = solCells.GroupBy(x => x.State).OrderBy(x => x.Key).ToList(); var playStates = playCells.GroupBy(x => x.State).OrderBy(x => x.Key).ToList(); Log("\nStates in solution board:"); foreach (var s in solStates) Log($" state {s.Key}: {s.Count()} tiles"); Log("\nStates in play board:"); foreach (var s in playStates) Log($" state {s.Key}: {s.Count()} tiles"); Log("\nCoordinate -> state (solution board):"); foreach (var c in solCells) Log($" ({c.X},{c.Y}) = {c.State}"); Log("\nCoordinate -> state (play board):"); foreach (var c in playCells) Log($" ({c.X},{c.Y}) = {c.State}"); Log("\nHint: colors are client visuals; script logs exact numeric states."); Log("Use this once, then map state->color manually by looking at one tile per state.");