XNA Game-Themed CS1 Examples (XGC1) Release 2.0 (XNA V3.1) 2/8/2010
Topic: Topic.6.Arrays
Example: Ex_1.ArrayOfIntegers

# Arrays: Basic Array Of Integers

References:

• Pre-requisite: it is assumed that you have read through the prior tutorials, and are familiar with the concepts covered in those tutorials.

Goals:

• In this tutorial, we will:
• Examine a simple array, which we will use to hold a collection of numbers.  The real goal here is to introduce you to the basic concepts of arrays

1. Obtain the example code

Download and unzip the zip file and you will see an ExampleProgram folder. Open the ExampleProgram folder, the EXE folder contains the compiled program and you can double click on the .sln file to work with the source code.

When the game starts, you'll see a screen that looks similar to this:

As you can see, this program draws five soccer balls across the screen.  The program also draws a basketball on the screen, and allows you to move the basketball using the right thumbstick.

What's new and interesting with this program is that there are five separate numbers across the bottom of the screen - 10, 20, 30, 40, and 50.  If you push the A button, you increment the first number, up to 11.  Push the A button again, and you're looking at 12, and so on.  Similarly, the B button will increment the second number (to 21, then 22, etc), the X button increments the third number, and Y increments the fourth number.  The fifth, and last, number cannot be incremented by the user.

What's going on here is that these integers are being stored in an array, which is the major topic for this chapter.  In C#, an array consists of a bunch of elements (a.k.a. locations, or slots, or spaces, etc);  all the individual elements are of the same type (in this case, all integers), but each element stores a separate, unique, individual value.  All the elements in a single array are stored together right next to each other in memory, without any breaks in memory (i.e., they're stored contiguously in memory).  The entire array is accessed using a single variable name.  In order to access individuals elements in the array, the first one  is numbered with zero - you can think of this as an "address", or part of it's "name".  The number zero is commonly referred to as the element's subscript, or the index of the element.  The second element is given the subscript (index) 1, the next element is 2, etc.  Here's a picture that represents the array that we're using in the above program, when the game starts:

The numbers in red, above the array, are labeled "Subscripts", while the numbers in black, inside the squares, are labeled "Elements".  Each element holds a single integer (since it's an array of integers).  You'll notice that the first element has the value "10", the second element has the value "20", etc. Before we look at the code, let's examine some syntactical details of arrays, first:

If the array (as a whole) is referred to use the variable named m_MyArray, then we can talk about the first element in our program using the "name" m_MyArray[0]Notice that the way we refer to an element is by using the name for the whole array, then an open bracket after the name (  [  ), then the subscript/index number for the element that we want to access, and then the close bracket (  ]  ).  Because each element holds a separate value, you can think of each element of the array as being a separate variable.  The only difference between a normal variable and an array element is that the array elements all share the same name (but each element has a unique subscript!)

Let's say that we wanted to store the number 10 into the first array element of the array named m_MyArray.  Just for comparison's sake, let's also say that we want to store the value 12 into the variable named myInteger.   (Let's also assume that both have been declared, created, and initialized, as appropriate).  In order to assign these values, our code would look like:

m_MyArray[0] = 10;

myInteger = 12;

Notice how similar the lines are - in effect, "m_MyArray[0]" is the name of the first element in the array, so we can use that exactly like we'd use the name of a normal, integer variable, like myInteger.

This means that any expression you could use in an assignment statement for a normal variable, you can use when assigning to an array element:

int x = 10;

myInteger = 10 + 2 * x - 7;    // assigns 23 to myInteger

m_MyArray[0] = 10 + 2 * x - 7; // assigns 23 to m_MyArray[0]

You can also write any expression that will evaluate to an integer number inside the brackets, as well.  This expression will first be evaluated, then the assignment will be done:

m_MyArray[2 - 1] = 10; // assigns 10 to slot number 1 ( 2 - 1 = 1 )

You can also get the value stored in an array element, and use it like you would any other integer:

myInteger = 3;

m_MyArray[0] = 3;

int x;

int y;

x = myInteger + 2; // assigns 5 to x

y = m_MyArray[0]+ 2; // assigns 5 to y

You can combine the 'getting data out of' syntax, and 'putting data into' syntax, on the same line, just like you would for a normal integer.  For example, one way to increment a normal integer, and an integer array element:

myInteger = myInteger + 1;

m_MyArray[0] = m_MyArray[0] + 1;

Another way to do the exact same thing, using the increment (++) operator:

myInteger++;

m_MyArray[0]++;

In addition to possible new syntax errors, using an array introduces the possibility of a new type of logical error: attempting to access an element that doesn't exist.  If you consider the 5 element array pictured above, you can clearly see that m_MyArray[0] has the value 10.  You can also try to access the element -1, like so: m_MyArray[-1].  However, there is no element with the number -1, so you'll see an error message that says something about the index being out of range.  Likewise, if you try to access m_MyArray[10], despite the fact that the array has only 5 elements, you'll get the same error message.

One very common error is to access m_MyArray[5], when has only 5 elements.  This is an error because the first element is numbered 0, the second 1, and so on, until the fifth element, which is numbered 4, not 5!  Take a close look at the above picture, and you'll see this in detail.

Having looked at some of the syntax issues around arrays, let's examine the code for this tutorial!

2. Examining The Program:

Let's examine the C# source code that produces the behavior we see on-screen

First, note that the program draws 5 soccer balls, using a loop, like you've seen in previous tutorials. We will ignore this for now, but we'll be leaving it in this program, since we will soon examine how loops & arrays naturally work together.

• Declaring the instance variables and named constants XNACS1Circle m_BasketBall; // this is under user control    #endregion     // Notice the way array is declared in C#     private int[] m_MyArray;
• This program will declare an array as an instance variable, so that we can access the data stored in it anywhere in the program, throughout the life of the program:

// Notice the way array is declared in C#

private int[] m_MyArray;

• We're still using the word private, as we do for all our instance variables.
• Next, we list the type of the instance variable, just like normal.  However, instead of saying just int, we instead write int[].  The square brackets are what tells C# that we want an array, not just a single integer.
• Finally, we name the variable whatever we'd like (in this case, we chose m_MyArray), followed by the semi-colon.
• Declaring an array is very similar to declaring an object, such as a XNACS1Circle - you'll notice that we need to first declare the array here, then create a new array in the InitializeWorld routine:
• InitializeWorld():  protected override void InitializeWorld(){     World.SetWorldCoordinate(new Vector2(0,0), 100.0f);     // Allocate memory for the array     m_MyArray = new int[5];     m_MyArray[0] = 10;     m_MyArray[1] = 20;     m_MyArray[2] = 30;     m_MyArray[3] = 40;     m_MyArray[4] = 50;     From previous example (create and allocate 5 soccers and one basketball }
• Much like we do for objects (such as an XNACS1Circle), we first create the new array, using the new keyword
m_MyArray = new int[5];
• Notice that we need to decide how many elements the array will have, when we create the array.  We need to do this so that C# will know how much memory to allocate in the computer's memory.  In this case, we want to allocate space for 5 integers, so we write the number 5, in square brackets, after the name of the data type (int).
• Once the array has been created, each element has the default value for that data type. Since our array consists for integer, and the default value for an int is zero, each element starts off with the value zero, like so:
• Since we don't want to start with zeroes in every element, we need to initialize the array's elements with numbers:
m_MyArray[0] = 10;

m_MyArray[1] = 20;

m_MyArray[2] = 30;

m_MyArray[3] = 40;

m_MyArray[4] = 50;

• UpdateWorld(): if (GamePad.ButtonAClicked())         m_MyArray[0] = m_MyArray[0] + 1;     if (GamePad.ButtonBClicked())         m_MyArray[1] = m_MyArray[1] + 1;     if (GamePad.ButtonXClicked())         m_MyArray[2] = m_MyArray[2] + 1;     if (GamePad.ButtonYClicked())         m_MyArray[3] = m_MyArray[3] + 1;
• The new code for this tutorial consists of four if statements.  Since they're nearly identical, we will explain just the first one in detail.
• The if statement starts out by checking if this is the first UpdateWorld since the A button was pushed.

• If the A button hasn't been pushed, or if the player is still pushing down the A button since the last time that the UpdateWorld was called, GamePad.ButtonAClicked() will return false.  Since the UpdateWorld function can be called dozens of times a second, and since humans can't normally tap the A button quickly enough, using this function will ensure that the if statement evaluates to true only ONCE for each time that the player pushes, then releases, the A button
• The other Button_Clicked functions work the same way, for the B, X, and Y buttons
• If the 'A' button was pushed, then we should increment the first element of the array:
m_MyArray[0] = m_MyArray[0] + 1;
• This pattern was discussed in the first part of this document.

FURTHER EXERCISES::

1. Start from a blank starter project (1000.201, if you need it), and re-do the code from memory as much as possible.  On your first try, do what you can, and keep the above code open so that when you get stuck, you can quickly look up what you forgot (and that after you finish a line, so that you can compare your line to the 'correct' line).  On the next try, do the same thing, but try to use the finished code less.  Repeat this until you can type everything, without refering the tutorial's code.
• Repeat this exercise daily for several days, so that you really get the hang of this.  As you go on, periodically review this by re-doing this exercise.
2. Arrays and data types
For this exercise, you should use the same project that was explained in the above tutorial.
Go through the code, and change the data type of the array elements from being integers, to being floating-point numbers.
3. Different Array Sizes
For this exercise, you should use the same project that was explained in the above tutorial.
1. Working off the code presented in the above tutorial, you should change the size of the array from 5 elements, to 8.  Make sure that you update the message at the bottom of the screen, so that it displays all the elements of the array.
2. Working off the code presented in the above tutorial, you should change the size of the array to be exactly 4 elements, and update the program appropriately.
4. IndexOutOfRangeException
For this exercise, you should use the same project that was explained in the above tutorial.
In the provided tutorial code, in the InitializeWorld method, try changing the following line:
m_MyArray[0] = 10;

So that it attempts to assign the value 10 to element -1, or to element 10, or to the element with the index of 5.  For each of these, note carefully what happens, as this is a very distinctive error message - being able to quickly recognize this, and fix this sort of error, is a valuable skill to have.