56 lines
1.8 KiB
C#
56 lines
1.8 KiB
C#
|
|
using Chessistics.Engine.Model;
|
||
|
|
|
||
|
|
namespace Chessistics.Engine.Rules;
|
||
|
|
|
||
|
|
public static class CollisionResolver
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Resolves collisions after movement. For each cell with 2+ pieces,
|
||
|
|
/// the strongest piece survives and destroys the others.
|
||
|
|
/// Priority: SocialStatus desc → Level desc → mutual destruction on exact tie.
|
||
|
|
/// </summary>
|
||
|
|
public static List<(PieceState? Survivor, List<PieceState> Destroyed, Coords Cell)> ResolveCollisions(
|
||
|
|
IReadOnlyList<PieceState> pieces)
|
||
|
|
{
|
||
|
|
var results = new List<(PieceState? Survivor, List<PieceState> Destroyed, Coords Cell)>();
|
||
|
|
var byCell = new Dictionary<Coords, List<PieceState>>();
|
||
|
|
|
||
|
|
foreach (var piece in pieces)
|
||
|
|
{
|
||
|
|
if (!byCell.TryGetValue(piece.CurrentCell, out var list))
|
||
|
|
{
|
||
|
|
list = [];
|
||
|
|
byCell[piece.CurrentCell] = list;
|
||
|
|
}
|
||
|
|
list.Add(piece);
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (var (cell, occupants) in byCell)
|
||
|
|
{
|
||
|
|
if (occupants.Count < 2) continue;
|
||
|
|
|
||
|
|
// Sort by priority: highest status first, then highest level
|
||
|
|
var sorted = occupants
|
||
|
|
.OrderByDescending(p => p.SocialStatus)
|
||
|
|
.ThenByDescending(p => p.Level)
|
||
|
|
.ToList();
|
||
|
|
|
||
|
|
var top = sorted[0];
|
||
|
|
var second = sorted[1];
|
||
|
|
|
||
|
|
// If top two have same status AND same level → mutual destruction
|
||
|
|
if (top.SocialStatus == second.SocialStatus && top.Level == second.Level)
|
||
|
|
{
|
||
|
|
results.Add((null, sorted, cell));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
var destroyed = sorted.Skip(1).ToList();
|
||
|
|
results.Add((top, destroyed, cell));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return results;
|
||
|
|
}
|
||
|
|
}
|