using Godot; using System.Collections.Generic; using Chessistics.Engine.Model; namespace Chessistics.Scripts.Board; public partial class BoardView : Node2D { public const int CellSize = 80; private readonly Dictionary _cells = new(); private int _width; private int _height; public void BuildBoard(LevelDef level) { // Clear existing children foreach (var child in GetChildren()) child.QueueFree(); _cells.Clear(); _width = level.Width; _height = level.Height; var boardState = BoardState.FromLevel(level); for (int col = 0; col < level.Width; col++) { for (int row = 0; row < level.Height; row++) { var coords = new Coords(col, row); var cellView = new CellView(); cellView.Setup(coords, boardState.GetCell(coords), CellSize); AddChild(cellView); _cells[coords] = cellView; } } // Label productions and demands foreach (var prod in level.Productions) { if (_cells.TryGetValue(prod.Position, out var cell)) cell.SetLabel(prod.Name); } foreach (var demand in level.Demands) { if (_cells.TryGetValue(demand.Position, out var cell)) cell.SetLabel(demand.Name); } } public void BuildBoardFromSnapshot(BoardSnapshot snap) { // Clear existing children foreach (var child in GetChildren()) child.QueueFree(); _cells.Clear(); _width = snap.Width; _height = snap.Height; for (int col = 0; col < snap.Width; col++) { for (int row = 0; row < snap.Height; row++) { var coords = new Coords(col, row); var cellView = new CellView(); cellView.Setup(coords, snap.Grid[col, row], CellSize); AddChild(cellView); _cells[coords] = cellView; } } // Label productions and demands foreach (var prod in snap.Productions) { if (_cells.TryGetValue(prod.Position, out var cell)) cell.SetLabel(prod.Name); } foreach (var demand in snap.Demands) { if (_cells.TryGetValue(demand.Position, out var cell)) cell.SetLabel(demand.Name); } foreach (var transformer in snap.Transformers) { if (_cells.TryGetValue(transformer.Position, out var cell)) cell.SetLabel(transformer.Name); } } public Coords? PixelToCoords(Vector2 localPos) { int col = Mathf.FloorToInt(localPos.X / CellSize); // Cell at row R has top-left Y = -R*CellSize, extending downward. // floor(-Y/Size) != -floor(Y/Size) for non-integers, so use the latter. int row = -Mathf.FloorToInt(localPos.Y / CellSize); var coords = new Coords(col, row); return coords.IsOnBoard(_width, _height) ? coords : null; } public Vector2 CoordsToPixel(Coords coords) { return new Vector2( coords.Col * CellSize + CellSize / 2f, -coords.Row * CellSize + CellSize / 2f ); } public CellView? GetCellView(Coords coords) => _cells.GetValueOrDefault(coords); public void SetHoverCell(Coords? coords) { foreach (var cell in _cells.Values) cell.SetHover(false); if (coords != null && _cells.TryGetValue(coords.Value, out var cellView)) cellView.SetHover(true); } public void ClearHighlights() { foreach (var cell in _cells.Values) cell.SetHighlight(false); } public void HighlightCells(IEnumerable cells, Color color) { foreach (var coords in cells) { if (_cells.TryGetValue(coords, out var cellView)) cellView.SetHighlightColor(color); } } }