using System; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(BoardFitter))] public class Board : MonoBehaviour { [SerializeField] private ChipPointer pointer; private BoardFitter fitter; private BoardConfiguration config; public static Board Instance { get; private set; } public Chip[,] Grid { get; private set; } public int Columns { get; private set; } public int Rows { get; private set; } public int MovesCount { get; private set; } public void Init() { if (TryGetComponent(out BoardFitter fitter)) this.fitter = fitter; else throw new InvalidOperationException("Не найден fitter на доске"); Instance = this; ApplySettings(); SettingsManager.OnSettingsChanged.AddListener(ApplySettings); } public Vector2 GetStickedPosition(int column) => new Vector2(GetXPosition(column), config.stickedY); public Vector2 GetTargetPosition(int column) => new Vector2(GetXPosition(column), GetYPosition(column)); public void MakeClearField() { PerformChipsClear(); MovesCount = 0; Grid = new Chip[Columns, Rows]; } public bool CanDrop(int column) => Grid[column, 0] == null; public void AttachChipToGrid(Chip chip, int column, int row) { if (column < 0 || column >= Columns) { Debug.LogError($"Попытка поставить фишку в колонку {column}. Колонок: {Columns}"); return; } if (row < 0 || row >= Rows) { Debug.LogError($"Попытка поставить фишку в ряд {row}. Рядов: {Rows}"); return; } Grid[column, row] = chip; MovesCount++; } public int[] GetNonFullColumns() { List temp = new(); for (int column = 0; column < Columns; column++) if (CanDrop(column)) temp.Add(column); return temp.ToArray(); } public int GetLowestEmptyRow(int colIndex) { if (colIndex < 0 || colIndex >= Columns) throw new ArgumentOutOfRangeException($"Попытка проверить колонку {colIndex}. Колонок: {Columns}"); for (int row = Rows - 1; row >= 0; row--) if (Grid[colIndex, row] == null) return row; return -1; } public CellState[,] GridToTeam() { CellState[,] res = new CellState[Columns, Rows]; for (int col = 0; col < Columns; col++) { for (int row = 0; row < Rows; row++) { var chip = Grid[col, row]; if (chip == null) res[col, row] = CellState.Empty; else res[col, row] = chip.Team; } } return res; } private float GetXPosition(int column) => config.topLeft.x + config.cellOffset.x * column; private float GetYPosition(int column) => config.topLeft.y - GetLowestEmptyRow(column) * config.cellOffset.y; private void PerformChipsClear() { SoundManager.instance.playExplosion(); GameManager.instance.currentChip?.RemoveFromField(); if (Grid == null) return; foreach (Chip chip in Grid) chip?.RemoveFromField(); } //todo: реализовать private void ApplySettings() { int columns = SettingsManager.GetInt("", 6); int rows = SettingsManager.GetInt("", 5); RebuildBoard(columns, rows); } private void RebuildBoard(int columns, int rows) { Columns = columns; Rows = rows; fitter.FitBoard(columns, rows); config = fitter.GetConfiguration(); MakeClearField(); } }