Double Entry in AILists

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
Hephi
Engineer
Engineer
Posts: 72
Joined: 25 Oct 2009 09:56
Location: Belgium

Double Entry in AILists

Post by Hephi »

Hi, I'm having a strange problem with AIAbstractLists

for example

local townList = AITownList();
AILog.Info("b="+townList.Begin());
while(townList.HasNext()){
AILog.Info("t="+townList.Next());
}

would return this (say there are 3 towns on the map)

b= 2
t= 1
t= 0
t= 0

As you can see the last town on the list is shown twice.
If you would sort the list it will give for example

b= 0
t= 2
t= 1
t= 1

I tried fixing this by adding townList.RemoveLast(1) before
doing the loop but then it shows like (taken last sorted example)

b= 0
t= 2
t= 2

Correctly removing the last town (1) but again repeating the last item in the list twice

So, the initial list is correct but somehow the loop iterates the last item twice.
The last call to HasNext() should return false but doesn't.
Strangely enough it does return false the time after that (otherwise it would loop infinitely)


Can someone explain to me what's happening here?
Should I give up on while-loops and use for-loops instead?

edit: using 0.7.3 on win vista
--------------------------------------------------
MailAI, a casual postal service for openTTD.
--------------------------------------------------
User avatar
Zutty
Director
Director
Posts: 565
Joined: 22 Jan 2008 16:33

Re: Double Entry in AILists

Post by Zutty »

Hmmm... I cant explain whats going wrong, but I would suggest that you use a foreach loop instead...

Code: Select all

foreach(townId, _ in AITownList()) {
  AILog.Info("t="+townId);
}
Note that the _ is just a dummy variable. The foreach loop takes as parameters either (value in list) or (key, value in list). If you only wanted the values then you could omit the key (though you cant omit the value and only get the key). For example...

Code: Select all

local total = 0, towns = AITownList();
towns.Valuate(AITown.GetPopulation);
foreach(population in towns) total += population;
AILog.Info("Total world population is "+total);
Hope this helps.
PathZilla - A networking AI - Now with tram support.
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: Double Entry in AILists

Post by Zuu »

That is awesome! Didn't knew you could use the foreach loop for AI*List. I have been using it only for Squirrel arrays. The foreach loop saves so much typing that could go wrong. :-)
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Blustuff
Engineer
Engineer
Posts: 112
Joined: 21 Aug 2008 09:37
Location: France

Re: Double Entry in AILists

Post by Blustuff »

You can use foreach on tables, arrays and objects (not necessary instances, I'm not sure) which have a suitable metamethod.
Hephi
Engineer
Engineer
Posts: 72
Joined: 25 Oct 2009 09:56
Location: Belgium

Re: Double Entry in AILists

Post by Hephi »

Thanks, I didn't know the foreach loop worked with AILists as well, I've been using it only for arrays like

foreach(route in routeArray){...}

It took me a while to understand the difference between key and value.
Now I can use

foreach(route, dummy in List)

where I could use the dummy if I had valuated the list before.
--------------------------------------------------
MailAI, a casual postal service for openTTD.
--------------------------------------------------
honnes
Engineer
Engineer
Posts: 30
Joined: 22 Sep 2009 16:07

Re: Double Entry in AILists

Post by honnes »

Just to make a guess what could have been the cause of the previous while loop. I thought that in while loops, that the condition is being checked after the while loop has taken place, so that could be why the last entry is shown twice.

If you're not a fan of the foreach in squirrel, you could use the following:

Untested, not sure if it's like this, but I guess it is:

Code: Select all

do 
{
//code
}while( <statement> )
honnes
Engineer
Engineer
Posts: 30
Joined: 22 Sep 2009 16:07

Re: Double Entry in AILists

Post by honnes »

Zuu wrote:That is awesome! Didn't knew you could use the foreach loop for AI*List. I have been using it only for Squirrel arrays. The foreach loop saves so much typing that could go wrong. :-)
Never thought someone like you would still learn something in the OpenTTD developing section after being here for 6 years :mrgreen:

Note: It's just meant as a positive joke, nothing offensive :) If you feel different about it, let me know and i'll delete this post
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: Double Entry in AILists

Post by Zuu »

Hehe, no offense taken. Yes one can never learn enough.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Hephi
Engineer
Engineer
Posts: 72
Joined: 25 Oct 2009 09:56
Location: Belgium

Re: Double Entry in AILists

Post by Hephi »

I thought the while(){...} evaluated first and then executed and
the do{...}while() executed one time at least and then evaluated
--------------------------------------------------
MailAI, a casual postal service for openTTD.
--------------------------------------------------
Blustuff
Engineer
Engineer
Posts: 112
Joined: 21 Aug 2008 09:37
Location: France

Re: Double Entry in AILists

Post by Blustuff »

Hephi wrote:I thought the while(){...} evaluated first and then executed and
the do{...}while() executed one time at least and then evaluated
And you were right.
honnes wrote:Never thought someone like you would still learn something in the OpenTTD developing section after being here for 6 years :mrgreen:
Actually, Squirrel isn't used by AI developpers for six years. I don't know when Squirrel have been choosen as the new AI language. And the manual is actually so inaccurate that the only way to know everything about squirrel is to read the source code of the compiler / virtual machine or to make thousands of weird tests.
Hephi
Engineer
Engineer
Posts: 72
Joined: 25 Oct 2009 09:56
Location: Belgium

Re: Double Entry in AILists

Post by Hephi »

Zutty wrote:The foreach loop takes as parameters either (value in list) or (key, value in list). If you only wanted the values then you could omit the key (though you cant omit the value and only get the key).

Actually I believe you can omit the value and get the key.

Code: Select all

tile_list.AddTile(aTile);
tile_list.AddTile(bTile);
tile_list.AddTile(cTile);
foreach(tile in tile_list)
{
  AILog.Info("tile = "+tile);
} 
This would give me the tiles I put in the list without having to write foreach(tile, dummy in list).
--------------------------------------------------
MailAI, a casual postal service for openTTD.
--------------------------------------------------
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: Double Entry in AILists

Post by Zuu »

No, in that case you will get the values, not the keys.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Hephi
Engineer
Engineer
Posts: 72
Joined: 25 Oct 2009 09:56
Location: Belgium

Re: Double Entry in AILists

Post by Hephi »

ok, I see the error of my ways now :)
--------------------------------------------------
MailAI, a casual postal service for openTTD.
--------------------------------------------------
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 6 guests