Due Tuesday, 11:59pm

Goals for this homework

  • Write a class from the start
  • Use C# Collections

You are expected to complete this assignment individually. If you need help, you are invited to come to office hours and/or ask questions on piazza. Clarification questions about the assignments may be asked publicly. Once you have specific bugs related to your code, make the posts private.

Another note about Piazza. Piazza is your community resource - please use those as discussions amongst yourselves. We are not monitoring it all day, rather we each have check-in times once a day. Therefore, you need to start early enough to wait for feedback and/or build a vibrant, supportive community that helps each other while we are completing other necessary tasks (research, developing assignments, preparing for lecture, performing advising tasks, etc.).

In this homework, you'll add to the sprite we created.

You should submit several files for this assignment ( Sprite.cs, TestSprite.cs, TestPoint.cs, Point.cs, testsprite.txt, testpoint.txt Makefile). You will submit your work in a zip file to Gradescope. More detailed submission instructions will come later.

Error Handling

Error handling capabilities vary by language, and what you want to do in an error varies by the situation. When an error occurs in a function, the question becomes, what should you do, and how do you notify the caller that an error occurred?

In C#, there is a construct for this. We'll use this when calling functions that use it but, right now, we won't implement them ourselves. This is an exercise because if you write a function, and it's used in a variety of different circumstances, it is bad programming practice to determine within the function what will be done. For example, one program might want to exit, whereas another might want to notify the user that there was bad input and to try again.

In this course, we will print the error message in a special way (see below). If there is an opportunity, we will designate a specific return value for an error condition. If there is no available return value, then we will exit from within the function.

  fprintf(stderr, "error: too many widgets for the number of grommets\n");
  fprintf(stderr, "error: need ten boondoggles, but only have %d\n", num_bds);

Sometimes, these lines will be followed by exit(1); This immediately exits the program and returns a code. If you were writing a large program, you might assign a different code to each type of error that would result in an exit.

Makefile

Because you are adding a second set of files to your directory, you need to add a second target to your Makefile. In your makefile, add another two lines (with a space between these and the ones already there).
TestSprite.exe: TestSprite.cs Point.cs Sprite.cs
	mcs TestSprite.cs Sprite.cs Point.cs
To compile, type:
make TestSprite.exe

Set Up

The first thing to do is to create a skeleton project that will minimally execute. In the future, you will be expected to create it for yourself. A skeleton has the following in it:
  • Step 1: In one file, put in the class and method declarations. In the body, print the fact that it is not yet implemented and return with the right type. For example:
    public float surface_area_cylinder(float height, float radius)
    {
    	Console.WriteLine("surface_area_cylinder not yet implemented");
    	return 0.0;
    }
    
  • Step 2: Create the test file with the Main method. For each method, put in a single call. For example:
    public static void Main(string[] args)
    {
    	float fval;
    	LabXMethods lxm = new LabXMethods();
    
    	fval = lxm.surface_area_cylinder(3.5, 7.9);
    }
    

First get this compiling and running. It won't do anything useful, but this will mean that your code will compile and execute with our infrastructure. This must work in order to get any points in this course. Do this first, not last.

Reading from a file

Because the sprite state is more complex, you'll need to store the state in a file (well, the inventory items, anyway). You will need to place this code in TestSprite.cs to read in the initial state of a sprite. Here is how you read from a file.

Here is code to read the lines of a file into an array of strings.

        // Read each line of the file into a string array. Each element
        // of the array is one line of the file.
        string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Public\TestFolder\WriteLines2.txt");

        // Display the file contents by using a foreach loop.
        System.Console.WriteLine("Contents of WriteLines2.txt = ");
        foreach (string line in lines)
        {
            // Use a tab to indent each line of the file.
            Console.WriteLine("\t" + line);
        }
Here is code to parse a string into different pieces, split by spaces.

	string phrase = "The quick brown fox jumps over the lazy dog.";
	string[] words = phrase.Split(' ');

	foreach (var word in words)
	{
	    System.Console.WriteLine($"<{word}>");
	}

Point Class

The first thing you will do is create a Point class to hold the x, y, z coordinate of the object. This class will have the following methods. Point has three private variables: XCoor, YCoor, and ZCoor.
  • public Point()
    Constructor. Set to (0, 0, 0)
  • public Point(int x, int y, int z)
    Constructor. Set to (x, y, z)
  • public void SetLocation(int x, int y, int z)
    Set to (x, y, z)
  • public void SetX(int x)
    Standard setter. Set x coordinate to x
  • public void SetY(int y)
    Standard setter. Set y coordinate to y
  • public void SetZ(int z)
    Standard setter. Set z coordinate to z
  • public int GetX()
    Standard getter. Return x coordinate
  • public int GetY()
    Standard getter. Return y coordinate
  • public int GetZ()
    Standard getter. Return z coordinate
  • public float CalculateDistance(Point p)
    Calculate distance between this Point and input argument p
  • public override bool Equals(Object obj)
    Define what it means for two Points to be equal. Look at the Sprite Equals for the pattern of how to code it.
  • public override int GetHashCode()
    Again, use the Sprite code as a guide, doing an xor of the three variables.
  • Also, update your Sprite code to use Point for the location instead of the separate XCoor, YCoor, and ZCoor.

Sprite Class

You will now add inventory functionality to your Sprite class. There will be a full inventory (everything that is in their backpack) The inventory is stored in name, number pairs. The name is the name of the item and the number is the number of that item they are holding. For example, if they are holding 3 small potions, inventory shows ("SmallPotion",3). as well as 6 quick slots (everything they can use with a single keystroke). The full inventory will be a dictionary, whereas the 6 quick slots will be an array. You need to implement the following functions.

  • Sprite()
    Add initialization of the inventory and quick slots to empty for all constructors
  • Equals()
    update the code to include checking the inventory and quick slots
  • void AddItem(string item)
    add an item to the inventory, updating the number of items as necessary.
  • bool HasItem(string item)
    return true if the item is in the inventory, false if not.
  • void PutItemInQuickSlot(string item, uint slot)
    If slot < 6, put in quick slot. If quick slot already has something, replace it with new item. Item is still in inventory. You are not removing something from the inventory, merely indicating which items can be utilized in a single keystroke by the user of the game. Therefore, the quantity of item is still the same as in the inventory. In addition, you cannot have the same item in two different quickslots at the same time.
  • string GetItemInQuickSlot(uint slot)
    If slot < 6, and there is an item in that slot, return the item
  • void PrintInventory()
    Print the contents of the inventory. It must print out like this:
    Console.WriteLine(""+i+": ("+item+", "+count+")");
    That is, it must have a counter that increments each item (i), then print the item name, then print the number of that item in the inventory.
  • void PrintQuickSlots()
    Print the contents of the quick slots. It must print out like this:
    Console.WriteLine(""+i+": ("+item+", "+count+")");
    That is, it must have a counter that increments each item (i), then print the item name, then print the number of that item in the quick slots. The counts are based on the inventory - you need not store the quantity in the array.

    If a specific slot is empty, then print #: empty

Testing



For testing Point, the general test line will look like this:
TestPoint.exe start_state expected_end_state test# inputs expected_ret_val
We will have the following tests for Point functions:
  • SetLocation: TestPoint.exe x y z x y z 0 newx newy newz
  • SetX: TestPoint.exe x y z x y z 1 newx
  • SetY: TestPoint.exe x y z x y z 2 newy
  • SetZ: TestPoint.exe x y z x y z 3 newz
  • GetX: TestPoint.exe x y z x y z 4 x
  • GetY: TestPoint.exe x y z x y z 5 y
  • GetZ: TestPoint.exe x y z x y z 6 z
  • CalculateDistance: TestPoint.exe x y z x y z 7 otherx othery otherz distance
  • Equals: TestPoint.exe x y z x y z 8 otherx othery otherz result
  • You are not required to test GetHashCode
For testing, the general test line will look like this:
TestSprite.exe start_state expected_end_state test# inputs expected_ret_val
The start state is given in the following order for sprites:
x, y, z, horiz, vert, health, shield, items.txt
where items.txt lists the items in the inventory and, if applicable, quick slots.
  • AddItem: TestSprite.exe x y z h v h s items.txt x y z h v h s items2.txt 0 item
  • HasItem: TestSprite.exe x y z h v h s items.txt x y z h v h s items.txt 1 item ret_val
  • PutItemInQuickSlot: TestSprite.exe x y z h v h s items.txt x y z h v h s items2.txt 2 item quickslot
  • GetItemInQuickSlot: TestSprite.exe x y z h v h s items.txt x y z h v h s items.txt 3 quickslot item
  • PrintInventory: TestSprite.exe x y z h v h s items.txt x y z h v h s items.txt 4 expected_output.txt
  • PrintQuickSlots: TestSprite.exe x y z h v h s items.txt x y z h v h s items.txt 5 expected_output.txt

Submit