NoAI Branch - An AI Framework
Moderator: OpenTTD Developers
And finally it is there: binaries! You can get them here:
http://nightly.openttd.org/noai/scoreboard.php
It gives you a pretty nice set of API functions. Although you won't be able to do anything fancy with it, you can at least make primitive bus-routes. Soon more and more functions will be added, but this at least should get your on your way. If you detect any problems/errors/bugs, feel free to tell us about it! Have fun writing your own AI
http://nightly.openttd.org/noai/scoreboard.php
It gives you a pretty nice set of API functions. Although you won't be able to do anything fancy with it, you can at least make primitive bus-routes. Soon more and more functions will be added, but this at least should get your on your way. If you detect any problems/errors/bugs, feel free to tell us about it! Have fun writing your own AI
The only thing necessary for the triumph of evil is for good men to do nothing.
AI: Clueless
Note: I'm just playing around with the API. This is not meant to be the next big thing.
Posting a shot of my AI, now named Clueless.
Out of 7 AIs four of them make profit, and then we should remember that they all play on the same quite small map with 14 towns of various sizes.
[EDIT: in year 1957 of the same game: 6 of 7 AIs make profit]
Yep, the road-network don't look pretty with several AIs. With the current API it is hard to make use of existing road-networks since you can't tell if two tiles actually are connected with each other by road. Even if two adjacent tiles have road they might not be connected.
The world-information available though the current API:
* Location of towns/cities and their population.
* If a given tile have road on it or not
* If the company can or can not build roads from center to center of tiles.
* If the company can or can not build stations and/or depots on a given tile.
Clueless basically chooses two cities to connect. Build a road-station and a depot in each city. Find a road tile in the border of each town. Connect the border-tiles with an inter-city road. Currently each border-tile is marked with a sign. (for debug purpose) You see there is 56 signs => 56/2 = 28 inter-city-connections.
At some point Clueless will meet the public audience in person (as much as an AI can! ), but for now he have chosen to only show a picture of himself.
A funny side note, If Clueless find other clueless companies it think that it is not so clueless after all and name himself something less clueless. The more other clueless companies he finds, the smarter Clueless think that he is.
Posting a shot of my AI, now named Clueless.
Out of 7 AIs four of them make profit, and then we should remember that they all play on the same quite small map with 14 towns of various sizes.
[EDIT: in year 1957 of the same game: 6 of 7 AIs make profit]
Yep, the road-network don't look pretty with several AIs. With the current API it is hard to make use of existing road-networks since you can't tell if two tiles actually are connected with each other by road. Even if two adjacent tiles have road they might not be connected.
The world-information available though the current API:
* Location of towns/cities and their population.
* If a given tile have road on it or not
* If the company can or can not build roads from center to center of tiles.
* If the company can or can not build stations and/or depots on a given tile.
Clueless basically chooses two cities to connect. Build a road-station and a depot in each city. Find a road tile in the border of each town. Connect the border-tiles with an inter-city road. Currently each border-tile is marked with a sign. (for debug purpose) You see there is 56 signs => 56/2 = 28 inter-city-connections.
At some point Clueless will meet the public audience in person (as much as an AI can! ), but for now he have chosen to only show a picture of himself.
A funny side note, If Clueless find other clueless companies it think that it is not so clueless after all and name himself something less clueless. The more other clueless companies he finds, the smarter Clueless think that he is.
- Attachments
-
- scenario.scn
- The scenario if someone wants to use it.
- (47.09 KiB) Downloaded 248 times
-
- clueless.png
- (178.87 KiB) Downloaded 376 times
Last edited by Zuu on 27 Mar 2007 18:45, edited 2 times in total.
I tough I post the VIM syntax file I've made by modifying a copy of the C++ syntax file.
It is just a hack, it is not complete in any sense. I've just added most of the Squirrel keywords to the syntax-file and removed some C++-keywords that are not present in Squirrel.
However there are lot of more stuff to do to if you want all Squirrel language features to be included and highlighted in the correct way. Also lot of C/C++ stuff are highlighted which are not present in Squirrel.
If you want it use it, use it. If you find my hack too much of a hack then you're welcome to make something better.
It is just a hack, it is not complete in any sense. I've just added most of the Squirrel keywords to the syntax-file and removed some C++-keywords that are not present in Squirrel.
However there are lot of more stuff to do to if you want all Squirrel language features to be included and highlighted in the correct way. Also lot of C/C++ stuff are highlighted which are not present in Squirrel.
If you want it use it, use it. If you find my hack too much of a hack then you're welcome to make something better.
- Attachments
-
- squirrel.vim.txt
- Place this file in ~/.vim/syntax/ and remove the .txt-extension.
- (1.8 KiB) Downloaded 248 times
-
- filetype.vim.txt
- Place this file in ~/.vim/ to make VIM use squirrel.vim automatically on '.not'-files. (remember to remove the .txt extension)
- (155 Bytes) Downloaded 229 times
Great work you have done here
After just looking things over i had a few ideas, but dont worry, i wont bother you with all of them.
A suggestion for expanding the AIIndustry class:
Static IndustryID getRandomIndustry()
Static IndustryID getRandomIndustry(IndustryType type)
Static IndustryID getIndustryIndex(TileIndex tile)
Static IndustryType getIndustryType(IndustryID id)
Static TileIndex getIndustryTile(IndustryID id)
Static byte getIndustryType(IndustryID id)
Static CargoID[3] getAcceptedCargo(IndustryID id)
Static CargoID[2] getCargoProduced(IndustryID id)
Static byte[2] getLastMonthCargoProduction(IndustryID id)
Static byte[2] getPctTransported(IndustryID id)
This is a result of a brainstorm and maybe some of this is not viable, but most should be pretty straightforward to implement.
-klaus
After just looking things over i had a few ideas, but dont worry, i wont bother you with all of them.
A suggestion for expanding the AIIndustry class:
Static IndustryID getRandomIndustry()
Static IndustryID getRandomIndustry(IndustryType type)
Static IndustryID getIndustryIndex(TileIndex tile)
Static IndustryType getIndustryType(IndustryID id)
Static TileIndex getIndustryTile(IndustryID id)
Static byte getIndustryType(IndustryID id)
Static CargoID[3] getAcceptedCargo(IndustryID id)
Static CargoID[2] getCargoProduced(IndustryID id)
Static byte[2] getLastMonthCargoProduction(IndustryID id)
Static byte[2] getPctTransported(IndustryID id)
This is a result of a brainstorm and maybe some of this is not viable, but most should be pretty straightforward to implement.
-klaus
I agree with thosekaan wrote:Static IndustryID getRandomIndustry()
Static IndustryID getIndustryIndex(TileIndex tile)
The industry type is an internal value that doesn't mean anything solid once newindustries gets introduced.kaan wrote:Static IndustryID getRandomIndustry(IndustryType type)
Static IndustryType getIndustryType(IndustryID id)
Already implemented (GetLocation)kaan wrote:Static TileIndex getIndustryTile(IndustryID id)
I was rather thinking about returning the accepted cargo for a given tile (as that 'merges' it with towns), especially because not all industry tiles accept cargo. However, it makes it harder (for an AI) to determine the types. I'm rather thinking about adding bool industry.Cargo[Produced|Accepted](CargoID) to make iterating industries a little easier, i.e. simplifying AIs that want to check for a single cargo type.kaan wrote:Static CargoID[3] getAcceptedCargo(IndustryID id)
Static CargoID[2] getCargoProduced(IndustryID id)
The same problem as with the previous one exists, however this might be more troublesome as you need to know the cargo types to get any usefull information... I'm not really sure what to do with these functions.kaan wrote:Static byte[2] getLastMonthCargoProduction(IndustryID id)
Static byte[2] getPctTransported(IndustryID id)
GreatRubidium wrote:I agree with thosekaan wrote:Static IndustryID getRandomIndustry()
Static IndustryID getIndustryIndex(TileIndex tile)
No reason to do this then. Alternatly we could define our own industrytype but it is hardly worth the trouble.Rubidium wrote:The industry type is an internal value that doesn't mean anything solid once newindustries gets introduced.kaan wrote:Static IndustryID getRandomIndustry(IndustryType type)
Static IndustryType getIndustryType(IndustryID id)
There is no arguing with thatRubidium wrote:Already implemented (GetLocation)kaan wrote:Static TileIndex getIndustryTile(IndustryID id)
a bool would be usefull for iterating for a match among many industries, but if you want to exploit a specific industry it really makes no sence to iterate through all cargotypes (twice) just to obtain accepts/produces.Rubidium wrote:I was rather thinking about returning the accepted cargo for a given tile (as that 'merges' it with towns), especially because not all industry tiles accept cargo. However, it makes it harder (for an AI) to determine the types. I'm rather thinking about adding bool industry.Cargo[Produced|Accepted](CargoID) to make iterating industries a little easier, i.e. simplifying AIs that want to check for a single cargo type.kaan wrote:Static CargoID[3] getAcceptedCargo(IndustryID id)
Static CargoID[2] getCargoProduced(IndustryID id)
I think a well formatted struct would be a good solution to these kinds of information.Rubidium wrote:The same problem as with the previous one exists, however this might be more troublesome as you need to know the cargo types to get any usefull information... I'm not really sure what to do with these functions.kaan wrote:Static byte[2] getLastMonthCargoProduction(IndustryID id)
Static byte[2] getPctTransported(IndustryID id)
The reason i picked this format was that i lifted it from the industry struct in industry.h
Code: Select all
/**
* Defines the internal data of a functionnal industry
*/
struct Industry {
TileIndex xy; ///< coordinates of the primary tile the industry is built one
byte width;
byte height;
const Town* town; ///< Nearest town
CargoID produced_cargo[2]; ///< 2 production cargo slots
uint16 cargo_waiting[2]; ///< amount of cargo produced per cargo
byte production_rate[2]; ///< production rate for each cargo
CargoID accepts_cargo[3]; ///< 3 input cargo slots
byte prod_level; ///< general production level
uint16 last_mo_production[2]; ///< stats of last month production per cargo
uint16 last_mo_transported[2]; ///< stats of last month transport per cargo
byte pct_transported[2]; ///< percentage transported per cargo
uint16 total_production[2]; ///< total units produced per cargo
uint16 total_transported[2]; ///< total units transported per cargo
uint16 counter; ///< used for animation and/or production (if available cargo)
byte type; ///< type of industry. see IT_COAL_MINE and others
OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE
byte random_color; ///< randomized colour of the industry, for display purpose
Year last_prod_year; ///< last year of production
byte was_cargo_delivered; ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry
IndustryID index; ///< index of the industry in the pool of industries
};
Thanks for commenting
-klaus
Console
Hello,
I've tried to run the example AI that comes with the binary. But it does not seem to do anything. A new company is indeed started, called NoAI. So that works.
I do not see any output from it. I'd expect this to go to the console, but I have noticed no output there. So where are its messages printed instead?
I'm 100% assured it runs; I forgot to sleep(1), and the game hung in an infinite while loop in main.nut. After I added it, it did not hang (had to restart the game in this case, of couse).
Is there a way to obtain information about the AI through the
console?
Is there a manual or wiki for the console?
Is there a list with API functions, and their functioning? Of course, I found the functions as used in regression.nut, but as I do not see where the output goes, it's kinda blind programming like this.
Anyway, the whole idea of this is simply marvellous!
I've tried to run the example AI that comes with the binary. But it does not seem to do anything. A new company is indeed started, called NoAI. So that works.
I do not see any output from it. I'd expect this to go to the console, but I have noticed no output there. So where are its messages printed instead?
I'm 100% assured it runs; I forgot to sleep(1), and the game hung in an infinite while loop in main.nut. After I added it, it did not hang (had to restart the game in this case, of couse).
Is there a way to obtain information about the AI through the
console?
Is there a manual or wiki for the console?
Is there a list with API functions, and their functioning? Of course, I found the functions as used in regression.nut, but as I do not see where the output goes, it's kinda blind programming like this.
Anyway, the whole idea of this is simply marvellous!
A game worth playing is a game worth modding
Unless things have changed the last week you need to watch the terminal-window, not the in-game console. If you start openTTD using other means than a terminal-window, I'm afraid you need to start openTTD via a terminal window to receive the output.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Junctioneer (a traffic intersection simulator)
Thanks, Zuu and glx!
I got it running, and I now have an AI intelligent enough to print the tick value every 1000 ticks
I noticed some unexpected behaviour though: contrary to what I had expected, squirrel also inteprets files that are not named main.nut. Actually, it does not even seem to need the extension .nut. It seems to me that it looks into each subdirectory of ai for an intepretable file....
So, which files does squirrel consider when it chooses an AI?
Is it going to be possible in the future that (for debugging purposes) the user can restart or stop an AI?
I got it running, and I now have an AI intelligent enough to print the tick value every 1000 ticks
I noticed some unexpected behaviour though: contrary to what I had expected, squirrel also inteprets files that are not named main.nut. Actually, it does not even seem to need the extension .nut. It seems to me that it looks into each subdirectory of ai for an intepretable file....
So, which files does squirrel consider when it chooses an AI?
Is it going to be possible in the future that (for debugging purposes) the user can restart or stop an AI?
OpenTTD scans the ai/ dir for files called 'main.nut' and opens them. It doesn't check for any other file, it doesn't try to open any file, 'main.nut' is the only thing it does. Even more: it needs to be in the FIRST subdir of ai/. So if you think it loads an AI even if you don't have a main.nut, I would suggest to look really close once moregriffin71 wrote:Thanks, Zuu and glx!
I got it running, and I now have an AI intelligent enough to print the tick value every 1000 ticks
I noticed some unexpected behaviour though: contrary to what I had expected, squirrel also inteprets files that are not named main.nut. Actually, it does not even seem to need the extension .nut. It seems to me that it looks into each subdirectory of ai for an intepretable file....
So, which files does squirrel consider when it chooses an AI?
Is it going to be possible in the future that (for debugging purposes) the user can restart or stop an AI?
In the future there will be a GUI to control several aspects of an AI, one being the debug-information of an AI, the other being able to configure which AI to start. But all this in the future.
The only thing necessary for the triumph of evil is for good men to do nothing.
still confused...
Thanks for your respons in the first place. After spending 3 more hours on this, I conclude, that it seems that no other files are being interpreted; my earlier observations were due to the faulty assumption that which AIs are present is determined when a new game is started, but this is done when openttd is started. The main.nut files are (re-)read when a new AI is started in-game. Correct?TrueLight wrote:OpenTTD scans the ai/ dir for files called 'main.nut' and opens them. It doesn't check for any other file, it doesn't try to open any file, 'main.nut' is the only thing it does. Even more: it needs to be in the FIRST subdir of ai/. So if you think it loads an AI even if you don't have a main.nut, I would suggest to look really close once more
However, without that there is another AI main.nut present, sometimes, there seems to be a default AI called NoAI that gives massive output like
[terminal]
NoAI Transport has loaned 90000
NoAI 525425600 Transport has loaned 80000
Town Prinnton [11 of 25] at (73, 201) with 733 inhabitants
[/terminal]
For sake of clarity, I have added my current ai directory that shows this behaviour.
Sounds great!In the future there will be a GUI to control several aspects of an AI, one being the debug-information of an AI, the other being able to configure which AI to start. But all this in the future.
- Attachments
-
- ai.rar
- Does this contain an AI called NoAI?
- (95.39 KiB) Downloaded 217 times
A game worth playing is a game worth modding
glx, you can smile about that, but how do I get rid of it? Since there is no sourcefile available, I cannot recompile without NoAI active?glx wrote:NoAI is a c++ AI
Or am I making a major stupid remark? (could be, of course, I'm still new on this forum....)
A game worth playing is a game worth modding
[url]svn://svn.openttd.org/branches/noai/[/url]
Don't panic - My YouTube channel - Follow me on twitter (@XeryusTC) - Play Tribes: Ascend - Tired of Dropbox? Try SpiderOak (use this link and we both get 1GB extra space)
OpenTTD: manual #openttdcoop: blog | wiki | public server | NewGRF pack | DevZone
OpenTTD: manual #openttdcoop: blog | wiki | public server | NewGRF pack | DevZone
the source is also available there, along with binaries for all platforms (same as nightlies)
There is a command line option (-a "ai name") to specify one AI that openTTD will use so that you don't have to wait untill the randomness starts your AI. (by default openTTD starts a random AI when an AI-company is started).griffin71 wrote:glx, you can smile about that, but how do I get rid of it? Since there is no sourcefile available, I cannot recompile without NoAI active?glx wrote:NoAI is a c++ AI
Or am I making a major stupid remark? (could be, of course, I'm still new on this forum....)
for example I start my AI by
Code: Select all
./openttd -a "Clueless" -g "ai/Clueless/scenario.scn"
EDIT: I guess you wanted to remove NoAI so that you're AI become the only AI because of the issue described above. If your reasons are other, I'm sorry I've misinterpreted you.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
Junctioneer (a traffic intersection simulator)
Who is online
Users browsing this forum: No registered users and 40 guests