private int GetShortestDistanceToMineInOtherComponent(Edge edge,
                                                       PunterConnectedComponents punterConnectedComponents, Punter punter)
 {
     return(Math.Min(
                GetShortestDistanceToMineInOtherComponent(edge.Source, punterConnectedComponents, punter),
                GetShortestDistanceToMineInOtherComponent(edge.Target, punterConnectedComponents, punter)
                ));
 }
예제 #2
0
 private static void CheckComponents(Node[] component1, Node[] component2, PunterConnectedComponents actual, int punterId, bool expected)
 {
     foreach (var left in component1)
     {
         foreach (var right in component2)
         {
             actual.IsInSameComponent(left.Id, right.Id, punterId).Should().Be(expected, $"{left.Id} - {right.Id}, punter {punterId}");
         }
     }
 }
        private int GetShortestDistanceToMineInOtherComponent(Node node,
                                                              PunterConnectedComponents punterConnectedComponents, Punter punter)
        {
            var minesInOtherComponents = scorer.State.Mines
                                         .Where(mine => !punterConnectedComponents.IsInSameComponent(mine.Id, node.Id, punter.Id))
                                         .ToArray();

            if (minesInOtherComponents.Length == 0)
            {
                return(1000 * 1000 * 1000);
            }

            return(minesInOtherComponents.Min(mine => scorer.GetDistance(mine, node)));
        }
예제 #4
0
        private int GetWeight(Edge claimEdge, Punter punter, PunterConnectedComponents punterConnectedComponents)
        {
            if (punterConnectedComponents.IsInSameComponent(claimEdge.Source.Id, claimEdge.Target.Id, punter.Id))
            {
                return(0);
            }

            claimEdge.Punter = punter;

            var leftComponent  = punterConnectedComponents.GetComponent(punter.Id, claimEdge.Source.Id);
            var rightComponent = punterConnectedComponents.GetComponent(punter.Id, claimEdge.Target.Id);

            var scoreDelta = scorer.ScoreForUnitingComponents(leftComponent, rightComponent);

            claimEdge.Punter = null;
            return(scoreDelta);
        }
        private int GetWeight(Edge claimEdge, Punter punter, PunterConnectedComponents punterConnectedComponents)
        {
            if (punterConnectedComponents.IsInSameComponent(claimEdge.Source.Id, claimEdge.Target.Id, punter.Id))
            {
                return(0);
            }

            claimEdge.Punter = punter;

            var leftComponent  = punterConnectedComponents.GetComponent(punter.Id, claimEdge.Source.Id);
            var rightComponent = punterConnectedComponents.GetComponent(punter.Id, claimEdge.Target.Id);

            var scalingFactor = Math.Max(10, maxScore / 100);
            var scoreDelta    = (scorer.ScoreForUnitingComponents(leftComponent, rightComponent) + scalingFactor - 1) /
                                scalingFactor;

            claimEdge.Punter = null;
            return(scoreDelta);
        }
예제 #6
0
        private Edge GetBridge(GameState gameState, Map map, Punter punter, HashSet <int> reachableNodeIds,
                               PunterConnectedComponents strictComponents, Edge[] bridgeEdges)
        {
            var goodBridges = bridgeEdges
                              .Select(x => new { edge = x, weight = GetWeightForBridge(map, x, punter, reachableNodeIds) })
                              .Where(x => x.weight > 0)
                              .ToArray();

            bridgeMaxScore = goodBridges.Length > 0 ? goodBridges.Max(x => x.weight) : 1;
            maxScore       = goodBridges.Length > 0 ? goodBridges.Max(x => GetWeight(x.edge, punter, strictComponents)) : 1;

            var bestBridge = goodBridges
                             .Select(x => x.edge)
                             .OrderByDescending(x => GetWeightForBridge(map, x, punter, reachableNodeIds))
                             .ThenByDescending(x => GetWeight(x, punter, strictComponents))
                             .ThenBy(x => GetShortestDistanceToMineInOtherComponent(x, strictComponents, punter))
                             .ThenByDescending(x => CountFreeNeighborEdges(gameState, x))
                             .FirstOrDefault();

            return(bestBridge);
        }
예제 #7
0
        private static PunterConnectedComponents GetConnectedComponents(Map map, bool withFreeEdges)
        {
            var connectedComponents = new PunterConnectedComponents();

            var punters = map
                          .Edges
                          .Select(x => x.Punter)
                          .Where(x => x != null)
                          .Select(x => x.Id)
                          .Distinct()
                          .Select(x => new Punter {
                Id = x
            })
                          .ToArray();

            var queue = new Queue <Node>();

            foreach (var punter in punters)
            {
                var visitedNodeIds = new HashSet <int>();

                foreach (var node in map.Nodes)
                {
                    if (visitedNodeIds.Contains(node.Id))
                    {
                        continue;
                    }

                    var component = new List <Node>();
                    component.Add(AddNode(queue, visitedNodeIds, node));
                    Bfs(map, punter, queue, visitedNodeIds, component, withFreeEdges);

                    var nodeIds = component.Select(x => x.Id).ToArray();
                    connectedComponents.AddComponent(nodeIds, punter.Id);
                }
            }

            return(connectedComponents);
        }