namespace API.Models.Game; public readonly struct Coordinates(int x, int y) { public readonly int X = x; public readonly int Y = y; } public enum DropResult { OutOfGameField, NotAllowedPlayer, ColumnFull, InvalidFieldValue, Placed } public enum FieldState { OutOfGameField, Empty, OccupiedRed, OccupiedYellow, InvalidFieldValue } public class GameField(Coordinates gFs) { public Coordinates GFs = gFs; public int[,] CurrentField { get; } = new int[gFs.Y, gFs.X]; public int[,] BackupField { get; } = new int[gFs.Y, gFs.X]; public DropResult Drop(int column, int player) { if (column < 0 || column >= CurrentField.GetLength(1)) return DropResult.OutOfGameField; if (player != 1 && player != 2) return DropResult.NotAllowedPlayer; int rows = CurrentField.GetLength(0); for (int y = rows - 1; y >= 0; y--) { int currentValue = CurrentField[y, column]; if (currentValue == 0) { CreateSave(); CurrentField[y, column] = player; return DropResult.Placed; } if (currentValue != 1 && currentValue != 2) return DropResult.InvalidFieldValue; } return DropResult.ColumnFull; } public FieldState CheckField(Coordinates coordinates) { if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) || coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0)) return FieldState.OutOfGameField; var currentValue = CurrentField[coordinates.Y, coordinates.X]; return currentValue switch { 0 => FieldState.Empty, 1 => FieldState.OccupiedRed, 2 => FieldState.OccupiedYellow, _ => FieldState.InvalidFieldValue }; } public bool IsFull() { int rows = CurrentField.GetLength(0); int cols = CurrentField.GetLength(1); for (int y = 0; y < rows; y++) { for (int x = 0; x < cols; x++) { if (CurrentField[y, x] == 0) return false; } } return true; } private int CountInDirection(int startX, int startY, int dx, int dy, int player) { var count = 0; var x = startX; var y = startY; while ( x >= 0 && x < CurrentField.GetLength(1) && y >= 0 && y < CurrentField.GetLength(0) && CurrentField[y, x] == player) { count++; x += dx; y += dy; } return count; } private bool CheckLine(int startX, int startY, int dx, int dy, int player) { int count = CountInDirection(startX + dx, startY + dy, dx, dy, player); count += CountInDirection(startX - dx, startY - dy, -dx, -dy, player); return count + 1 >= 4; } public int CheckForWin() { int rows = CurrentField.GetLength(0); int cols = CurrentField.GetLength(1); (int dx, int dy)[] directions = [(1, 0), (0, 1), (1, 1), (-1, 1)]; for (int y = 0; y < rows; y++) { for (int x = 0; x < cols; x++) { int player = CurrentField[y, x]; if (player != 1 && player != 2) continue; foreach (var (dx, dy) in directions) { if (CheckLine(x, y, dx, dy, player)) return player; } } } return 0; } private void CreateSave() { Array.Copy(CurrentField, BackupField, CurrentField.Length); } }