using System; using UnityEngine; //using static UnityEngine.Rendering.DebugUI.Table; //кем занят/не занят слот 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); //for (int row = 0; row < height; row++) //{ // for (int col = 0; col < width; col++) // { // fieldArr[row, col] = CellState.Empty; // } //} } //Основные проверки с развернутым результатом 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 < 7; 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 = 5; row >= 0; row--) { CellState cell = fieldArr[row, column]; 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] = column; //indexesRow[i] = row + 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; if (sum <= 2 || sum >=9) //при такой сумме индексов 4 фишки в диагональ не помещаются return new CheckResult(false, false); //считаем индекс начала диагонали (лево низ) int startRow = Mathf.Clamp(sum, 0, 5); int startCol = Mathf.Clamp(sum - 5, 0, 5); 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)//комбинация из 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 + 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; int startRow = Mathf.Clamp(sub, 0, 2); int startCol = Mathf.Abs(Math.Clamp(sub, -3, 0)); //CellState[] diagonalArray = getUpDownDiagonal(row, col); int lineLength = 0; for (row = startRow, col = startCol; row < 6 && col < 7; row++, 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++) {//идем назад и заполняем индексы tempIndexesColumn[i] = col - i; tempIndexesRow[i] = row - i; //indexesColumn[i] = col - i; //indexesRow[i] = row - i; } return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn); } } return new CheckResult(false, false);//не нашли комбинацию } public int getHeight(int colIndex) { //перебираем ряды для выбранной колонки //ищем самый нижний слот в колонке, куда можем вставить фишку for (int row = 5; row >= 0; row--) { if (fieldArr[row, colIndex] == CellState.Empty) { return row; } } return -1;//если не нашли, то больше добавить нельзя } //Оптимизированные проверки для бота /* public bool checkRow(int row, CellState currentPlayer, CellState[,] field) { //Debug.Log("Ряд"); if (field[row, 3] != currentPlayer) return false; int lineLength = 0; for (int i = 0; i < 7; i++) { if (field[row, i] != currentPlayer) { lineLength = 0; continue; } lineLength++; if (lineLength == 4)//нашли ряд из 4 фишек return true; } return true; }*/ //проверка ничьей public bool checkDraw() { for (int col = 0; col < 7; col++) { //если есть хоть одна непустая колонка то игра продолжается if (getHeight(col) != -1) return false; } return true; } /* //Геттеры для разных рядов. Возвращают одномерные массивы CellState[] getRow(int rowIndex) { CellState[] row = new CellState[7]; for (int col = 0; col<7; col++) { row[col] = fieldArr[rowIndex, col]; } return row; } CellState[] getColumn(int colIndex) { CellState[] col = new CellState[6]; for (int row = 0; row < 6; row++) { col[row] = fieldArr[row, colIndex]; } return col; } CellState[] getUpDownDiagonal(int row, int col) { int sub = row - col; if (sub <= -4 || sub >= 3) //при такой разнице индексов 4 фишки в диагональ не помещаются return new CellState[0]; //считаем индекс начала диагонали (лево верх) int startRow = Mathf.Clamp(sub, 0, 2); int startCol = Mathf.Abs(Math.Clamp(sub, -3, 0)); List result = new List();//заранее сложно обсчитать сколько в диагонали элементов, поэтому лист for (row = startRow, col = startCol; row < height && col < width; row++, col++) { result.Add(fieldArr[row, col]); } result.TrimExcess();//Убрать незаполненные позиции return result.ToArray(); } CellState[] getDownUpDiagonal(int row, int col) { int sum = row + col; if (sum <= 2 || sum >= 9) //при такой сумме индексов 4 фишки в диагональ не помещаются return new CellState[0]; //считаем индекс начала диагонали (лево низ) int startRow = Mathf.Clamp(sum, 0, 5); int startCol = Mathf.Clamp(sum - 5, 0, 5); List result = new List();//заранее сложно обсчитать сколько в диагонали элементов, поэтому лист for (row = startRow, col = startCol; row >=0 && col < width; row--, col++) { result.Add(fieldArr[row, col]); } result.TrimExcess();//Убрать незаполненные позиции return result.ToArray(); }*/ }