How to detect a bridge on the water?

Discuss the new AI features ("NoAI") introduced into OpenTTD 0.7, allowing you to implement custom AIs, and the new Game Scripts available in OpenTTD 1.2 and higher.

Moderator: OpenTTD Developers

Post Reply
tristanb
Engineer
Engineer
Posts: 11
Joined: 31 Oct 2010 05:27

How to detect a bridge on the water?

Post by tristanb »

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.
How do you detect a bridge in front of where the AI would like to build a dock?
How do you detect a bridge in front of where the AI would like to build a dock?
how_do_you_detect_a_bridge.png (59.47 KiB) Viewed 1805 times
Thanks for your help. I've done a bit of searching through other code, but can't find any quick answer.
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: How to detect a bridge on the water?

Post by Zuu »

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.

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)
User avatar
Michiel
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 13 Jul 2008 00:57
Contact:

Re: How to detect a bridge on the water?

Post by Michiel »

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.
tristanb
Engineer
Engineer
Posts: 11
Joined: 31 Oct 2010 05:27

Re: How to detect a bridge on the water?

Post by tristanb »

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.
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: How to detect a bridge on the water?

Post by planetmaker »

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.
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?
User avatar
Lord Aro
Tycoon
Tycoon
Posts: 2369
Joined: 25 Jun 2009 16:42
Location: Location, Location
Contact:

Re: How to detect a bridge on the water?

Post by Lord Aro »

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
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 10 guests