Data++
[Agent practical 2 of 9]
Just as we did for the number of agents, let's extract the hardwired size of the data array. Go into your Environment class, and set it up like this:
int width = 300;
int height = 200;
double[][] data = new double[height][width];
This has a big advantage in terms of clarity. Now, if we casually refer to the "width" of our environment, we know we're always refering to the second dimension, not the first. This will help us be consistent. Secondly, if we want to get hold of the width of the Environment data from within our Model class, we can do this:
world.width
which is a lot easier than trying to work out if we need:
world.data.length
or:
world.data[0].length
The only downside is we might be tempted to try and do this:
world.width = 350;
hoping this increases the size of our array. Unfortunately it won't -- code inside of the class block, but outside of other blocks, only runs once, when an object is made from the class. As, in this case, the size of the array is set and the size variable used to do that is then discarded by the array, changing the size variable won't change the array. We'll see a way of stopping coders from trying to set this variable later in the course, but for now we'll just have to remember not to try and set it equal to anything.
Ultimately we're going to read data into our data array from a file. For the moment, however, let's fill it with some default values.
In your Model class, at the end of the last practical you probably had something like this:
Environment world = new Environment();
world.data[0][0] = 1.0;
world.data[0][1] = 2.0;
world.data[0][2] = 3.0;
world.data[1][0] = 4.0;
world.data[1][1] = 5.0;
world.data[1][2] = 6.0;
System.out.println("Number at [0][0] = " + world.data[0][0]);
System.out.println("Number at [1][1] = " + world.data[1][1]);
System.out.println("Number at [1][2] = " + world.data[1][2]);
Delete all of this *except* the first line making the Environment object.
Then, as we did with the agents array, set up a looping structure to set up the
world.data
array with values. You'll need to
set up a nested loop that implements the following algorithm. The
algorithm is written in a mix of English and code, what we call "pseudocode". You'll
need to convert it into proper working code.
// Loop through rows with index i.
// Loop through spaces on row with index j.
// world.data[i][j] = 255.0
// } End spaces loop.
// } End rows loop.
Note that because we use "i
" for the row counter (that is, it is
counting from zero to just less than world.height
) we're careful to make sure that it is
the first dimension in data[i][j]
. This is the kind of thing that it is very
easy to mess up.
Once you think you've written this, compile it and check it runs.
Doomed: Note that one thing we've done to
help is to set the width and height to different sizes. This means if we accidentally switch our
i
and j
, thus:
data[j][i] = 255.0;
we'll get a debugging message as the program runs, because it will run off the end of one of
the dimensions, thinking it is larger. Try this, then try setting both sizes to 300 to see
just how silently this problem can sit inside a program that uses square arrays. Remember to
change the size of the array and the data[j][i] = 255.0;
back to how it should be
after you've experimented.
Given we've added a fair amount of code here, it would be nice to print out the whole of the
array afterwards to check it. Ideally we'd print each row value on the same line, dropping a
line between each row. If you'd like to write a piece of code to do this, you can find
an example on the Key Ideas page for the last lecture; look for the bit that talks about the
difference between print
and println
.
Once you're happy your code works, move on to making your model run.