using System; using UnityEngine; public enum CellState { Empty, Player1, Player2 } public class FieldModel { //двумерный массив для поля public CellState[,] fieldArr; public int height, width; // Кешированные массивы для избежания аллокаций private static readonly int[] tempIndexesRow = new int[4]; private static readonly int[] tempIndexesColumn = new int[4]; public FieldModel(int width, int height) { //0 индекс для строк, 1 индекс для столбцов this.width = width; this.height = height; makeEmptyField(width, height); } public void makeEmptyField(int width, int height) { fieldArr = new CellState[height, width]; Array.Clear(fieldArr, 0, fieldArr.Length); } //Основные проверки с развернутым результатом public CheckResult check(int row, int col) { CheckResult result; result = checkRow(row); if (result.end) return result; result = checkColumn(col); if (result.end) return result; result = checkDiagonalDownUp(row, col); if (result.end) return result; result = checkDiagonalUpDown(row, col); if (result.end) return result; if (checkDraw()) { return new CheckResult(true, true); } return result; } public CheckResult checkRow(int row) { CellState currentPlayer = GameManager.instance.currentPlayer; int lineLength = 0; for (int col = 0; col < width; col++) { CellState cell = fieldArr[row, col]; if (cell != currentPlayer) { lineLength = 0; continue; } lineLength++; if (lineLength == 4)//нашли ряд из 4 фишек { //массивы чтобы запомнить из-за какой комбинации произошла победа //int[] indexesRow = new int[4]; //int[] indexesColumn = new int[4]; for (int i = 0; i < 4; i++) { //indexesColumn[i] = col - i; //indexesRow[i] = row; tempIndexesColumn[i] = col - i; tempIndexesRow[i] = row; } return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn); } } return new CheckResult(false, false);//не нашли комбинацию } public CheckResult checkColumn(int column) { CellState currentPlayer = GameManager.instance.currentPlayer; int lineLength = 0; for (int row = height - 1; row >= 0; row--) { CellState cell = fieldArr[row, column]; if (cell != currentPlayer) { lineLength = 0; continue; } lineLength++; if (lineLength == 4)//нашли ряд из 4 фишек { for (int i = 0; i < 4; i++) { tempIndexesColumn[i] = column; tempIndexesRow[i] = row + i; } return new CheckResult(true,false,tempIndexesRow, tempIndexesColumn); } } return new CheckResult(false, false);//не нашли комбинацию } public CheckResult checkDiagonalDownUp(int row, int col) { CellState currentPlayer = GameManager.instance.currentPlayer; int sum = row + col; // Диагональ слишком короткая, если сумма меньше минимальной (3) или больше максимальной (height+width-4) if (sum < 3 || sum > height + width - 4) return new CheckResult(false, false); // Вычисляем начальную точку диагонали int startRow = Mathf.Clamp(sum, 0, height - 1); int startCol = Mathf.Clamp(sum - (height - 1), 0, width - 1); int lineLength = 0; for (row = startRow, col = startCol; row >= 0 && col < width; row--, col++) { CellState cell = fieldArr[row, col]; if (cell != currentPlayer) { lineLength = 0; continue; } lineLength++; if (lineLength == 4) { for (int i = 0; i < 4; i++) { tempIndexesRow[i] = row + i; tempIndexesColumn[i] = col - i; } return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn); } } return new CheckResult(false, false); } public CheckResult checkDiagonalUpDown(int row, int col) { CellState currentPlayer = GameManager.instance.currentPlayer; int sub = row - col; // Начальная точка диагонали, проходящей через (row, col) int startRow = sub >= 0 ? sub : 0; int startCol = sub >= 0 ? 0 : -sub; int lineLength = 0; for (row = startRow, col = startCol; row < height && col < width; row++, col++) { CellState cell = fieldArr[row, col]; if (cell != currentPlayer) { lineLength = 0; continue; } lineLength++; if (lineLength == 4) { for (int i = 0; i < 4; i++) { tempIndexesColumn[i] = col - i; tempIndexesRow[i] = row - i; } return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn); } } return new CheckResult(false, false); } public int getHeight(int colIndex) { //перебираем ряды для выбранной колонки //ищем самый нижний слот в колонке, куда можем вставить фишку for (int row = height-1; row >= 0; row--) { if (fieldArr[row, colIndex] == CellState.Empty) { return row; } } return -1;//если не нашли, то больше добавить нельзя } //проверка ничьей public bool checkDraw() { for (int col = 0; col < width; col++) { //если есть хоть одна непустая колонка то игра продолжается if (getHeight(col) != -1) return false; } return true; } }