コード例 #1
0
ファイル: RoadBuilder.cs プロジェクト: ttv86/CsNut
        /// <summary>
        /// Uses A*-algorithm to find the best route between two tiles.
        /// </summary>
        /// <param name="start">First tile to search from.</param>
        /// <param name="goal">Goal to find.</param>
        /// <param name="previous">Tile just before the first tile.</param>
        /// <param name="forbidden">List of tiles that should be never used on route.</param>
        /// <param name="sign">Optional function for building signs.</param>
        /// <returns></returns>
        internal static List <PathInfo> FindPath(TileIndex start, TileIndex goal, TileIndex previous, HashSet <TileIndex> forbidden = null, Action <TileIndex, string> sign = null)
        {
            // Nodes to evaluate
            var tilesToProcess = new FibonacciHeap <TileIndex>();

            tilesToProcess.Insert(start, 0);

            // Nodes evaluated
            var cameFrom = new Dictionary <TileIndex, PathInfo>();

            cameFrom[start] = new PathInfo(start, 1, 0, BuildType.Basic, previous != null ? new PathInfo(previous, 1, 0, BuildType.Basic, null) : null);

            while (tilesToProcess.Count() > 0)
            {
                var current = tilesToProcess.Pop();
                //AILog.Info($"Processing: {Helper.FormatTile(current)}");
                if (current == goal)
                {
                    // We found the target.
                    return(RoadBuilder.BuildFinalPath(cameFrom[current]));
                }

                var neighbors = RoadBuilder.GetNeighbors(current, cameFrom[current]);
                foreach (var neighborItem in neighbors)
                {
                    var neighbor = neighborItem.Tile;
                    if ((neighbor == previous) || ((forbidden != null) && forbidden.Contains(neighbor)))
                    {
                        // We can't go here.
                        continue;
                    }

                    var neighborDist = neighborItem.Length;
                    if (!cameFrom.ContainsKey(neighbor))
                    {
                        tilesToProcess.Insert(neighbor, neighborItem.Cost);
                    }
                    else
                    {
                        if (neighborItem.Cost >= cameFrom[neighbor].Cost)
                        {
                            continue;
                        }
                    }

                    sign?.Invoke(neighbor, neighborItem.Cost.ToString());
                    cameFrom[neighbor] = neighborItem;
                }
            }

            return(null);
        }
コード例 #2
0
        protected override void Start()
        {
            AICompany.SetLoanAmount(0);
            SignManager signManager = new SignManager();
            TownNetwork tn          = new TownNetwork();

            try
            {
                AICompany.SetLoanAmount(AICompany.GetMaxLoanAmount());
                AIRoad.SetCurrentRoadType(AIRoad.ROADTYPE_ROAD);
                foreach (var edge in tn.Graph.Edges)
                {
                    AILog.Info($"Build road from {edge.Node1.Name} to {edge.Node2.Name}.");
                    var stationInfo1 = tn.EnsureStation(edge.Node1);
                    var stationInfo2 = tn.EnsureStation(edge.Node2);

                    RoadBuilder.BuildRoad(
                        stationInfo1.tile,
                        stationInfo1.entryPoint,
                        stationInfo2.entryPoint,
                        stationInfo2.tile,
                        new HashSet <TileIndex>()
                        );

                    var depotInfo1 = tn.EnsureDepot(edge.Node1);
                    var depotInfo2 = tn.EnsureDepot(edge.Node2);

                    tn.MakeRoute(edge.Node1, edge.Node2);
                    tn.MakeRoute(edge.Node2, edge.Node1);
                }
            }
            catch
            {
            }

            Sleep(50);
            signManager.ClearSigns();
            var step = 0;

            while (true)
            {
                // Main loop
                //this.setMinLoan();
                CsTestAi.SetMinimumLoanAmount();

                tn.UpdateRoutes();

                Sleep(100);
                step++;
            }
        }
コード例 #3
0
ファイル: RoadBuilder.cs プロジェクト: ttv86/CsNut
        internal static bool BuildRoad(TileIndex previous, TileIndex from, TileIndex to, TileIndex next, HashSet <TileIndex> forbidden, Action <TileIndex, string> sign = null)
        {
            var path = RoadBuilder.FindPath(from, to, previous, forbidden);

            if (path == null)
            {
                return(false);
            }

            for (var i = 0; i < path.Count - 1; i++)
            {
                var p  = i == 0 ? next : path[i - 1].Tile;
                var c  = path[i].Tile;
                var n  = i == path.Count - 1 ? previous : path[i + 1].Tile;
                var nt = i == 0 ? BuildType.Basic : path[i - 1].Type;
                //sign(c, "[" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] " + path[i].type);
                bool good = false;
                switch (path[i].Type)
                {
                case BuildType.Basic:
                    if (path[i].Length > 1)
                    {
                        AILog.Error($"Length is: {path[i].Length}. ([" + AIMap.GetTileX(p) + ", " + AIMap.GetTileY(p) + "] via [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] to [" + AIMap.GetTileX(n) + ", " + AIMap.GetTileY(n) + "])");
                        continue;
                        //throw new Exception("Should not be Road");
                    }

                    if (nt != BuildType.Basic)
                    {
                        continue;
                    }

                    //AILog.Info("Build a Road  from [" + AIMap.GetTileX(p) + ", " + AIMap.GetTileY(p) + "] via [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] to [" + AIMap.GetTileX(n) + ", " + AIMap.GetTileY(n) + "].");
                    good = AIRoad.BuildRoad(p, c);
                    good = AIRoad.BuildRoad(c, n);
                    break;

                case BuildType.Bridge:
                    var bridgeTypes = new AIBridgeList_Length(path[i].Length);
                    //AILog.Info("Build a bridge " + bridgeTypes.Begin() + " from [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] to [" + AIMap.GetTileX(n) + ", " + AIMap.GetTileY(n) + "].");
                    good = AIBridge.BuildBridge(AIVehicle.VT_ROAD, bridgeTypes.Begin(), c, n);
                    if ((!good) && (sign != null))
                    {
                        sign(p, "s");
                        sign(c, "e");
                    }

                    break;

                case BuildType.Tunnel:
                    throw new Exception("Tunnels not supported");
                }

                if (!good)
                {
                    var reason = AIError.GetLastErrorString();
                    if (reason != "ERR_ALREADY_BUILT")
                    {
                        AILog.Error("Failed to build on [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "]. Reason: " + reason);
                    }
                }
            }

            return(true);
        }