146 lines
4.6 KiB
C#
146 lines
4.6 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using DG.Tweening;
|
||
using UnityEngine;
|
||
|
||
[RequireComponent(typeof(BoardFitter))]
|
||
public class Board : MonoBehaviour
|
||
{
|
||
[SerializeField] private ChipPointer pointer;
|
||
|
||
[Header("PvP colors")]
|
||
[SerializeField] private Color _pvpInnerColor = new Color(0.2f, 0.65f, 1f, 1f);
|
||
[SerializeField] private Color _pvpOutlineColor = new Color(1f, 0.5f, 0.1f, 1f);
|
||
[SerializeField] private Color _pvpCellsColor = new Color(0.65f, 0.2f, 1f, 1f);
|
||
|
||
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 Sequence GetColorSequence(Color innerColor, Color outlineColor, Color cellsColor, float duration)
|
||
=> fitter.GetColorSequence(innerColor, outlineColor, cellsColor, duration);
|
||
|
||
public void SetColorsImmediately(Color innerColor, Color outlineColor, Color cellsColor)
|
||
=> fitter.SetColorsImmediately(innerColor, outlineColor, cellsColor);
|
||
|
||
public void ApplyPvpColors()
|
||
=> SetColorsImmediately(_pvpInnerColor, _pvpOutlineColor, _pvpCellsColor);
|
||
|
||
public Vector2 GetMiddleStickedPosition() => new Vector2(GetXPosition(Columns/2), config.stickedYOffset);
|
||
|
||
public Vector2 GetStickedPosition(int column) => new Vector2(GetXPosition(column), config.topLeftCell.position.y + config.stickedYOffset);
|
||
|
||
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 DropChip(Chip chip, int column)
|
||
{
|
||
int row = GetLowestEmptyRow(column);
|
||
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 Team[,] GridToTeam()
|
||
{
|
||
Team[,] res = new Team[Rows, Columns];
|
||
for (int row = 0; row < Rows; row++)
|
||
{
|
||
for (int col = 0; col < Columns; col++)
|
||
{
|
||
var chip = Grid[col, row];
|
||
res[row, col] = chip == null ? Team.None : chip.team;
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
private float GetXPosition(int column) => config.topLeftCell.position.x + config.cellOffset.x * column;
|
||
|
||
private float GetYPosition(int column) => config.topLeftCell.position.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();
|
||
}
|
||
}
|