184 lines
5.4 KiB
C#
184 lines
5.4 KiB
C#
using GameModel;
|
|
using GameModel.DeathGame;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace GameHandler.DeathGame
|
|
{
|
|
public delegate void CoffinCompleted(Coffin coffin);
|
|
public delegate void ExpenseTriggered(ExpenseTrigger expenseType);
|
|
public class DeathGameHandler
|
|
{
|
|
const int MIN_PLAYER_COUNT = 3;
|
|
const int MAX_PLAYER_COUNT = 12;
|
|
const int MIN_COFFIN_SIZE = 6;
|
|
const int MAX_COFFIN_SIZE = 12;
|
|
|
|
public event CoffinCompleted CoffinCompleted;
|
|
public event ExpenseTriggered ExpenseTriggered;
|
|
|
|
private static Random random = new Random();
|
|
|
|
|
|
private void ValidatePlayerCount(int playerCount)
|
|
{
|
|
if (playerCount < MIN_PLAYER_COUNT)
|
|
{
|
|
throw new InvalidDataException($"MaxPlayerCount must be at least {MIN_PLAYER_COUNT}");
|
|
}
|
|
if (playerCount > MAX_PLAYER_COUNT)
|
|
{
|
|
throw new InvalidDataException($"MaxPlayerCount cannot be greater than {MAX_PLAYER_COUNT}");
|
|
}
|
|
}
|
|
|
|
private void ValidateGameSettings(DeathGameSettings deathGameSettings)
|
|
{
|
|
if (deathGameSettings.MaxCoffinSize < MIN_COFFIN_SIZE || deathGameSettings.MaxCoffinSize > MAX_COFFIN_SIZE )
|
|
{
|
|
throw new InvalidDataException($"Max coffin size must be from {MIN_COFFIN_SIZE} to {MAX_COFFIN_SIZE}");
|
|
}
|
|
}
|
|
|
|
public DeathGameHandler()
|
|
{
|
|
}
|
|
|
|
public DeathGameModel InitGameModel(int[] playerIds, DeathGameSettings deathGameSettings)
|
|
{
|
|
ValidatePlayerCount(playerIds.Count());
|
|
ValidateGameSettings(deathGameSettings);
|
|
|
|
var coffins = new List<Coffin>();
|
|
foreach (var playerId in playerIds)
|
|
{
|
|
if (coffins.Any(_ => _.PlayerId.Equals(playerId)))
|
|
{
|
|
throw new InvalidDataException($"player {playerId} already exists");
|
|
}
|
|
coffins.Add(new Coffin(playerId,0,0));
|
|
}
|
|
return new DeathGameModel(1, coffins.OrderBy(_ => random.Next()).ToList().ToArray(), deathGameSettings);
|
|
}
|
|
|
|
public DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins, bool boardCleared)
|
|
{
|
|
var incLine = false;
|
|
var incX = false;
|
|
if (gm.Id == 1) // first round in game
|
|
{
|
|
incX = true;
|
|
if (pinCount < 3)
|
|
{
|
|
ExpenseTriggered?.Invoke(ExpenseTrigger.FirstThrowFail);
|
|
incLine = true;
|
|
}
|
|
}
|
|
|
|
if (isTrowIntoAllPins)
|
|
{
|
|
incX = true;
|
|
}
|
|
|
|
if (pinCount == 0)
|
|
{
|
|
incLine = true;
|
|
}
|
|
|
|
var current = gm.Coffins.First();
|
|
var next = gm.Coffins.Skip(1).First();
|
|
var previous = gm.Coffins.Last();
|
|
Coffin? currentUpdated = null;
|
|
Coffin? nextUpdated = next;
|
|
Coffin? previousUpdated = previous;
|
|
|
|
|
|
var xCount = current.XCount;
|
|
var lineCount = current.LineCount;
|
|
|
|
if (incLine)
|
|
{
|
|
lineCount++;
|
|
}
|
|
|
|
if (incX)
|
|
{
|
|
xCount++;
|
|
}
|
|
|
|
if (xCount == 3)
|
|
{
|
|
xCount = 0;
|
|
lineCount++;
|
|
}
|
|
currentUpdated = current with { LineCount = lineCount, XCount = xCount };
|
|
|
|
if (lineCount > gm.deathGameSettings.MaxCoffinSize)
|
|
{
|
|
CoffinCompleted?.Invoke(currentUpdated);
|
|
currentUpdated = null;
|
|
}
|
|
|
|
|
|
if (boardCleared)
|
|
{
|
|
previousUpdated = previous with { LineCount = previous.LineCount + 1 };
|
|
if (previousUpdated.LineCount > gm.deathGameSettings.MaxCoffinSize)
|
|
{
|
|
CoffinCompleted?.Invoke(previousUpdated);
|
|
previousUpdated = null;
|
|
}
|
|
|
|
|
|
if (next.XCount < 2)
|
|
{
|
|
nextUpdated = next with { XCount = next.XCount + 1 };
|
|
}
|
|
else
|
|
{
|
|
nextUpdated = next with { LineCount = previous.LineCount + 1, XCount = 0 };
|
|
if (nextUpdated.LineCount > gm.deathGameSettings.MaxCoffinSize)
|
|
{
|
|
CoffinCompleted?.Invoke(nextUpdated);
|
|
nextUpdated = null;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
var coffins = gm.Coffins.Skip(1).ToList();
|
|
if (currentUpdated != null)
|
|
{
|
|
coffins.Add(currentUpdated);
|
|
}
|
|
|
|
if (nextUpdated == null)
|
|
{
|
|
coffins.Remove(next);
|
|
}
|
|
|
|
if (previousUpdated == null)
|
|
{
|
|
coffins.Remove(previous);
|
|
}
|
|
else
|
|
{
|
|
var idx = coffins.IndexOf(previous);
|
|
|
|
coffins.Remove(previous);
|
|
coffins.Insert(idx, previousUpdated);
|
|
}
|
|
|
|
|
|
|
|
|
|
var result = gm with { Coffins = coffins.ToArray(), Id = gm.Id + 1 };
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|