Loading

Paste #pxgw20pmb

  1. names = ["Pathways", "Pather", "Cheap Ways"];
  2. suffixes = ["Inc.", "Co.", "S.A.", "Corps"]
  3.  
  4. cityCargoClasses = [
  5.     AICargo.CargoClass.CC_PASSENGERS,
  6.     AICargo.CargoClass.CC_MAIL
  7. ];
  8.  
  9. function pick(arr)
  10. {
  11.     return arr[1.0 * arr.len() * rand() / RAND_MAX];
  12. }
  13.  
  14. function checkMoney(money, func)
  15. {
  16.     if ( AICompany.GetBankBalance(AICompany.CompanyID.COMPANY_SELF) > money )
  17.         func(AICompany.GetBankBalance(AICompany.CompanyID.COMPANY_SELF));
  18. }
  19.  
  20. function ClosestDepotToRoad(begin)
  21. {
  22.     neighbors = AITileList();
  23.     neighbors.Add(begin, 0);
  24.  
  25.     costs = {
  26.         [begin] = 0
  27.     };
  28.  
  29.     cameFrom = {
  30.         [begin] = null;
  31.     };
  32.  
  33.     function CostFor(current, tile)
  34.     {
  35.         return GetSlope(tile) != AITile.Slope.SLOPE_FLAT ? 2 : 1;
  36.     }
  37.  
  38.     function CostForBridge(tile)
  39.     {
  40.         return    AIBridge.GetMinLength(AIBridge.GetBridgeID(tile))
  41.                 / AIBridge.GetMaxSpeed(AIBridge.GetBridgeID(tile));
  42.     }
  43.  
  44.     function CostForTunnel(tile)
  45.     {
  46.         return    AITile.GetManhattanDistance(tile, AITunnel.GetOtherTunneEnd(tile))
  47.                 / AIEngine.GetMaxSpeed(
  48.                     AIEngineList(AIVehicle.VehicleType.VT_RAIL)
  49.                             .Valuate(AIEngine.GetPrice)
  50.                             .End()
  51.                 );
  52.     }
  53.  
  54.     function CalcCameFrom(tile, current)
  55.     {
  56.         if ( !cameFrom.HasItem(tile) || neighbors.GetValue(tile) < CostFor(current, tile) )
  57.             cameFrom[tile] <- current;
  58.     }
  59.  
  60.     function AddNeighbor(tile, current)
  61.     {
  62.         if ( AIRail.IsRailTile(tile) && AIRail.AreTilesConnected(tile, current) )
  63.         {
  64.             CalcCameFrom(tile, current);
  65.  
  66.             neighbors.SetValue(tile, CostFor(current, tile));
  67.         }
  68.     }
  69.  
  70.     function AddBridge(tile)
  71.     {
  72.         if ( !AIRail.IsRailTile(tile) )
  73.             return;
  74.  
  75.         if ( AIBridge.IsBridgeTile(tile) )
  76.         {
  77.             CalcCameFrom(AIBridge.GetOtherBridgeEnd(tile), tile);
  78.  
  79.             neighbors.SetValue(tile, CostForBridge(tile));
  80.         }
  81.  
  82.         else if ( AITunnel.IsTunnelTile(tile) )
  83.         {
  84.             CalcCameFrom(AITunnel.GetOtherTunneEnd(tile), tile);
  85.  
  86.             neighbors.SetValue(tile, CostForTunnel(tile));
  87.         }
  88.     }
  89.  
  90.     while ( neighbors.Count() > 0 )
  91.     {
  92.         t = neighbors.Begin();
  93.         neighbors.RemoveTop(1);
  94.  
  95.         // orthogonals
  96.         AddNeighbor(tile - AIMap.GetTileIndex(1,0));
  97.         AddNeighbor(tile - AIMap.GetTileIndex(0,1));
  98.         AddNeighbor(tile - AIMap.GetTileIndex(-1,0));
  99.         AddNeighbor(tile - AIMap.GetTileIndex(0,-1));
  100.  
  101.         // diagonals
  102.         AddNeighbor(tile - AIMap.GetTileIndex(-1,1));
  103.         AddNeighbor(tile - AIMap.GetTileIndex(1,1));
  104.         AddNeighbor(tile - AIMap.GetTileIndex(1,-1));
  105.         AddNeighbor(tile - AIMap.GetTileIndex(-1,-1));
  106.        
  107.         AddBridge(t);
  108.     }
  109.  
  110.     return function(depot)
  111.     {
  112.         if ( cameFrom.HasItem(depot) )
  113.             return costs[depot];
  114.  
  115.         return 0x7FFF;
  116.     };
  117. }
  118.  
  119. function TilesInCity(city)
  120. {
  121.     tiles = AITileList();
  122.     neighbors = AITileList();
  123.  
  124.     function AddNeighbor(tile)
  125.     {
  126.         if ( AITown.IsWithinTownInfuence(city, tile) )
  127.         {
  128.             neighbors.AddTile(tile);
  129.             tiles.AddTile(tile);
  130.         }
  131.     }
  132.  
  133.     while ( neighbors.Count() > 0 )
  134.     {
  135.         t = neighbors.Begin();
  136.         neighbors.RemoveTop(1);
  137.  
  138.         // orthogonals
  139.         AddNeighbor(tile - AIMap.GetTileIndex(1,0));
  140.         AddNeighbor(tile - AIMap.GetTileIndex(0,1));
  141.         AddNeighbor(tile - AIMap.GetTileIndex(-1,0));
  142.         AddNeighbor(tile - AIMap.GetTileIndex(0,-1));
  143.     }
  144.  
  145.     return tiles;
  146. }
  147.  
  148. function CityOutletRoads(city)
  149. {
  150.     outlets = AITileList();
  151.  
  152.     function IsOutlet(tile)
  153.     {
  154.         if ( !AIRoad.IsRoadTile(tile) )
  155.             return false;
  156.  
  157.         neighbors = OrthoNeighbors(tile);
  158.  
  159.         neighboringRoads = 0;
  160.  
  161.         foreach ( tile in neighbors )
  162.         {
  163.             if ( !AITile.IsBuildable(tile) )
  164.                 return false;
  165.  
  166.             if ( AIRoad.IsRoadTile(tile) )
  167.                 neighboringRoads++;
  168.         }
  169.  
  170.         return neighboringRoads == 1;
  171.     }
  172.  
  173.     foreach ( tile, val in TilesInCity(city) )
  174.     {
  175.         if ( IsOutlet(tile) )
  176.             outlets.AddTile(tile);
  177.     }
  178.  
  179.     return outlets;
  180. }
  181.  
  182. function OrthoNeighbors(point)
  183. {
  184.     return [
  185.         AddNeighbor(tile - AIMap.GetTileIndex(1,0)),
  186.         AddNeighbor(tile - AIMap.GetTileIndex(0,1)),
  187.         AddNeighbor(tile - AIMap.GetTileIndex(-1,0)),
  188.         AddNeighbor(tile - AIMap.GetTileIndex(0,-1))
  189.     ];
  190. }
  191.  
  192. class RoadPath
  193. {
  194.     path = null;
  195.  
  196.     constructor(p)
  197.     {
  198.         path = p;
  199.     }
  200.  
  201.     function BuildPath()
  202.     {
  203.         for ( local i = 0; i < path.len() - 1; i++ )
  204.             if ( !AIRoad.BuildRoad(path[i], path[i] + 1) )
  205.                 return false;
  206.  
  207.         return true;
  208.     }
  209.  
  210.     function BuildStations()
  211.     {
  212.         local done = false;
  213.         local pos = 0;
  214.  
  215.         while ( AIRoad.BuildRoadStation(
  216.             path[pos], path[pos] + 1,
  217.             AIRoad.RoadVehicleType.ROADVEHTYPE_BUS,
  218.             AIStation.STATION_JOIN_ADJACENT
  219.         ) )
  220.         {
  221.             pos++;
  222.             done = true;
  223.         }
  224.  
  225.         if ( !done )
  226.             return false;
  227.  
  228.         done = false;
  229.         pos = path.len() - 1;
  230.  
  231.         while ( AIRoad.BuildRoadStation(
  232.             path[pos], path[pos] - 1,
  233.             AIRoad.RoadVehicleType.ROADVEHTYPE_BUS,
  234.             AIStation.STATION_JOIN_ADJACENT
  235.         ) )
  236.         {
  237.             pos--;
  238.             done = true;
  239.         }
  240.  
  241.         return done;
  242.     }
  243.  
  244.     function RandomPoint()
  245.     {
  246.         return pick(path);
  247.     }
  248.  
  249.     function RandomNeighboringPoint()
  250.     {
  251.         candidates = [];
  252.  
  253.         while ( candidates.len() < path.len() )
  254.         {
  255.             p = RandomPoint();
  256.  
  257.             if ( !(p in candidates) )
  258.                 candidates.push(p);
  259.         }
  260.  
  261.         foreach ( p in candidates )
  262.             foreach ( neighbor in OrthoNeighbors(p) )
  263.                 if ( !AIRoad.IsRoadTile(neighbor) && AITile.IsBuildable(neighbor) )
  264.                     return {
  265.                         pos = neighbor,
  266.                         from = p
  267.                     };
  268.  
  269.         return null;
  270.     }
  271.  
  272.     function Begin()
  273.     {
  274.         return path[0];
  275.     }
  276.  
  277.     function End()
  278.     {
  279.         return path[path.len() - 1];
  280.     }
  281. }
  282.  
  283. function CityPathes(city1, city2)
  284. {
  285.     paths = []
  286.     pathCosts = AIList();
  287.  
  288.     destinations = CityOutletRoads(city2);
  289.  
  290.     function findOutletPath(outlet)
  291.     {
  292.         neighbors = AITileList();
  293.         neighbors.Add(outlet, 0);
  294.  
  295.         costs = {
  296.             [outlet] = 0
  297.         };
  298.  
  299.         cameFrom = {
  300.             [outlet] = null;
  301.         };
  302.  
  303.         function CostFor(current, tile)
  304.         {
  305.             return GetSlope(tile) != AITile.Slope.SLOPE_FLAT ? 2 : 1;
  306.         }
  307.  
  308.         function CostForBridge(tile)
  309.         {
  310.             return    AIBridge.GetMinLength(AIBridge.GetBridgeID(tile))
  311.                     / AIBridge.GetMaxSpeed(AIBridge.GetBridgeID(tile));
  312.         }
  313.  
  314.         function CostForTunnel(tile)
  315.         {
  316.             return    AITile.GetManhattanDistance(tile, AITunnel.GetOtherTunneEnd(tile))
  317.                     / AIEngine.GetMaxSpeed(
  318.                         AIEngineList(AIVehicle.VehicleType.VT_ROAD)
  319.                                 .Valuate(AIEngine.GetPrice)
  320.                                 .End()
  321.                     );
  322.         }
  323.  
  324.         function CalcCameFrom(tile, current)
  325.         {
  326.             if ( !cameFrom.HasItem(tile) || neighbors.GetValue(tile) < CostFor(current, tile) )
  327.                 cameFrom[tile] <- current;
  328.         }
  329.  
  330.         function AddNeighbor(tile, current)
  331.         {
  332.             if ( AIRoad.IsRoadTile(tile) && AIRoad.AreRoadTilesConnected(tile, current) )
  333.             {
  334.                 CalcCameFrom(tile, current);
  335.  
  336.                 neighbors.SetValue(tile, CostFor(current, tile));
  337.             }
  338.         }
  339.  
  340.         function AddBridge(tile)
  341.         {
  342.             if ( !AIRoad.IsRoadTile(tile) )
  343.                 return;
  344.  
  345.             if ( AIBridge.IsBridgeTile(tile) )
  346.             {
  347.                 CalcCameFrom(AIBridge.GetOtherBridgeEnd(tile), tile);
  348.  
  349.                 neighbors.SetValue(tile, CostForBridge(tile));
  350.             }
  351.  
  352.             else if ( AITunnel.IsTunnelTile(tile) )
  353.             {
  354.                 CalcCameFrom(AITunnel.GetOtherTunneEnd(tile), tile);
  355.  
  356.                 neighbors.SetValue(tile, CostForTunnel(tile));
  357.             }
  358.         }
  359.  
  360.         while ( neighbors.Count() > 0 )
  361.         {
  362.             t = neighbors.Begin();
  363.             neighbors.RemoveTop(1);
  364.  
  365.             // orthogonals
  366.             AddNeighbor(tile - AIMap.GetTileIndex(1,0));
  367.             AddNeighbor(tile - AIMap.GetTileIndex(0,1));
  368.             AddNeighbor(tile - AIMap.GetTileIndex(-1,0));
  369.             AddNeighbor(tile - AIMap.GetTileIndex(0,-1));
  370.  
  371.             AddBridge(tile);
  372.         }
  373.  
  374.         pathes = [];
  375.         pcosts = AIList();
  376.  
  377.         foreach ( dest in destinations )
  378.         {
  379.             path = [];
  380.             c = dest;
  381.  
  382.             while ( c != null && c in cameFrom )
  383.             {
  384.                 path.push(c);
  385.  
  386.                 c = cameFrom[c];
  387.  
  388.                 if ( c == outlet )
  389.                     break;
  390.             }
  391.  
  392.             pcosts.SetValue(pathes.len(), costs[dest]);
  393.             path.reverse();
  394.             pathes.push(path);
  395.         }
  396.  
  397.         return {
  398.             "pathes" = pathes,
  399.             "costs" = pcosts
  400.         };
  401.     }
  402.  
  403.     foreach ( outlet, _ in CityOutletRoads(city1) )
  404.     {
  405.         res = findOutletPath(outlet);
  406.  
  407.         paths.extend(RoadPath(res.pathes));
  408.         pathCosts.AddList(res.costs);
  409.     }
  410.  
  411.     return {
  412.         "pathes": paths,
  413.         "costs": pathCosts
  414.     };
  415. }
  416.  
  417. function ClosestCityPath(city1, city2)
  418. {
  419.     res = CityPathes(city1, city2);
  420.  
  421.     if ( res.costs.Count() == 0 )
  422.         return null;
  423.  
  424.     return res.pathes[res.costs.Begin()];
  425. }
  426.  
  427. function pollEvents()
  428. {
  429.     while (AIEventController.IsEventWaiting()) {
  430.         local e = AIEventController.GetNextEvent();
  431.  
  432.         switch (e.GetEventType()) {
  433.             case AIEvent.AI_ET_VEHICLE_CRASHED:
  434.                 local ec = AIEventVehicleCrashed.Convert(e);
  435.                 local v  = ec.GetVehicleID();
  436.                 AILog.Info("We have a crashed vehicle (" + v + ")");
  437.  
  438.                 /* Handle the crashed vehicle */
  439.                 AIVehicle.StartStopVehicle( wAIVehicle.CloneVehicle(
  440.                     AIDepotList()
  441.                             .Valuate(ClosestDepotToRoad(
  442.                                 AIEventVehicleCrashed.Convert(e).GetCrashSite())
  443.                             )
  444.                             .End(),
  445.  
  446.                     AIEventVehicleCrashed.Convert(e).GetVehicleID();
  447.                     true
  448.                 ) );
  449.  
  450.                 break;
  451.         }
  452.     }
  453. }
  454.  
  455. function max(a, b)
  456. {
  457.     return a > b ? a : b;
  458. }
  459.  
  460. function EstimateNumVehicles(path, engine)
  461. {
  462.     return max(
  463.         AITile.GetManhattanDistance(path.Begin(), path.End()) + 3) / AIEngine.GetMaxSpeed(engine)
  464.                 - AIEngine.GetCapacity(engine) / 8),
  465.  
  466.         1
  467.     );
  468. }
  469.  
  470. function linkGivenCities(engine, start, end)
  471. {
  472.     path = ClosestCityPath(start, end);
  473.  
  474.     if ( path == null )
  475.     {
  476.         AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + ": No path found!");
  477.  
  478.         return false;
  479.     }
  480.  
  481.     if ( !path.BuildPath() )
  482.     {
  483.         AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + ": Road building failed!");
  484.  
  485.         return false;
  486.     }
  487.  
  488.     else
  489.     {
  490.         depot = path.RandomNeighboringPoint();
  491.  
  492.         if ( depot == null )
  493.         {
  494.             AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + ": No depot location found in pathway built!");
  495.  
  496.             return false;
  497.         }
  498.  
  499.         if ( !AIRoad.BuildRoadDepot(depot.pos, depot.from) )
  500.         {
  501.             AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + ": Depot building failed!");
  502.  
  503.             return false;
  504.         }
  505.  
  506.         veh = BuildVehicle(depot.pos, engine);
  507.  
  508.         for ( i = 1; i <= EstimateNumVehicles(path, engine); i++ )
  509.         {
  510.             if ( veh == null )
  511.             {
  512.                 AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + " with vehicle #" + i + ": Vehicle buying failed!");
  513.  
  514.                 return false;
  515.             }
  516.  
  517.             if ( !path.BuildStations() )
  518.             {
  519.                 AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + " with vehicle #" + i + ": Could not build stations!");
  520.  
  521.                 return false;
  522.             }
  523.  
  524.             if ( AITile.GetManhattanDistance(depot, path.Begin()) < AITile.GetManhattanDistance(depot, path.End()) )
  525.                 locs = [path.Begin(), depot.pos, path.End()];
  526.  
  527.             else
  528.                 locs = [path.Begin(), path.End(), depot.pos];
  529.  
  530.             foreach ( l in locs )
  531.             {
  532.                 if ( !AIOrder.AppendOrder(
  533.                     veh,
  534.                     l,
  535.                     l == depot.pos ? AIOrder.AIOrderFlags.OF_SERVICE_IF_NEEDED : AIOrder.AIOrderFlags.OF_NONE
  536.                 ) )
  537.                 {
  538.                     AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + " with vehicle #" + i + ": Could not add vehicle orders!");
  539.  
  540.                     return false;
  541.                 }
  542.             }
  543.  
  544.             if ( !AIVehicle.StartStopVehicle(veh) )
  545.             {
  546.                 AILog.Warning("Could not link " + AITown.GetName(start) + " to " + AITown.GetName(end) + " with vehicle #" + i + ": Could not start vehicle!");
  547.  
  548.                 return false;
  549.             }
  550.         }
  551.     }
  552.  
  553.     return true;
  554. }
  555.  
  556. function linkCities(engine)
  557. {
  558.  
  559. }
  560.  
  561. class EdsgerMain extends AIController
  562. {
  563.     function Start();
  564. }
  565.  
  566. function NameCompany()
  567. {
  568.     if ( AICompany.IsMine(AICompany.CompanyID.COMPANY_SELF) )
  569.     {
  570.         retries = 0;
  571.  
  572.         while ( !AICompany.SetName(pick(names) + " " + pick(suffixes)) && retries < 25 )
  573.             retries++;
  574.  
  575.         if ( retries == 25 )
  576.         {
  577.             i = 0;
  578.  
  579.             while ( true )
  580.             {
  581.                 retries = 0;
  582.  
  583.                 while ( !AICompany.SetName(pick(names) + " " + pick(suffixes)) + " #" + i && retries < 25 )
  584.                     retries++;
  585.  
  586.                 if ( retries == 25 )
  587.                     i++;
  588.  
  589.                 else
  590.                     break;
  591.             }
  592.         }
  593.  
  594.         AICompany.SetPresidentName("Edsger W. Dijkstra")
  595.     }
  596. }
  597.  
  598. function EdsgerMain::Start()
  599. {
  600.     NameCompany();
  601.  
  602.     while (true) {
  603.         pollEvents();
  604.  
  605.         cheapVeh = AIEngineList(AIVehicle.VehicleType.VT_ROAD)
  606.             .Valuate(function(engine) {
  607.                 AICargo.HasCargoClass(AIEngine.GetCargoType(engine), pick(cityCargoClasses))
  608.             })
  609.             .KeepValue(1)
  610.             .Valuate(AIEngine.GetPrice)
  611.             .End();
  612.  
  613.         checkMoney(12000 + AIEngine.GetPrice(cheapVeh), function(cost) {
  614.             linkCities(cheapVeh);
  615.         })
  616.  
  617.         this.Sleep(150);
  618.     }
  619. }

Comments