Should AIMap.GetIndex + tile work this way?

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
User avatar
Dustin
Transport Coordinator
Transport Coordinator
Posts: 272
Joined: 07 Dec 2005 19:22

Should AIMap.GetIndex + tile work this way?

Post by Dustin »

Code: Select all

  nextTile = AIMap.GetTileIndex(1,1);
  while(nextTile != end)
    {
        nextTile = AIMap.GetTileIndex(1, 0) + nextTile;
        AISign.BuildSign(nextTile, "Visited");
    }
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.
deepblue2k8
Engineer
Engineer
Posts: 44
Joined: 06 Sep 2008 12:41
Location: Hamburg, Germany

Re: Should AIMap.GetIndex + tile work this way?

Post by deepblue2k8 »

Code: Select all

nextTile = AIMap.GetTileIndex(1, 0) + nextTile;
Hi,

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.
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: Should AIMap.GetIndex + tile work this way?

Post by Zuu »

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.

Code: Select all

function Helper::GetTileRelative(relative_to_tile, delta_x, delta_y)
{
	local tile_x = AIMap.GetTileX(relative_to_tile);
	local tile_y = AIMap.GetTileY(relative_to_tile);

	local new_x = tile_x + delta_x;
	local new_y = tile_y + delta_y;

	return AIMap.GetTileIndex(new_x, new_y);
}
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
User avatar
Zutty
Director
Director
Posts: 565
Joined: 22 Jan 2008 16:33

Re: Should AIMap.GetIndex + tile work this way?

Post by Zutty »

Think of a tile index in terms of the following

Code: Select all

i = x + yY
x < Y
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.

Code: Select all

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
  ...
}
PathZilla - A networking AI - Now with tram support.
User avatar
Dustin
Transport Coordinator
Transport Coordinator
Posts: 272
Joined: 07 Dec 2005 19:22

Re: Should AIMap.GetIndex + tile work this way?

Post by Dustin »

Zutty wrote:Think of a tile index in terms of the following

Code: Select all

i = x + yY
x < Y
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.

Code: Select all

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.
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Should AIMap.GetIndex + tile work this way?

Post by Yexo »

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.
User avatar
fanioz
Transport Coordinator
Transport Coordinator
Posts: 320
Joined: 19 Dec 2008 05:03
Location: Indonesia
Contact:

Re: Should AIMap.GetIndex + tile work this way?

Post by fanioz »

Nice idea. :D
Correct me If I am wrong - PM me if my English was bad :D

**[OpenTTD AI]** Image
***[NewGRF] *** Image
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 7 guests