| | | 1 | | using TicTacToeApp.API.Entity.Enums; |
| | | 2 | | |
| | | 3 | | namespace TicTacToeApp.API.Services; |
| | | 4 | | |
| | | 5 | | public sealed class GameService |
| | | 6 | | { |
| | | 7 | | |
| | | 8 | | internal static ResultGame CheckBoard(string?[][] arr, string p) |
| | | 9 | | { |
| | 0 | 10 | | if ((arr[0][0] == p && arr[0][0] == arr[0][1] && arr[0][1] == arr[0][2]) || |
| | 0 | 11 | | (arr[1][0] == p && arr[1][0] == arr[1][1] && arr[1][1] == arr[1][2]) || |
| | 0 | 12 | | (arr[2][0] == p && arr[2][0] == arr[2][1] && arr[2][1] == arr[2][2]) || |
| | 0 | 13 | | (arr[0][0] == p && arr[0][0] == arr[1][0] && arr[1][0] == arr[2][0]) || |
| | 0 | 14 | | (arr[0][1] == p && arr[0][1] == arr[1][1] && arr[1][1] == arr[2][1]) || |
| | 0 | 15 | | (arr[0][2] == p && arr[0][2] == arr[1][2] && arr[1][2] == arr[2][2]) || |
| | 0 | 16 | | (arr[0][0] == p && arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2]) || |
| | 0 | 17 | | (arr[2][0] == p && arr[2][0] == arr[1][1] && arr[1][1] == arr[0][2]) |
| | 0 | 18 | | ) |
| | | 19 | | { |
| | | 20 | | switch (p) |
| | | 21 | | { |
| | | 22 | | case "X": |
| | 0 | 23 | | return ResultGame.WinX; |
| | | 24 | | case "O": |
| | 0 | 25 | | return ResultGame.WinO; |
| | | 26 | | } |
| | | 27 | | } |
| | | 28 | | |
| | 0 | 29 | | var canContinueGame = arr.Any(cell => cell == null); |
| | 0 | 30 | | if (!canContinueGame) return ResultGame.None; |
| | | 31 | | |
| | 0 | 32 | | return ResultGame.Draw; |
| | | 33 | | } |
| | | 34 | | internal static ResultGame CheckBoardN(string?[][] board, string player, int lineToWin) |
| | | 35 | | { |
| | 0 | 36 | | int size = board.Length; |
| | | 37 | | |
| | | 38 | | // Проверка всех возможных линий |
| | 0 | 39 | | for (int i = 0; i < size; i++) |
| | | 40 | | { |
| | 0 | 41 | | for (int j = 0; j < size; j++) |
| | | 42 | | { |
| | | 43 | | // Пропускаем пустые клетки |
| | 0 | 44 | | if (board[i][j] != player) |
| | | 45 | | continue; |
| | | 46 | | |
| | | 47 | | // Проверка горизонтали (→) |
| | 0 | 48 | | if (CheckLine(board, i, j, 0, 1, player, lineToWin)) |
| | 0 | 49 | | return GetWinResult(player); |
| | | 50 | | |
| | | 51 | | // Проверка вертикали (↓) |
| | 0 | 52 | | if (CheckLine(board, i, j, 1, 0, player, lineToWin)) |
| | 0 | 53 | | return GetWinResult(player); |
| | | 54 | | |
| | | 55 | | // Проверка диагонали (↘) |
| | 0 | 56 | | if (CheckLine(board, i, j, 1, 1, player, lineToWin)) |
| | 0 | 57 | | return GetWinResult(player); |
| | | 58 | | |
| | | 59 | | // Проверка диагонали (↙) |
| | 0 | 60 | | if (CheckLine(board, i, j, 1, -1, player, lineToWin)) |
| | 0 | 61 | | return GetWinResult(player); |
| | | 62 | | } |
| | | 63 | | } |
| | | 64 | | |
| | | 65 | | // Проверка на ничью (если нет пустых клеток) |
| | 0 | 66 | | bool isDraw = !board.Any(row => row.Any(cell => cell == null)); |
| | 0 | 67 | | return isDraw ? ResultGame.Draw : ResultGame.None; |
| | | 68 | | } |
| | | 69 | | |
| | | 70 | | // Проверяет, есть ли K символов player в ряд, начиная с (startX, startY) |
| | | 71 | | private static bool CheckLine(string?[][] board, int startX, int startY, int dx, int dy, string player, int lineToWi |
| | | 72 | | { |
| | 0 | 73 | | int size = board.Length; |
| | 0 | 74 | | int count = 0; |
| | | 75 | | |
| | 0 | 76 | | for (int step = 0; step < lineToWin; step++) |
| | | 77 | | { |
| | 0 | 78 | | int x = startX + step * dx; |
| | 0 | 79 | | int y = startY + step * dy; |
| | | 80 | | |
| | | 81 | | // Выход за границы поля |
| | 0 | 82 | | if (x < 0 || x >= size || y < 0 || y >= size) |
| | | 83 | | break; |
| | | 84 | | |
| | 0 | 85 | | if (board[x][y] == player) |
| | 0 | 86 | | count++; |
| | | 87 | | else |
| | | 88 | | break; |
| | | 89 | | } |
| | | 90 | | |
| | 0 | 91 | | return count == lineToWin; |
| | | 92 | | } |
| | | 93 | | |
| | | 94 | | // Возвращает ResultGame.WinX или ResultGame.WinO |
| | | 95 | | private static ResultGame GetWinResult(string player) |
| | | 96 | | { |
| | 0 | 97 | | return player == "X" ? ResultGame.WinX : ResultGame.WinO; |
| | | 98 | | } |
| | | 99 | | |
| | | 100 | | public static string?[][] CreateEmptyBoard(int size) |
| | | 101 | | { |
| | 4 | 102 | | var board = new string?[size][]; |
| | 44 | 103 | | for (int i = 0; i < size; i++) |
| | | 104 | | { |
| | 18 | 105 | | board[i] = new string?[size]; |
| | 304 | 106 | | for (int j = 0; j < size; j++) |
| | | 107 | | { |
| | 134 | 108 | | board[i][j] = null; |
| | | 109 | | } |
| | | 110 | | } |
| | | 111 | | |
| | 4 | 112 | | return board; |
| | | 113 | | } |
| | | 114 | | |
| | | 115 | | } |