128 lines
3.7 KiB
C#
128 lines
3.7 KiB
C#
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 += 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<int> 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(SettingKey.BOARD_COLUMNS);
|
||
int rows = SettingsManager.GetInt(SettingKey.BOARD_ROWS);
|
||
RebuildBoard(columns, rows);
|
||
}
|
||
|
||
private void RebuildBoard(int columns, int rows)
|
||
{
|
||
Columns = columns;
|
||
Rows = rows;
|
||
|
||
fitter.FitBoard(columns, rows);
|
||
config = fitter.GetConfiguration();
|
||
|
||
MakeClearField();
|
||
}
|
||
} |