Difference between revisions of "Add a command to Save to a new gme file"

From TRCCompSci - AQA Computer Science
Jump to: navigation, search
(The method)
(The method)
 
(2 intermediate revisions by the same user not shown)
Line 6: Line 6:
 
<syntaxhighlight lang=c#>
 
<syntaxhighlight lang=c#>
 
         private static bool SaveGame(string filename, List<Character> characters, List<Item> items, List<Place> places)
 
         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;
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
We need to convert:
+
We need to convert the following line:
 
<syntaxhighlight lang=c#>
 
<syntaxhighlight lang=c#>
 
             int noOfCharacters, noOfPlaces, NoOfItems;
 
             int noOfCharacters, noOfPlaces, NoOfItems;
Line 36: Line 32:
 
using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))
 
using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Now after this line is where characters are loaded:
 +
 +
<syntaxhighlight lang=c#>
 +
                    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);
 +
                    }
 +
</syntaxhighlight>
 +
 +
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();":
 +
 +
<syntaxhighlight lang=c#>
 +
                    writer.Write(noOfCharacters);
 +
                    foreach(Character tempCharacter in characters)
 +
                    {
 +
                        writer.Write(tempCharacter.ID);
 +
                        writer.Write(tempCharacter.Name);
 +
                        writer.Write(tempCharacter.Description);
 +
                        writer.Write(tempCharacter.CurrentLocation);
 +
                    }
 +
</syntaxhighlight>
 +
 +
You can now do the same for Places and items:
 +
 +
<syntaxhighlight lang=c#>
 +
                    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);
 +
                    }
 +
</syntaxhighlight>
 +
 +
=Completed Method=
 +
Your method should look like this:
 +
 +
<syntaxhighlight lang=c#>
 +
        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;
 +
            }
 +
        }
 +
</syntaxhighlight>
 +
 +
=Using it=
 +
To use this method, create a new case in the PlayGame switch case statement:
 +
 +
<syntaxhighlight lang=c#>
 +
                    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;
 +
</syntaxhighlight>
 +
 +
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.

Latest revision as of 12:21, 13 December 2018

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.