Hi all. I'm playing around with a ship building AI, at the very early stages - so far all it does it try to detect the "best" place to put a dock in a city.
To check if a dock is buildable, I test that the slope faces onto a water tile with AITile.IsWaterTile. My problem is with bridges.
If there is a bridge, the AI API still detects this as a water tile - which I'm okay about. The problem is, I cannot find any other function to exclude a bridge being there. I have tried AIBridge.GetBridgeID (to see if not -1) and AITile.HasTransportType (testing for road or rail). But the former must only work on the bridge end tiles.
What are my options? Will I need to enumerate through all the bridges to check none of them intersect my water tile?
I've attached a picture to show what I mean. The AI wants to build a dock where the pink arrow ends - it has no way of detecting that the water tile in front onto has a bridge over it.
Thanks for your help. I've done a bit of searching through other code, but can't find any quick answer.
How to detect a bridge on the water?
Moderator: OpenTTD Developers
Re: How to detect a bridge on the water?
You need to iterate in the +/-90 degree direction from the tile you want to check until you find a bridge head in order to check if there is a bridge or not. This is the same as how to find a bridge on land.
I've implemented a function for this in my SuperLib library: SuperLib::Tile::GetBridgeAboveStart(tile, bridge_search_direction)
Note that bridge_search_direction is a Direction constant found in SuperLib::Direction.
I've implemented a function for this in my SuperLib library: SuperLib::Tile::GetBridgeAboveStart(tile, bridge_search_direction)
Note that bridge_search_direction is a Direction constant found in SuperLib::Direction.
Code: Select all
function _SuperLib_Tile::GetBridgeAboveStart(tile, bridge_search_direction)
{
if (!_SuperLib_Direction.IsMainDir(bridge_search_direction))
{
_SuperLib_Log.Error("Tile::GetBridgeAboveStart(tile, bridge_search_direction) was called with a non-main direction", _SuperLib_Log.LVL_INFO);
return -1;
}
local max_height = AITile.GetMaxHeight(tile);
for (local curr_tile = _SuperLib_Direction.GetAdjacentTileInDirection(tile, bridge_search_direction);
AIMap.IsValidTile(curr_tile);
curr_tile = _SuperLib_Direction.GetAdjacentTileInDirection(curr_tile, bridge_search_direction))
{
local curr_tile_height = AITile.GetMaxHeight(curr_tile);
if (curr_tile_height < max_height)
{
// The down slope at the other side of a hill has been found -> There can't be a bridge to 'tile'.
return -1;
}
max_height = Helper.Max(max_height, curr_tile_height);
if (AIBridge.IsBridgeTile(curr_tile))
{
// A bridge was found
// Check that the bridge goes in the right direction
local other_end = AIBridge.GetOtherBridgeEnd(curr_tile);
local found_bridge_dir = _SuperLib_Direction.GetDirectionToTile(curr_tile, other_end);
// Return -1 if the bridge direction is wrong eg. 90 deg of bridge_search_direction or away from the tile 'tile'
return found_bridge_dir == bridge_search_direction? curr_tile : -1;
}
}
return -1;
}
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Junctioneer (a traffic intersection simulator)
Re: How to detect a bridge on the water?
Alternatively, keep a list of the best spots you found and just try to build the dock at the first one. If it fails, try the next (and maybe plant a sign with the error message on the first spot). That way, you don't have to specifically handle this unfortunate case, or others you didn't think of yet.
Re: How to detect a bridge on the water?
Hey thanks both for your help.
I'll use a combination of both the lateral-search, but later I guess I'll need a robust repositioning in case there's a stray boat or something else unexpected blocking the way.
Interesting to see your library, Zuu. It looks like incredibly useful, and contains functions that I have thought about myself. I'm planning to only ever use boats, so I probably won't use it, but it'll be a great reference for working out how to do things.
I'll use a combination of both the lateral-search, but later I guess I'll need a robust repositioning in case there's a stray boat or something else unexpected blocking the way.
Interesting to see your library, Zuu. It looks like incredibly useful, and contains functions that I have thought about myself. I'm planning to only ever use boats, so I probably won't use it, but it'll be a great reference for working out how to do things.
- planetmaker
- OpenTTD Developer
- Posts: 9432
- Joined: 07 Nov 2007 22:44
- Location: Sol d
Re: How to detect a bridge on the water?
Even if you only use boats: what's the point of re-inventing the wheel instead of using an existing library which exists, is readily on bananas and - as you say - provides those functions you need?tristanb wrote: It looks like incredibly useful, and contains functions that I have thought about myself. I'm planning to only ever use boats, so I probably won't use it, but it'll be a great reference for working out how to do things.
OpenTTD: manual | online content | translations | Wanted contributions and patches
#openttdcoop: blog | wiki | public server | DevZone | NewGRF web translator
DevZone - home of the free NewGRFs: OpenSFX | OpenMSX | OpenGFX | Swedish Rails | OpenGFX+ Trains|RV|Industries|Airports|Landscape | NML
Re: How to detect a bridge on the water?
As discussed on irc, it is very easy to implement a function that provides this (line 58 of bridge_map.h
)

AroAI - A really feeble attempt at an AI
It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration. --Edsger Dijkstra
It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration. --Edsger Dijkstra
Who is online
Users browsing this forum: No registered users and 10 guests