Problems of Scale
While learning the ins/outs of programming we’ve encountered a few different “scaling” problems. We’ve wanted to write programs by just “writing code” but the tools we knew at the time made writing code to solve certain classes of problems very prohibitive! Thankfully we’ve learned a few techniques to address some of these problems:
- Loops allow us to repeat instructions, so we don’t need to rewrite them over and over again
- Functions allow us to invoke code without rewriting it, so we can use that code in a modular way
So we’ve solved some “problems of scale” as they relate to instructions… but what about the data of our programs, namely variables?
Say you and your friends are making a Pokémon fangame, and you’re working on a special challenge area. The player shouldn’t be able to enter the challenge area unless all of their Pokémon are above level 50. Since you’re in charge of this design, you also need to program some game logic to go with it! How might you write this code?
Here’s one example:
int p1Level = 33;
int p2Level = 40;
int p3Level = 18;
int p4Level = 16;
int p5Level = 87;
int p6Level = 52;
//Somewhere later in our code...
bool canEnterChallenge = (p1Level > 50 && p2Level > 50 && p3Level > 50 && p4Level > 50 && p5Level > 50 && p6Level > 50);Does this work in practice? Sure it does. Is it also annoying as hell? Absolutely.
Another annoying example, what if we wanted to heal all of the player’s Pokémon when they enter the challenge area?
//These intergers were declared
//somewhere else previously
p1HP = p1HPMax;
p2HP = p2HPMax;
p3HP = p3HPMax;
p4HP = p4HPMax;
p5HP = p5HPMax;
p6HP = p6HPMax;Also annoying, and kinda error-prone. If we mess up a number somewhere we’re doomed!
Another example… what if we wanted an average of all of our party’s Attack power?
//Again, these attack integers were created earlier
int attackSum = p1Attack + p2Attack + p3Attack + p4Attack + p5Attack + p6Attack;
float averageAttack = attackSum / 6.0f;You get the idea, not the most fun thing in the world. What if we had to do this for more than 6 things? What if, for example, each student here in class had 1 Pokémon, and we wanted to calculate the average attack power of the class Pokémon. That’d be like… almost 60 numbers to add together! That’s a lot!
Modern software, including games, deals with HUGE amounts of data. How do programmers write code to scale with having tons of data? For example, what if you worked as a software engineer for Netflix, and you wanted to write code to calculate the average run-time of ALL FILMS ON NETFLIX? How would you even begin to do that?
Turns out it’s actually pretty straightforward… if you know how to leverage arrays :)
Arrays
Arrays are a feature in most programming languages. They’re basically just groups or lists of variables. Below is some simple array syntax:
Create a new array
//Create a new integer array with 6 elements
int[] partyLevels = new int[6];What the heck is that thing? What does it do!?! It’s our way of creating space in our program’s memory for a group of 6 integers, which we refer to by a single name, partyLevels.
Length of an array
If we need to know the length of an array for some reason, we can do the following:
//We can get the length/size of an array
//using .Length, like below:
int whatever = partyLevels.Length;Access the first element of an array
To access one of the integers in our array, we would do the following:
//Create a new integer array with 6 elements
int[] partyLevels = new int[6];
//Access the first array element
partyLevels[0] = 33;Holy square-brackets Batman! What’s going on? Well since we now have a group of 6 integers that we refer to by a single name, we need a way to access the individual integers (we call them elements) in this group. We do so by using the name of the array, followed by square brackets, and a number (we call it an index) to specify which element we’re referring to.
Filling out an array
Cool, so… what do we do with it? How is it used? For starters, this could be used to represent the levels of the 6 Pokémon in our party. Instead of using individual variables for each and every Pokémon, we’d use our array instead!
//Create a new integer array with 6 elements
int[] partyLevels = new int[6];
//assign values to each array element
partyLevels[0] = 33;
partyLevels[1] = 40;
partyLevels[2] = 18;
partyLevels[3] = 16;
partyLevels[4] = 87;
partyLevels[5] = 52;OH NO IT’S TOO MUCH TOO FAST, WHAT ARE YOU DOING!?! It helps to think about this visually:

The old way of making a bunch of variables to store our Pokémon levels could be thought of like this, where our variables aren’t connected by name, and they’re just hanging out in memory, wherever:

So to state it again: in the code above, we’re creating a new array (group) of 6 integers. This is similar to making 6 individual integer variables. But now, instead, we have this mechanism of making 6 integers at once, and then referring to them with a single name and number. Neat!
Array Indices/Elements
If we wanted to access the FIRST element in an array of integers (like above), we’d use index ZERO (0):
//Arrays START with index ZERO, 0
partyLevels[0] = 33;If we wanted to access the SECOND element in an array of integers (like above), we’d use index ONE (1):
//Second element of the array, index 1
partyLevels[1] = 40;Neat! We’re accessing this group of integers and storing integer values in individual elements. Bangin’.
And keep in mind, you can also use the value stored in an array element JUST like you’d use the value of a variable for something! Observe:
//Create a new array, assign values to each element
int[3] myNumbers = new int[3];
myNumbers[0] = 105;
myNumbers[1] = -12;
myNumbers[2] = 48;
//Some other integers
int x = 2;
int y = 3;
int z = x + y;
//Mix and match!
int a = myNumbers[0];
int b = x + myNumbers[1] - myNumbers[2];
z = y * myNumbers[2];
int sum = myNumbers[0] + myNumbers[1] + myNumbers[2];
myNumbers[1] = myNumbers[0] + z;You can more or less treat each array element just like a normal integer! That’s pretty sweet!
You can also do the following:
int x = 0;
myNumbers[x] = 75;Since the expression inside the square brackets needs to be an integer, we can just substitute ANY integer value! So variable values being used as array indices are totally a valid thing.
Why use arrays though?
OK, I’ll say what you’re thinking… “This just looks like the code we had before, but with extra steps! It’s just confusing!” And you’re not wrong. But the interesting thing about arrays is that they solve our scaling problem. Let’s revisit our Pokémon challenge area example:
int p1Level = 33;
int p2Level = 40;
int p3Level = 18;
int p4Level = 16;
int p5Level = 87;
int p6Level = 52;
//Somewhere later in our code...
bool canEnterChallenge = (p1Level > 50 && p2Level > 50 && p3Level > 50 && p4Level > 50 && p5Level > 50 && p6Level > 50);How can we change this to make it a bit easier?
//Create a new integer array with 6 elements
int[] partyLevels = new int[6];
//assign values to each array element
partyLevels[0] = 33;
partyLevels[1] = 40;
partyLevels[2] = 18;
partyLevels[3] = 16;
partyLevels[4] = 87;
partyLevels[5] = 52;
bool canEnterChallenge = ???;OK neat, but how do we do the last part? Turns out that arrays pair REALLLLLLLLY well with something we’ve already learned about… take a guess what that is?
//Create a new integer array with 6 elements
int[] partyLevels = new int[6];
//assign values to each array element
partyLevels[0] = 33;
partyLevels[1] = 40;
partyLevels[2] = 18;
partyLevels[3] = 16;
partyLevels[4] = 87;
partyLevels[5] = 52;
bool canEnterChallenge = true;
for(int i = 0; i < 6; ++i)
{
//Access each party level using index 'i'
bool levelTooLow = partyLevels[i] <= 50;
if(levelTooLow)
{
canEnterChallenge = false;
break;
}
}Loooooooooooooooooooops! If loops are peanut butter, arrays are the strawberry jam. They fit together super well! In fact, that’s part of why we usually write loops that start at 0… so it’s easier to plug arrays into the mix!