using System.Collections.Generic; public enum Team { None, Player1, Player2 } public static class FieldChecker { public static Chip[,] FieldArray => Board.Instance.Grid; public static int Height => Board.Instance.Rows; public static int Width => Board.Instance.Columns; public static int TargetLineLength = 4; public static CheckResult lastResult; public static CheckResult Check(Team lastPlayer) { HashSet<(int row, int col)> WinningIndexes = new(); var rowsResult = checkAllRows(lastPlayer); var colsResult = checkAllColumns(lastPlayer); var diagonalsResult = checkAllDiagonals(lastPlayer); bool hasWin = rowsResult.hasWin || colsResult.hasWin || diagonalsResult.hasWin; if (hasWin) { WinningIndexes.UnionWith(rowsResult.winningIndexes); WinningIndexes.UnionWith(colsResult.winningIndexes); WinningIndexes.UnionWith(diagonalsResult.winningIndexes); lastResult = new CheckResult(end: true, isDraw: false, WinningIndexes); return lastResult; } else if (checkDraw()) { lastResult = new CheckResult(end: true, isDraw: true, WinningIndexes); return lastResult; } else { lastResult = new CheckResult(end: false, isDraw: false, WinningIndexes); return lastResult; } } private static (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllRows(Team targetTeam) { var winningCells = new HashSet<(int row, int col)>(); for (int row = 0; row < Height; row++) { int start = -1; for (int col = 0; col < Width; col++) { var chip = FieldArray[col, row]; bool isMatch = chip != null && chip.team == targetTeam; if (isMatch && start == -1) start = col; if (!isMatch && start != -1) { int length = col - start; if (length >= TargetLineLength) { for (int c = start; c < col; c++) winningCells.Add((row, c)); } start = -1; } } // Проверка последовательности в конце строки if (start != -1) { int length = Width - start; if (length >= TargetLineLength) { for (int c = start; c < Width; c++) winningCells.Add((row, c)); } } } return (winningCells.Count > 0, winningCells); } private static (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllColumns(Team targetTeam) { var winningCells = new HashSet<(int row, int col)>(); for (int col = 0; col < Width; col++) { int start = -1; for (int row = 0; row < Height; row++) { var chip = FieldArray[col, row]; bool isMatch = chip != null && chip.team == targetTeam; if (isMatch && start == -1) start = row; if (!isMatch && start != -1) { int length = row - start; if (length >= TargetLineLength) { for (int r = start; r < row; r++) winningCells.Add((r, col)); } start = -1; } } // Проверка последовательности в конце столбца if (start != -1) { int length = Height - start; if (length >= TargetLineLength) { for (int r = start; r < Height; r++) winningCells.Add((r, col)); } } } return (winningCells.Count > 0, winningCells); } private static (bool hasWin, HashSet<(int row, int col)> winningIndexes) checkAllDiagonals(Team targetCellState) { var winningCells = new HashSet<(int row, int col)>(); // Проверка главных диагоналей for (int row = 0; row < Height; row++) { CheckDiagonalStartingAt(row, 0, 1, 1, targetCellState, winningCells); } for (int col = 1; col < Width; col++) { CheckDiagonalStartingAt(0, col, 1, 1, targetCellState, winningCells); } // Проверка побочных диагоналей for (int row = 0; row < Height; row++) { CheckDiagonalStartingAt(row, Width - 1, 1, -1, targetCellState, winningCells); } for (int col = Width - 2; col >= 0; col--) { CheckDiagonalStartingAt(0, col, 1, -1, targetCellState, winningCells); } return (winningCells.Count > 0, winningCells); } private static void CheckDiagonalStartingAt(int startRow, int startCol, int rowStep, int colStep, Team targetCellState, HashSet<(int, int)> winningCells) { int rows = Height; int cols = Width; int currentRow = startRow; int currentCol = startCol; int sequenceLength = 0; int sequenceStartRow = startRow; int sequenceStartCol = startCol; while (currentRow >= 0 && currentRow < rows && currentCol >= 0 && currentCol < cols) { var chip = FieldArray[currentCol, currentRow]; bool isMatch = chip != null && chip.team == targetCellState; if (isMatch) { sequenceLength++; } else { if (sequenceLength >= TargetLineLength) { for (int i = 0; i < sequenceLength; i++) { int r = sequenceStartRow + i * rowStep; int c = sequenceStartCol + i * colStep; winningCells.Add((r, c)); } } sequenceLength = 0; sequenceStartRow = currentRow + rowStep; sequenceStartCol = currentCol + colStep; } currentRow += rowStep; currentCol += colStep; } // Проверка последовательности в конце диагонали if (sequenceLength >= TargetLineLength) { for (int i = 0; i < sequenceLength; i++) { int r = sequenceStartRow + i * rowStep; int c = sequenceStartCol + i * colStep; winningCells.Add((r, c)); } } } public static bool checkDraw() { for (int col = 0; col < Width; col++) { if (Board.Instance.GetLowestEmptyRow(col) != -1) return false; } return true; } }