Skip to content

C# Adventure 11: Lists and Instances

At the end our game we'll add a summary of what the player has accomplished, as well as a list of the items they've found. We will also congratulate them on achieving any specific goals that we've asked them to meet.

Items stored in a list
Items stored in a list written to the console window

In this section we'll work with two more programming concepts; lists and object instances. The inventory list we add to our Game class will track items that have been found by the player throughout the game. We'll make instances of our Item class for random items that the user can also find, and look at how using an object instance is different from accessing a static class.

Lists

Lists in C# are similar to arrays, but you can add to them dynamically. We have to specify our array's size when we declare it, or initialize it with a set amount of values. Using a list gives us more freedom to add new items dynamically.

We'll use a list to track items the player finds in the game, and your project will have examples of using both structures (arrays and lists).

Add Directive

At the top of your file add another using directive. This will give us access to generic collections, including Lists.

using System.Collections.Generic;

Creating a List

Add a list to your Game class. Since we'll be using the list to keep track of all of the items the player has found, we can call it Inventory.

public static class Game
{
    static int Scenarios = 3;
    static string CharacterName;
    static List<string> Inventory = new List<string>();
    [.....]

When the player "finds" something in the game, we'll add it to this list. We'll first add items that have been written into your content and then we'll add some random items that the player can find. Later we'll use a loop to write out all the items in a summary.

Inside of the Choice method is our switch statement with nested if/else statements. In the example text the player finds a flashlight if they choose A at the first decision point. To add a flashlight to the list this statement can be used:

Inventory.Add("flashlight");

Inside the parentheses we pass the string we want to add. In this case it is "flashlight".

Create statements to add items to the inventory list. Where you place the code in your switch statement will depend on your unique story. You can look at an example below that shows several items being added to the Inventory list based on the example text.

Example Code

An example of the Choice method with items being added to the Inventory list.

static void Choice()
{
    for (int scenario = 1; scenario <= Scenarios; scenario++)
    {
	string input = "";

	switch (scenario)
	{
	    case 1:
		//Part One

		//same pattern for each of the sections. 1) write the first part of the section
		Console.WriteLine(PartOne[0]);

		//2)read in player's choice (a or b)
		Console.ForegroundColor = ConsoleColor.Green;
		
		Console.Write("Enter your choice: ");
		input = Console.ReadLine();
		input = input.ToLower();
		Console.ResetColor();

		//3) if a write the next part of the array, otherwise skip next and print 3rd
		if (input == "a")
		{
		    Console.WriteLine(PartOne[1]);
		    Inventory.Add("flashlight");
		}
		else
		{
		    Console.WriteLine(PartOne[2]);
		    Inventory.Add("umbrella");
		}

		//4) write next part of the section
		Console.WriteLine(PartOne[3]);

		//5) again if a write next, otherwise skip ahead
		if (input == "a")
		{
		    Console.WriteLine(PartOne[4]);
		    Inventory.Add("snack");

		}
		else
		{
		    Console.WriteLine(PartOne[5]);
		}

		//6) print last piece of the section
		Console.WriteLine(PartOne[6]);

		break;

	    case 2:
		//Part Two
		
		Console.WriteLine(PartTwo[0]);
		Console.ForegroundColor = ConsoleColor.Green;
		Console.Write("Enter your choice: ");
		input = Console.ReadLine();
		input = input.ToLower();
		Console.ResetColor();
		if (input == "a")
		{
		    Console.WriteLine(PartTwo[1]);
		    Inventory.Add("rope");
		}
		else
		{
		    Console.WriteLine(PartTwo[2]);
		    Inventory.Add("chisel");
		}
		Console.WriteLine(PartTwo[3]);
		if (input == "a")
		{
		    Console.WriteLine(PartTwo[4]);
		    Inventory.Add("spider");
		}
		else
		{
		    Console.WriteLine(PartTwo[5]);
		    Inventory.Add("rune");
		}
		Console.WriteLine(PartTwo[6]);

		break;

	    case 3:
		//Part Three

		Console.WriteLine(PartThree[0]);
		Console.ForegroundColor = ConsoleColor.Green;
		Console.Write("Enter your choice: ");
		input = Console.ReadLine();
		input = input.ToLower();
		Console.ResetColor();
		if (input == "a")
		{
		    Console.WriteLine(PartThree[1]);
		    Inventory.Add("key");
		}
		else
		{
		    Console.WriteLine(PartThree[2]);
		}
		Console.WriteLine(PartThree[3]);
		if (input == "a")
		{
		    Console.WriteLine(PartThree[4]);
		    Inventory.Add("diamond");
		}
		else
		{
		    Console.WriteLine(PartThree[5]);
		    Inventory.Add("rare book");
		}
		Console.WriteLine(PartThree[6]);
		break;

	    default:
		//default if section number does not match one of the above
		break;
	}

	//let player advance when ready, then clear the screen
	Console.WriteLine("Press enter to continue...");
	Console.ReadKey();
	Console.Clear();
    }
}

List Summary

To write out the items the player found at the end of the game, we can use a foreach statement. You'll probably also want to provide context for the player by writing to the console something like "Here's what you found:".

Add a foreach to EndGame with a WriteLine inside.

public static void EndGame()
{
    //end of game text
    Console.WriteLine("End of story text here.....");
    Console.WriteLine("Congratulations " + CharacterName + "!");

    Console.WriteLine(CharacterName + " you found some items in your journey:");

    foreach (string item in Inventory)
    {
        Console.WriteLine(item);
    }
}

Player Objectives

You can include an objective for the player, then search the list to see if it was found.

For example, if the player is told their goal is to find a key, in the EndGame() method these lines will congratulate the player if it is found:

if (Inventory.Contains("key"))
{
    Console.ForegroundColor = ConsoleColor.Cyan;
    Console.WriteLine("Congratulations you accomplished the goal! You found the key!");
    Console.ResetColor();
}
Example showing match in list
Example showing match in list

Players who don't find the key could have alternative text shown:

if (Inventory.Contains("key"))
{
    Console.ForegroundColor = ConsoleColor.Cyan;
    Console.WriteLine("Congratulations you accomplished the goal! You found the key!");
    Console.ResetColor();
}
else
{
    Console.WriteLine("You didn't find the key... better luck next time!");
}
Example
Example

If you'd like to have a player objective to find a specific item, add the code to your project.

Object Instances

Our classes so far have been static. But as we discussed earlier, we can also make instances of classes. Each instance of a class can have unique information, but will also have properties and/or operations that identify it as part of a specific class.

So that you will have examples of both static and non-static classes in your project, we'll make instances of our Item class.

Static vs. Non-Static

When and why to use static classes versus non-static is a big topic. With this project you'll have examples of both. Later when you delve more deeply into object-oriented theory, you can learn more about when to use which.

Recommended resources:

Item Class

Before making instances, we'll build out our Item class.

Add two string variables. You'll probably want to have a name, and a description.

Item Class Variables Example

class Item
{
    string Name;
    string Description;
}

Access Modifier: Public

Just like with our Game class, we'll make our Item class public. Add the public keyword to your class and variables.

Public Modifier Example

public class Item
{
    public string Name;
    public string Description;
}

Item Class Constructor

All classes in C# have a constructor. If you don't define one, a default one is created by the compiler. Creating your own constructor can allow you to have more control.

A constructor has the same name as the class. For example:

public class Item
{
    //constructor
    public Item()
    {
    }
}

When an instance is made, code in the constructor runs first, meaning you can initialize values or set up criteria for the object in the constructor.

Add a constructor to your Item class (like the example above). We will use it shortly to create random items.

Item Class Instance

We will make random items for our player soon, but first we'll walk through making instances in general. To make an instance of a class such as Item we can use this formula:

class name identifier = new class name

Example:

Item randomItem1 = new Item();

Item randomItem1 = new Item();

Because the Item class is public, the variable values are easily changed. Use the instance name (instead of the class name as we've done with static classes):

randomItem1.Name = "Rock";
randomItem1.Description = "Ordinary rock, nothing special.";

To add the item's name to our inventory list, use Inventory.Add as before. Pass in the instance identifier and property.

Inventory.Add(randomItem1.Name);

Now let's make our random items.

Random Items

Here are the changes we'll be making to our code:

  1. Create default values for our Name and Description properties.
  2. Create two new arrays - one to hold item names, the other to hold item descriptions. Initialize with values in each.
  3. Make an instance of the Random class, and use it to get a random number.
  4. Use the random number to get a random item from the array.
  5. Write out the item name and description to the console window.

Default Values

This should be an easy task. Add default values to the Name and Description strings in your Item class.

New Arrays

Make two new arrays inside Item to hold names and descriptions. Use your own content.

Example of default values and two new arrays:

public class Item
{
    //default is a stone
    public string Name = "Small stone";
    public string Description = "Unimpressive object.";

    string[] Items = { "shoe", "can", "pair of chopsticks" };
    string[] Descriptions = { "Size 10 sneaker", "Empty root beer can", "Pink plastic chopsticks" }; 
[...]
}

Random

The last three items on our list we'll add inside of our constructor. The first is to instantiate an object of the Random class.

Random is the class name. In the example below, the identifier is "randomNumber".

Random randomNumber = new Random();

Next we'll make an integer.

int number;

We don't have an unlimited amount of options in the arrays we've made. In the example, there are only three items. We need a random number within that range.

To specify the range we'll use the Next method. There are a few ways you can use it since it is overloaded (it has more than one definition).

We'll use the form that takes one argument, a maximum value. It will return an integer that is greater than or equal to 0, and less than the max value.

What are the possible values that we might get after running this statement?

number = randomNumber.Next(3);

Check Your Answer

Did you guess 0, 1, and 2? If you did, congratulations!

Since we know how many elements are in our array, we could "hard code" the range with the number 3 as in the above example. But we could also use the size of the array.

Do you remember how to find the number of elements in an array? Rewrite the line of code above using the size of the array instead of a specific number like 3.

Check Your Answer

number = randomNumber.Next(Items.Length);

Add the three statements to your constructor to create a random number. Check the example code below after you've written your version.

Example Code

//constructor
public Item()
{
    // Instantiate random 
    Random randomNumber = new Random();
    int number;

    //Next(Int32) returns a non-negative random number less than the maximum
    number = randomNumber.Next(Items.Length);
}

We have two more tasks on our list:

  1. Create default values for our Name and Description properties.
  2. Create two new arrays - one to hold item names, the other to hold item descriptions. Initialize with values in each.
  3. Make an instance of the Random class, and use it to get a random number.
  4. Use the random number to get a random item from the array.
  5. Write out the item name and description to the console window.

Random Array Item

To access a random item from the array, we use the array identifier and inside of square brackets is the variable named "number".

Items[number]

To set the item's Name value add this code to your constructor:

Name = Items[number];

Add a similar line to set the description value:

Description = Descriptions[number];

Now your instance has random values (for name and definition).

Display Random Name and Description

The last task on the list is to write the information out to the console screen. Add a WriteLine so the player can see the name and description.

Console.Write("You found a " + Name + " (" + Description + ").");

Example:

Example random item
Example random item (highlighted)

Test your code. If you hit a snag, there is example code below you can compare to yours.

Example Constructor

//constructor
public Item()
{
    // Instantiate random number generator 
    Random randomNumber = new Random();
    int number;

    //Next(Int32) returns a nonnegative random number less than the specified maximum
    number = randomNumber.Next(Items.Length);

    Name = Items[number];
    Description = Descriptions[number];
    Console.Write("\nYou found a " + Name + " (" + Description + ").\n");
}

You've added a list, an instance, and random items!

To Do: Practice

Assignments

  1. Learn about converting values from one data type to another as you build a guessing game. Complete the walk-through: Numeric Guessing Game: C# Console Application.
  2. Look at an example of using arrays and the Random class to create characters with randomly assigned properties for the player to encounter. Review example code: Random Properties.

Creative Commons License

Consider using Creative Commons to create a license for your game.

If you choose a Creative Commons license for your game, update your comments to include it.

/*
 * [Your Title]
 * by Your Name, Date
 *  
 * This work is a derivative of 
 * "C# Adventure Game" by http://programmingisfun.com, used under CC BY.
 * https://creativecommons.org/licenses/by/4.0/
 * "[Your Game Title]" is licensed under
 * [license] by [Your name here].
 */

Next Step

In the next section we will create an alternative framework, and learn some new concepts!