public bool TryGetMoveTargetValidateWithBoardMove(Board board, MapNode source, AllianceScenario allianceScenario, BoardMove boardMove, out List <MapNode> path, out UnitMove move) { if (!board.OccupiedMapNodes.ContainsKey(source)) { throw new Exception($"No unit occupies {source} in the given board"); } var movesAvailableForSource = boardMove.GetAvailableFallSpringMovesForMapNode(board, source); if (movesAvailableForSource.Count == 0) { // couldn't find anything. // this is caused by picking moves that lead to a contradiction. // Force the caller to deal, perhaps with a hold on all affected... path = null; move = null; return(false); } Unit unit = board.OccupiedMapNodes[source]; Coalition myCoalition = allianceScenario.GetPossibleCoalitions()[unit.Power]; List <KeyValuePair <MapNode, double> > orderedDistances = GetWeightedMapNodeDistances(board, source, allianceScenario) .OrderBy(kvp2 => kvp2.Value).ToList(); // are we sitting on a supplycenter that we want? If so, hold if (source.Territory.IsSupplyCenter && !board.SupplyCenterIsOwnedBy(source.Territory, myCoalition)) { UnitMove holdMove = new UnitMove(unit, source); if (boardMove == null || boardMove.CurrentlyAllowsFallSpring(holdMove)) { path = new List <MapNode>() { source }; move = holdMove; return(true); } } List <Func <MapNode, bool> > predicateList = new List <Func <MapNode, bool> >() { (mn) => { return(mn.Territory.IsSupplyCenter && !board.SupplyCenterIsOwnedBy(mn.Territory, myCoalition)); }, (mn) => { return(mn.Territory != source.Territory); }, (mn) => { return(mn.Territory == source.Territory); }, }; foreach (var predicate in predicateList) { path = GetPath(board, source, boardMove, orderedDistances, predicate); if (path != null) { MapNode moveTarget = path[1]; move = board.GetUnitMoves().FirstOrDefault(um => um.Edge.Source == source && um.Edge.Target == moveTarget); return(true); } } UnitMove lastResort = movesAvailableForSource.First(); path = new List <MapNode>() { lastResort.Edge.Target }; move = lastResort; return(true); }