Page 1 of 1

How do you create a 2D Array?

Posted: 07 Feb 2011 14:14
by MinchinWeb
I've poured over the forum, the OpenTTD Wiki, and Squirrel documentation and can't find anything that works and the C++ method doesn't seem to work either. So how do you create a 2D array?? I expect this to work, but it doesn't...

Code: Select all

WmAtlas [][] = array[WmTownList.Count()][WmTownList.Count()+1];
Any suggestions?


What I'm attempting to do is create a 'table' with the distances between select towns. Here's the (non-working) code. Perhaps I just need another approach...

Code: Select all

	WmTownList = AITownList();
	WmTownList.Valuate(AITown.GetPopulation);
	local PopLimit = WmDOT.GetSetting("MinTownSize");
	WmTownList.KeepAboveValue(PopLimit);				// cuts under the pop limit
	WmTownList.Sort(AIAbstractList.SORT_BY_VALUE, false);
	AILog.Info("     Ignoring towns with population under " + PopLimit + ". " + WmTownList.Count() + " towns left.");

	// Generate Distance Matrix
	local iTown = WmTownList.Begin();
	local WmTownList2 = WmTownList;
	local jTown = WmTownList2.Begin();
//	WmAtlas [][] = array[WmTownList.Count()][WmTownList.Count()+1];
//	int WmAtlas [][];		
	for(local i=0; i < WmTownList.Count(); i++) {
		WmAtlas[i][0] = iTown;		// THIS IS WHERE IT BREAKS...
		jTown = WmTownList2.Begin();
		for (local j = 0; j < WmTownList.Count(); j++) {
			WmAtlas[i][j+1]=AIMap.DistanceManhattan(AITown.GetLocation(iTown,jTown));
			jTown = WmTownList2.Next();
		}
		iTown = WmTownList.Next();
	}
Many thanks in advance.

Re: How do you create a 2D Array?

Posted: 07 Feb 2011 16:39
by Yexo
Please note that townids are not always consecutive. If there are 3 towns it can be that they have ids 2, 3 and 8.

A multidimensional array can be created like this:

Code: Select all

local my_array = [];
for (i = 0; i < 10; i++) {
  local tmp_array = [];
  for (j = 0; j < 10; j++) {
    tmp_array.append(get_distance(i, j));
  }
  my_array.append(tmp_array);
}

Re: How do you create a 2D Array?

Posted: 07 Feb 2011 17:51
by Lord Aro
There must be an easier way than that, as NoCAB uses multi-dimensional arrays (world.nut), and it doesn't do it like that...

Re: How do you create a 2D Array?

Posted: 07 Feb 2011 19:16
by MinchinWeb
Thanks! Unfortunately that brings up the next question - how do you find out what size your array is?

And is there somewhere it explains what operators are available for arrays?

Re: How do you create a 2D Array?

Posted: 07 Feb 2011 19:53
by Zuu

Re: How do you create a 2D Array?

Posted: 08 Feb 2011 22:08
by krinn
MinchinWeb wrote:how do you find out what size your array is?
yourarray.len()

and if i may:

Code: Select all

local wmTownList2=AIList();
wmTownList2.AddList(wmTownList);
wmTownList2.Valuate(AIMap.DistanceManhattan,AITown.GetLocation(iTown));
if i understood well what you were trying to do (one list with town+pop and one list town+distance from the biggest town)

for your array problem you can solve it with

Code: Select all

local myarray=[];
foreach (town, population in wmTownList) {
foreach (town2, distance in wmTownList2) {
if (town == town2) {
myarray.push(town);
myarray.push(population);
myarray.push(distance);
}}}
lowindex to access them in the array will be myarray.len() * index
highindex will be lowindex+2;

Re: How do you create a 2D Array?

Posted: 09 Feb 2011 16:16
by MinchinWeb
Thanks for all your help. I ended up using the method Yexo suggested (generating one 'row' at a time and then stuffing it into the first array). My working code looks like this:

Code: Select all

function WmDOT::GenerateAtlas(WmTownArray)
{
	// Generate Distance Matrix
	local iTown;
	local WmAtlas=[];
	WmAtlas.resize(WmTownArray.len());
	
	for(local i=0; i < WmTownArray.len(); i++) {
		iTown = WmTownArray[i];
		local TempArray = [];		// Generate the Array one 'line' at a time
		TempArray.resize(WmTownArray.len()+1);
		TempArray[0]=iTown;
		local jTown = AITown();
		for (local j = 0; j < WmTownArray.len(); j++) {
			jTown = WmTownArray[j];
			TempArray[j+1] = AIMap.DistanceManhattan(AITown.GetLocation(iTown),AITown.GetLocation(jTown));
		}
		WmAtlas[i]=TempArray;
	}

	return WmAtlas;
}
Which generates a little matrix like the following:
  • 6 0 329 288 153
    17 329 0 45 176
    14 288 45 0 135
    15 153 176 135 0
Where the first column is TownID's and the rest is the distance between the pairs of towns.

Addressing seems to work as I expect it. eg WmAtlas[0][3] gives 288.

Re: How do you create a 2D Array?

Posted: 09 Feb 2011 19:00
by Zuu
If you want to save some computation time you can skip generating half of the matrix as the distance from town A to B is equal to the distance from town B to A. However, when accessing the matrix you will need to make sure that A index is < B or the reverse depending on which part of the matrix you keep. So for tiny matrices as the example matrix it is probably just a waste of code complexity to only generate half matrices but for larger ones the memory + computation time saved can be significant. All depending on the problem size.