using RobotAndDonkey.Game.Cards; using RobotAndDonkey.Game.Execution; using RobotAndDonkey.Game.Execution.Results; using RobotAndDonkey.Game.GameState; namespace RobotAndDonkey.Game.Intents; public class Discard(Guid[] cardIds, int energyCost) : Intent(energyCost) { public override void Run(Guid requestId, CoreLoop coreLoop, List newIntents, List results) { var pool = coreLoop.ProgramRow.ToDictionary(card => card.CardId); var discardCards = new List(cardIds.Length); foreach (var cardId in cardIds) { if (pool.TryGetValue(cardId, out var card)) discardCards.Add(card); } var discardSet = discardCards.ToHashSet(); var newProgramRow = new List(coreLoop.ProgramRow.Count); foreach (var card in coreLoop.ProgramRow) { if (!discardSet.Contains(card)) { newProgramRow.Add(card); continue; } coreLoop.Discard.Add(card); if (coreLoop.PatchDeck.Count > 0) { var newCard = coreLoop.PatchDeck[0]; coreLoop.PatchDeck.RemoveAt(0); newProgramRow.Add(newCard); } } var remainingTapeIds = coreLoop.TapeCardIds.Where(id => !cardIds.Contains(id)).ToHashSet(); coreLoop.SetProgramRow(newProgramRow, remainingTapeIds); results.Add(new CurrencyResult(requestId, coreLoop.Currency)); results.Add(new ProgramRowResult(requestId, coreLoop.ProgramRow.ToArray(), coreLoop.TapeCardIds)); results.Add(new HandResult(requestId, coreLoop.Hand.ToArray())); results.Add(new TapeResult(requestId, coreLoop.Tape.ToArray())); results.Add(new DeckResult(requestId, coreLoop.PatchDeck.ToArray())); base.Run(requestId, coreLoop, newIntents, results); } public override bool IsValid(CoreLoop coreLoop) { if (!base.IsValid(coreLoop)) return false; if (cardIds.Length == 0) return false; var uniqueIds = cardIds.ToHashSet(); if (uniqueIds.Count != cardIds.Length) return false; foreach (var cardId in uniqueIds) { if (!coreLoop.TapeCardIds.Contains(cardId)) return false; } return coreLoop.RunPhase == ERunPhase.ExecuteProgram; } public override bool Immune => true; public override string ToString() => $"Discard {string.Join(", ", cardIds.Select(id => id.ToString()))}, " + base.ToString(); }