2026-04-10 14:58:03 +02:00
|
|
|
using Godot;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Chessistics.Engine.Model;
|
|
|
|
|
|
|
|
|
|
namespace Chessistics.Scripts.Board;
|
|
|
|
|
|
|
|
|
|
public partial class BoardView : Node2D
|
|
|
|
|
{
|
2026-04-10 21:44:12 +02:00
|
|
|
public const int CellSize = 80;
|
|
|
|
|
|
|
|
|
|
private readonly Dictionary<Coords, CellView> _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 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<Coords> cells, Color color)
|
|
|
|
|
{
|
|
|
|
|
foreach (var coords in cells)
|
|
|
|
|
{
|
|
|
|
|
if (_cells.TryGetValue(coords, out var cellView))
|
|
|
|
|
cellView.SetHighlightColor(color);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-10 14:58:03 +02:00
|
|
|
}
|