public void NoTerritorySwappingAllowed() { Board board = Board.GetInitialBoard(); BoardMove moves = new BoardMove(); UnitMove move1 = board.GetMove("tri", "ven"); UnitMove move2 = board.GetMove("ven", "tri"); Assert.IsTrue(moves.CurrentlyAllowsFallSpring(move1)); moves.Add(move1); Assert.IsFalse(moves.CurrentlyAllowsFallSpring(move2)); }
private List <MapNode> GetPath(Board board, MapNode source, BoardMove boardMove, List <KeyValuePair <MapNode, double> > orderedDistances, Func <MapNode, bool> predicate) { var allMoves = board.GetUnitMoves(); foreach (MapNode currentTarget in orderedDistances.Select(kvp => kvp.Key) .Where(predicate)) { IEnumerable <UndirectedEdge <MapNode> > rawPath; if (!_predecessorObserver.TryGetPath(currentTarget, out rawPath)) { continue; } List <MapNode> path = MakePathList(source, currentTarget, rawPath); MapNode adjacentTarget = path[1]; UnitMove unitMove = allMoves.FirstOrDefault(um => um.Edge.Target == adjacentTarget && um.Edge.Source == source); if (boardMove == null || boardMove.CurrentlyAllowsFallSpring(unitMove)) { return(path); } } // couldn't find anything return(null); }
private static void GetBoardMovesFallSpringRecursive(Board originalBoard, BoardMove workingBoardMove, ILookup <MapNode, UnitMove> sourceNodeGroups, List <BoardMove> completedBoardMoves, int depth) { if (workingBoardMove.Count == sourceNodeGroups.Count) { completedBoardMoves.Add(workingBoardMove.Clone()); return; } MapNode node = sourceNodeGroups.First(n => !workingBoardMove.Sources.Contains(n.Key)).Key; foreach (UnitMove move in sourceNodeGroups[node]) { if (workingBoardMove.CurrentlyAllowsFallSpring(move)) { workingBoardMove.Add(move); GetBoardMovesFallSpringRecursive(originalBoard, workingBoardMove, sourceNodeGroups, completedBoardMoves, depth + 1); workingBoardMove.Remove(move); } } }
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); }