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.
This code will mark every tile in the game. I understand WHY this happens. I am just wondering if it might be more intutive if adding tiles together wouldn't wrap around. I can't think of a time it would be usefull to add a deltaX, deltaY to a tile and have it wrap around.
This caused a bug for my AI where I will sometimes try to flatten really big swaths of land.
I bring it up for discussion, because it seems like a lot of work to have to check for wrap-around every time you add tiles together like this.
I think with the syntax above the NoAI interpreter isn't able to check for wrap arounds. So in order to check automatically for wrap arounds you would have to use another new API function and check for an ERR_WRAP_AROUND or something like that afterwards. In that case you would have to change many code parts of your AI.
So no matter what you would have to change your code, which means that you could also write your own wrapper function that checks for wrap arounds.
I my (hopefully soon ) upcoming AI I check first if the rect is buildable, which is highly unlikely if the coordinates wrap around. I know this isn't bulletproof, but it works for now.
In PAXLink (and maybe CluelessPlus) I have a function in the Helper class that gets a tile relative to another tile: GetTileRelative. At the moment it does not do any checks for warp arounds, but it would be quite easy to add.
Where Y is the Y-size of the map. Knowing this, you can use the modulo operator to "split" the x and y terms apart. I haven't tested it, but I'm fairly sure the folloing code would allow you to wrap around the x or y axes.
local Y = AIMap.GetMapSizeY();
local Z = Y * AIMap.GetMapSizeX();
...
while(foo) {
...
wrapX = (wrapX + 1) % Y; // Increment x by one
wrapY = (wrapY + Y) % Z; // Increment y by one
...
}
Where Y is the Y-size of the map. Knowing this, you can use the modulo operator to "split" the x and y terms apart. I haven't tested it, but I'm fairly sure the folloing code would allow you to wrap around the x or y axes.
local Y = AIMap.GetMapSizeY();
local Z = Y * AIMap.GetMapSizeX();
...
while(foo) {
...
wrapX = (wrapX + 1) % Y; // Increment x by one
wrapY = (wrapY + Y) % Z; // Increment y by one
...
}
Nice.
Sure, I can think of a lot of ways to prevent this problem. One of those ways is to go in the game code and overload the + operator for whatever type AIMap.GetTileIndex is internally. I was wondering if that was the cleanest solution.
But before I ask for game code to be changed, I wanted to see if there was interest from other AI writers. The examples on the wiki show using AIMap.GetTilesIndex(deltaX, deltaY) to get nearby tiles. It's cool that it works at all, but it does lead to some unexpected results sometimes.
Maybe this function is a good candidate for Fanioz's new library.
Dustin wrote:Sure, I can think of a lot of ways to prevent this problem. One of those ways is to go in the game code and overload the + operator for whatever type AIMap.GetTileIndex is internally.
A TileIndex is just an integer.
But before I ask for game code to be changed, I wanted to see if there was interest from other AI writers. The examples on the wiki show using AIMap.GetTilesIndex(deltaX, deltaY) to get nearby tiles. It's cool that it works at all, but it does lead to some unexpected results sometimes.
Maybe this function is a good candidate for Fanioz's new library.
I think so too, a function like Tile.AddOffset(tile, x, y) that returns INVALID_TILE it wraps in either x or y is useful.