Files
2026-03-12 23:20:05 +01:00

152 lines
3.7 KiB
C#

using System.Text.Json.Serialization;
namespace API.Models.Game;
public readonly struct Coordinates
{
public int X { get; init; }
public int Y { get; init; }
}
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);
}
}