AI API How to detect a house on a tile.

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
crs
Engineer
Engineer
Posts: 2
Joined: 06 Jul 2023 20:30

AI API How to detect a house on a tile.

Post by crs »

Hello,

First time post here. Played on and off since childhood. Mighty props to the dev community of OpenTTD.

Im also a professional developer and turned some free time to writing an AI for fun.

I have though quite a problem which is either my lack of knowledge of the AI API or an oversight of its development, which is...

How do I detect if a tile contains a house/building, specifically one that generates passengers.

I am currently using this code, which has more than a minor code-smell feel to it.

Code: Select all

static function DoesTileHaveHouse(tileIndex)
	{
		if (AITile.IsBuildable(tileIndex)) { return false; }
		
		if (AIRoad.IsRoadTile(tileIndex)) { return false; }
		if (AIRoad.IsRoadDepotTile(tileIndex)) { return false; }
		if (AITile.IsSeaTile(tileIndex)) { return false; }
		if (AITile.IsWaterTile(tileIndex)) { return false; }
		if (AITile.IsStationTile(tileIndex)) { return false; }
		if (AITile.HasTreeOnTile(tileIndex)) { return false; }
		if (AITile.IsFarmTile(tileIndex)) { return false; }
		if (AITile.IsRockTile(tileIndex)) { return false; }
		if (AITile.IsRoughTile(tileIndex)) { return false; }
		if (AIIndustry.GetIndustryID(tileIndex) != 65535) { return false; }
		
		return true;
	}
It essentially tests if the tile is not buildable (has something on it), and then excludes all other reasons (that I can think of) for the tile to not be buildable, so left with only the last possibility that is has a house on it.

What is the correct way to detect if a tile has a house?

If one does not exist, how can I escalate to the dev team to implement this?

V13.0
User avatar
jfs
Tycoon
Tycoon
Posts: 1764
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: AI API How to detect a house on a tile.

Post by jfs »

crs wrote: 06 Jul 2023 20:39 How do I detect if a tile contains a house/building, specifically one that generates passengers.
I think you're right that this doesn't actually exist. At least not in an obvious way.
crs wrote: 06 Jul 2023 20:39 If one does not exist, how can I escalate to the dev team to implement this?
https://github.com/OpenTTD/OpenTTD/issues
crs
Engineer
Engineer
Posts: 2
Joined: 06 Jul 2023 20:30

Re: AI API How to detect a house on a tile.

Post by crs »

FOUND SOLUTION, YAY!

Staring me in the face in AITile.

Code: Select all

AITile.GetCargoProduction(tileIndex, cargoId, width, height, radius);
Where:
cargoId is 0 (representing passengers).
width is 1 (for a bus stop).
height is 1 (for a bus stop).
radius is 3 (for a bus stop catchment area).
User avatar
2TallTyler
Route Supervisor
Route Supervisor
Posts: 507
Joined: 11 Aug 2019 18:15
Contact:

Re: AI API How to detect a house on a tile.

Post by 2TallTyler »

You're also welcome to submit a Pull Request to add such a method.

A good reference for the basics of adding an AI/GS method would be this PR. You may want to add some regression checks as seen in this PR, but feel free to start with the first step and we can help you add the second through discussion on GitHub or on the Discord. Most of us developers hang out in those places, not here.
HGus
Engineer
Engineer
Posts: 121
Joined: 12 May 2013 22:28
Location: Argentina

Re: AI API How to detect a house on a tile.

Post by HGus »

Why not?

Code: Select all

static function DoesTileHaveHouse(tileIndex)
	{
		if (AITile.IsBuildable(tileIndex)) 
		
		|| (AIRoad.IsRoadTile(tileIndex))
		|| (AIRoad.IsRoadDepotTile(tileIndex)) 
		|| (AITile.IsSeaTile(tileIndex)) 
		|| (AITile.IsWaterTile(tileIndex)) 
		|| (AITile.IsStationTile(tileIndex))
		|| (AITile.HasTreeOnTile(tileIndex)) 
		|| (AITile.IsFarmTile(tileIndex)) 
		|| (AITile.IsRockTile(tileIndex)) 
		|| (AITile.IsRoughTile(tileIndex)) 
		|| (AIIndustry.GetIndustryID(tileIndex) != 65535) { return false; }
		
		return true;
	}
User avatar
jfs
Tycoon
Tycoon
Posts: 1764
Joined: 08 Jan 2003 23:09
Location: Denmark

Re: AI API How to detect a house on a tile.

Post by jfs »

While that might use a little fewer ops for the purpose of counting script time before suspend, it doesn't change the logical complexity of it at all. The question is about whether there is a direct way to tell that a tile has a house on it, instead of only an indirect "20 questions" way.
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: AI API How to detect a house on a tile.

Post by krinn »

Code: Select all

local cost = AIAccounting();
local test = AITestMode();
local success= AITile.DemolishTile(tile);
local clearcost = cost.GetCosts();
local housecost = AITile.GetBuildCost(AITile.BT_CLEAR_HOUSE);
return (clearcost == housecost);
DemolishTile may fail (town hates you, no money to do so...), fail also if cost to clear a house is same as clear something else... and you may also need to check inflation rate

so i will just put the logic: if the cost to demolish that tile is the cost to demolish an house, that should be a tile with a house

note also: GetCargoProduction answer if an area of tiles have enough passengers to actually gives passengers, you can have an house alone, that would gives you a false answer, or you could have an empty tile surrounded by houses that would tell you there's passenger to get there while in real there's no house in that tile
Jaume
Engineer
Engineer
Posts: 54
Joined: 24 Aug 2007 15:43

Re: AI API How to detect a house on a tile.

Post by Jaume »

Another way:

Code: Select all

local test = AITestMode();
local success = AIRail.BuildRail(tile - vector, tile, tile + vector);
if (!success && AIError.GetLastError() == AIError.ERR_AREA_NOT_CLEAR) return true;
return false;
HGus
Engineer
Engineer
Posts: 121
Joined: 12 May 2013 22:28
Location: Argentina

Re: AI API How to detect a house on a tile.

Post by HGus »

krinn wrote: 09 Aug 2023 15:13
note also: GetCargoProduction answer if an area of tiles have enough passengers to actually gives passengers, you can have an house alone, that would gives you a false answer, or you could have an empty tile surrounded by houses that would tell you there's passenger to get there while in real there's no house in that tile
He wanted to check if a tile has a house with purpose to build a station. With GetCargoProduction it doesn't matter if the center tile has a house as far as it returns minimum threshold plus the output of one house.
HGus
Engineer
Engineer
Posts: 121
Joined: 12 May 2013 22:28
Location: Argentina

Re: AI API How to detect a house on a tile.

Post by HGus »

Jaume wrote: 10 Aug 2023 18:20 Another way:

Code: Select all

local test = AITestMode();
local success = AIRail.BuildRail(tile - vector, tile, tile + vector);
if (!success && AIError.GetLastError() == AIError.ERR_AREA_NOT_CLEAR) return true;
return false;
That's too much generic. He wants to know if there are houses in the area, not anything else like roads, competitor rails or industries.
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: AI API How to detect a house on a tile.

Post by krinn »

HGus wrote: 11 Aug 2023 03:17
krinn wrote: 09 Aug 2023 15:13
note also: GetCargoProduction answer if an area of tiles have enough passengers to actually gives passengers, you can have an house alone, that would gives you a false answer, or you could have an empty tile surrounded by houses that would tell you there's passenger to get there while in real there's no house in that tile
He wanted to check if a tile has a house with purpose to build a station. With GetCargoProduction it doesn't matter if the center tile has a house as far as it returns minimum threshold plus the output of one house.
It does if the threshold is too low and the one space you build the station on is the space that had a house, lowering below the threashold and finishing with a station that get 0 after

For that purpose, the best way is check cargoproduction of adjacents tiles to a road and only consider them (building a station not attach to an existing road mean building the road, the station and the road creation could destroy passengers production and make you hate with the town)
I think this is common feature to any AI using bus, and superlib probably have the function already made for that task
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 16 guests