using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace CheckersSpielBot { public class BoardRenderer { // Frozen brushes — allocated once private static readonly SolidColorBrush BrushLightSquare = MakeBrush(0xEE, 0xEE, 0xEE); private static readonly SolidColorBrush BrushDarkSquare = MakeBrush(0x66, 0x66, 0x66); private static readonly SolidColorBrush BrushSelected = MakeBrush(0xFF, 0xD7, 0x00); private static readonly SolidColorBrush BrushValidMove = MakeBrush(0x4C, 0xAF, 0x50); private static readonly SolidColorBrush BrushMandatory = MakeBrush(0xFF, 0x60, 0x00); private static readonly SolidColorBrush BrushRedPiece = MakeBrush(0xB4, 0x1E, 0x1E); private static readonly SolidColorBrush BrushBluePiece = MakeBrush(0x1E, 0x1E, 0xB4); private static readonly SolidColorBrush BrushKingStar = new SolidColorBrush(Colors.Gold); private static SolidColorBrush MakeBrush(byte r, byte g, byte b) { var br = new SolidColorBrush(Color.FromRgb(r, g, b)); br.Freeze(); return br; } private readonly MainWindow _window; private readonly GameService _game; public BoardRenderer(MainWindow window, GameService game) { _window = window; _game = game; } public void RenderBoard(int selectedRow, int selectedCol, bool hasPieceSelected, bool isChainJumpActive) { for (int row = 0; row < 8; row++) for (int col = 0; col < 8; col++) RenderCell(row, col, selectedRow, selectedCol, hasPieceSelected, isChainJumpActive); UpdatePieceCounts(); } private void RenderCell(int row, int col, int selectedRow, int selectedCol, bool hasPieceSelected, bool isChainJumpActive) { Button btn = GetCellButton(row, col); if (btn == null) return; btn.Background = ResolveCellBackground(row, col, selectedRow, selectedCol, hasPieceSelected, isChainJumpActive); btn.Content = BuildPieceVisual(_game.Board[row, col]); } private SolidColorBrush ResolveCellBackground(int row, int col, int selectedRow, int selectedCol, bool hasPieceSelected, bool isChainJumpActive) { if (hasPieceSelected && selectedRow == row && selectedCol == col) return BrushSelected; if (hasPieceSelected && !isChainJumpActive && IsValidMoveTarget(row, col, selectedRow, selectedCol)) return BrushValidMove; if (!hasPieceSelected && _game.MandatoryCapturePieces.Contains((row, col))) return BrushMandatory; return BoardHelper.IsPlayableSquare(row, col) ? BrushDarkSquare : BrushLightSquare; } private bool IsValidMoveTarget(int row, int col, int selectedRow, int selectedCol) { return _game.GetLegalMoves(selectedRow, selectedCol, capturesOnly: false) .Exists(m => m.DestinationRow == row && m.DestinationCol == col); } private static UIElement? BuildPieceVisual(int piece) { if (piece == 0) return null; bool isRed = BoardHelper.IsRedPiece(piece); bool isKing = BoardHelper.IsKing(piece); var circle = new Ellipse { Width = 42, Height = 42, Fill = isRed ? BrushRedPiece : BrushBluePiece, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; var grid = new Grid(); grid.Children.Add(circle); if (isKing) { grid.Children.Add(new TextBlock { Text = "★", FontSize = 16, Foreground = BrushKingStar, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }); } return grid; } private void UpdatePieceCounts() { var (red, blue) = _game.GetPieceCounts(); _window.RedScoreText.Text = $"Red: {red}"; _window.BlueScoreText.Text = $"Blue: {blue}"; } private Button GetCellButton(int row, int col) => (Button)_window.FindName($"Cell_{row}_{col}"); } }