AIList.Valuate for dummies

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
Vasco
Engineer
Engineer
Posts: 3
Joined: 14 Jan 2019 13:30

AIList.Valuate for dummies

Post by Vasco » 01 Feb 2019 14:17

Hi folks,

I'm currently trying to figure out the AIList.Valuate function but it does not really make much sense to me yet.
Somehow it seems it valuates the index instead of the value of my list.

What I'm trying to archive: I want to check all waypoint locations in the DistanceManhattan to a specific tile.
Before this I did this with a for loop through all elements but it's slow and a lot of code for something (I thought) so simple.

What I came up with so far:

Code: Select all

intersections.Valuate(AIBaseStation.GetLocation); //asign tile ID to value
_info("manual calculated between: " + intersections.GetValue(intersections.Begin()) + " and " + tileS + " is: " + AIMap.DistanceManhattan(intersections.GetValue(intersections.Begin()),tileS),2);
_info("1---------------------------",1)
foreach (key,value in intersections)
	_info(key + " --> " + value)
_info("2---------------------------",1)
intersections.Valuate(distance, tileS)
foreach (key,value in intersections)
	_info(key + " --> " + value)
This produces for example following debug:
manual calculated between: 248265 and 169443 is: 180
1--------------------
2 --> 248265
4 --> 211915
2--------------------
4 --> -1
2 --> -1
so clearly the distance is not calculated. My distance function (I used AIMap.DistanceManhattan before but want to debug more) looks like this:

Code: Select all

function distance(tile1, tile2)
{
AILog.Error ("E---------------------------")
AILog.Info ("Tile 1: " + tile1 + " and Tile 2: " + tile2 + " are " + AIMap.DistanceManhattan(tile1,tile2)+ " tiles appart")
return AIMap.DistanceManhattan(tile1,tile2)
}
which returns:
E--------------------
Tile 1: 2 and Tile2: 169443 are -1 tiles appart
conclusion: it seems instead of value the index is passed to my function. Everything I'm reading in other AI they used the exact same approach. Where do I got it wrong? How can I hand over the value of index 2 instead of 2?

for the sake of completeness: My _info function just prints debug messages and formats/add time stamp and similar. It works fine and does not appear to make any issues. Debug mode is a setting from the AIsettings

Code: Select all

function _info(message, level = 0)
{
local date = AIDate.GetYear(AIDate.GetCurrentDate()) + "-" + AIDate.GetMonth(AIDate.GetCurrentDate()) + "-" + AIDate.GetDayOfMonth(AIDate.GetCurrentDate());
message = date + ":        " + message;
switch (level) 
	{
	case 1: //warning, print always in yellow
		{
		AILog.Warning (message)
		} 
		break;
	case 2: //Error, print always in red
		{
		AILog.Error (message)
		} 
		break;
	case 3: //special case for welcome message 
		{
		AILog.Info (message)
		} 
		break;
	default: // Info but only if debug mode is set 
		{
		if (debug_mode)
			AILog.Info (message)
		}
		break;
	}
return 1	
}
Is there any better documentation/examples about valuate then the NOAI documentation which could really explain this to me? I trust it's a very powerfull function and often used in other AIs. But I simply don't get the hang the moment it goes into more than one parameter.
--> http://noai.openttd.org/api/trunk/classAIList.html

xarick
Transport Coordinator
Transport Coordinator
Posts: 266
Joined: 26 Feb 2015 00:52

Re: AIList.Valuate for dummies

Post by xarick » 03 Feb 2019 02:23

I think it's this:

Code: Select all

local intersections = AIWaypointList(AIWaypoint.WAYPOINT_ANY);
intersections.Valuate(AIStation.GetDistanceManhattanToTile, tileS);
Formerly known as Samu

User avatar
Kev!
Engineer
Engineer
Posts: 36
Joined: 21 Jun 2011 16:30
Location: In Da House!
Contact:

Re: AIList.Valuate for dummies

Post by Kev! » 20 Feb 2019 22:07

Howdy,

Not an expert by any means... but here is my understanding.

in your first code block, intersections.Valuate(AIBaseStation.GetLocation) indicates that intersections is a list of stations, and the result would be a list of stations, with their location tiles as values.

AIBaseStation.Getlocation(station_id) is the syntax i would think for a regular statement. so your valuate is looking for the station_id to be the "item", and put the location in "value" for each item-value pair in your list.

If intersections is NOT a list of station_ids then the results could be undefined!


The next bit... intersections.Valuate(distance, tileS) indicates intersections is a list of tiles, and the result would be a list of tiles, with their distance to tileS as values.

if intersections is NOT a list of tiles, then the results could be undefined!


by the logging it can be seen that intersections is not a list of stations, nor a list of tiles, so it does not surprise the wonky results!


your code for distance function looks fine. It would work if you passed actual tiles.

I don't think you can print "tiles" with AILog . maybe AIMap.GetTileX(tile1) + ", " + AIMap.GetTileY(tile1) is what you are after?


xarick's code is a good example of something similar to what you are trying to do.


Good luck, and keep at it,
Kev!

P.S. The key thing to remember for Valuate is the ITEM will be the first variable passed to the valuator, so single input functions only have the function name... blah.Valuate(function_requiring_only_one_input) where blah is a list of things the function expects as input.
I DO like a nice caboose...

HGus
Engineer
Engineer
Posts: 95
Joined: 12 May 2013 22:28
Location: Argentina

Re: AIList.Valuate for dummies

Post by HGus » 23 Feb 2019 02:42

Kev! wrote: by the logging it can be seen that intersections is not a list of stations, nor a list of tiles, so it does not surprise the wonky results!


your code for distance function looks fine. It would work if you passed actual tiles.
Actually intersections it is a list of stations (the first valuation works). The runtime type of params in the distance function are StationID tile1 and TileIndex tile2, so the AIMap.DistanceManhattan function returns an error (-1)

User avatar
Kev!
Engineer
Engineer
Posts: 36
Joined: 21 Jun 2011 16:30
Location: In Da House!
Contact:

Re: AIList.Valuate for dummies

Post by Kev! » 23 Feb 2019 15:59

Howdy,
HGus wrote: Actually intersections it is a list of stations (the first valuation works). The runtime type of params in the distance function are StationID tile1 and TileIndex tile2, so the AIMap.DistanceManhattan function returns an error (-1)
Ah, I see it now. So, if he used AIStation.GetDistanceManhattanToTile in his distance function, it would work as he expects

Good to understand,
Kev!
I DO like a nice caboose...

HGus
Engineer
Engineer
Posts: 95
Joined: 12 May 2013 22:28
Location: Argentina

Re: AIList.Valuate for dummies

Post by HGus » 01 Mar 2019 06:51

Kev! wrote: Ah, I see it now. So, if he used AIStation.GetDistanceManhattanToTile in his distance function, it would work as he expects
And the whole "intersections.Valuate(AIBaseStation.GetLocation)" renders redundant, cause he doesn't need to calculate the locations of the stations.

Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 4 guests