Add a command to Save to a new gme file

From TRCCompSci - AQA Computer Science
Jump to: navigation, search

The key to completing this task is to use the same process as the LoadGame method but obviously instead of reading we need to write. The order of each item of data must be exactly the same or the data would be unreadable.

The method

Start by copying the entire LoadGame method, and rename it SaveGame. You need to keep all of the parameters:

        private static bool SaveGame(string filename, List<Character> characters, List<Item> items, List<Place> places)

We need to convert the following line:

            int noOfCharacters, noOfPlaces, NoOfItems;

This original line of the LoadGame method is to store the number of characters, places, and items stored in the gme file. To save we need to give each of these a value by counting the number of elements in each list:

            int noOfCharacters = characters.Count;
            int noOfPlaces = places.Count;
            int NoOfItems = items.Count;

At the moment this method uses BinaryReader, and we need to change this to BinaryWriter, so change:

using (BinaryReader Reader = new BinaryReader(File.Open(filename, FileMode.Open)))

to this:

using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))

Now after this line is where characters are loaded:

                    noOfCharacters = Reader.ReadInt32();
                    for (int Count = 0; Count < noOfCharacters; Count++)
                    {
                        Character tempCharacter = new Character();
                        tempCharacter.ID = Reader.ReadInt32();
                        tempCharacter.Name = Reader.ReadString();
                        tempCharacter.Description = Reader.ReadString();
                        tempCharacter.CurrentLocation = Reader.ReadInt32();
                        characters.Add(tempCharacter);
                    }

We want to change this, and to minimise the number of changes I recommend to use a foreach loop. I have also used the same name "tempCharacter" to minimise the changes. You then need to wrap each "tempCharacter." with a "writer.Write();":

                    writer.Write(noOfCharacters);
                    foreach(Character tempCharacter in characters)
                    { 
                        writer.Write(tempCharacter.ID);
                        writer.Write(tempCharacter.Name);
                        writer.Write(tempCharacter.Description);
                        writer.Write(tempCharacter.CurrentLocation);
                    }

You can now do the same for Places and items:

                    writer.Write(noOfPlaces);
                    foreach(Place tempPlace in places)
                    {
                        writer.Write(tempPlace.id);
                        writer.Write(tempPlace.Description);
                        writer.Write(tempPlace.North);
                        writer.Write(tempPlace.East);
                        writer.Write(tempPlace.South);
                        writer.Write(tempPlace.West);
                        writer.Write(tempPlace.Up);
                        writer.Write(tempPlace.Down);
                    }
                    writer.Write(NoOfItems);
                    foreach(Item tempItem in items)
                    {
                        writer.Write(tempItem.ID);
                        writer.Write(tempItem.Description);
                        writer.Write(tempItem.Status);
                        writer.Write(tempItem.Location);
                        writer.Write(tempItem.Name);
                        writer.Write(tempItem.Commands);
                        writer.Write(tempItem.Results);
                    }

Completed Method

Your method should look like this:

        private static bool SaveGame(string filename, List<Character> characters, List<Item> items, List<Place> places)
        {
            int noOfCharacters = characters.Count;
            int noOfPlaces = places.Count;
            int NoOfItems = items.Count;

            try
            {
                using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))
                {
                    writer.Write(noOfCharacters);
                    foreach(Character tempCharacter in characters)
                    { 
                        writer.Write(tempCharacter.ID);
                        writer.Write(tempCharacter.Name);
                        writer.Write(tempCharacter.Description);
                        writer.Write(tempCharacter.CurrentLocation);
                    }
                    writer.Write(noOfPlaces);
                    foreach(Place tempPlace in places)
                    {
                        writer.Write(tempPlace.id);
                        writer.Write(tempPlace.Description);
                        writer.Write(tempPlace.North);
                        writer.Write(tempPlace.East);
                        writer.Write(tempPlace.South);
                        writer.Write(tempPlace.West);
                        writer.Write(tempPlace.Up);
                        writer.Write(tempPlace.Down);
                    }
                    writer.Write(NoOfItems);
                    foreach(Item tempItem in items)
                    {
                        writer.Write(tempItem.ID);
                        writer.Write(tempItem.Description);
                        writer.Write(tempItem.Status);
                        writer.Write(tempItem.Location);
                        writer.Write(tempItem.Name);
                        writer.Write(tempItem.Commands);
                        writer.Write(tempItem.Results);
                    }
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

Using it

To use this method, create a new case in the PlayGame switch case statement:

                    case "save":
                        Console.Write("Enter filename> ");
                        string filename = Console.ReadLine() + ".gme";
                        if (SaveGame(filename, characters, items, places))
                            Console.WriteLine("Save done");
                        else
                            Console.WriteLine("Save failed");
                        break;

Now typing save will ask you for a filename and then save the game data. If it is completed it will give you a prompt to say it is done and if it fails a message will also be created.