Goals for this homework

  • Practice with object-oriented concepts - inheritance and polymorphism

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.

In this assignment, we are going to build up the idea of the "item" that is being stored in the inventory / quick slots. Fundamentally, there are two kinds of items. There are weapons that act on other objects and there are other items that act on the individual.

Previously, we had different methods in the Sprite class for the different actions that weapons and shields apply to the Sprite. This is not a good object-oriented design. Instead, we should have the Sprite class be simple and then have each of the shield classes / weapon classes be specialized to their own characteristics.

You should submit several files for this assignment ( Sprite.cs, Point.cs, Item.cs, Projectile.cs, SmallShieldPot.cs, LargeShieldPot.cs, BandageBazooka.cs, AssaultRifle.cs, Bandage.cs, MedKit.cs) and Makefile) to Gradescope. Make sure you use the new folder naming scheme.

Set Up

Make sure you add to your Makefile as you complete classes.

Now you need to make the skeleton code so that your program will minimally execute. You must do this in case you do not complete your assignment. Our testing infrastructure needs to compile and execute even if you did not complete the entire assignment.

  • Step 1: Create all of the .cs files. Each class requires its own file, named classname.cs. For each method, implement the method with a single line - return with the right type. For example:
    public class Blah {
      public double surface_area_cylinder(double height, double radius)
      {
    	return 0.0;
      }
    }
    
  • Step 2: Create TestItem.cs. For each method, put in a single method call. This single test file will end up testing all of your new classes. Most of the classes are so small they don't merit their own test file. For example:
    public static void Main(string[] args)
    {
    	Blah b = new Blah();
    	b.surface_area_cylinder(1.0, 5.0);
    	// add the rest of the method calls here
    }
    
First get this compiling and running. It won't print out anything, 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.

Step 1: Adding Setters and Getters to Sprite

Your first job is to add setters and getters to the Sprite class. A getter returns the value of an instance variable. A setter sets that value. Below is the code for the Shield. Add that to your Sprite class. Then you need to fill in the code for Health. You do not need to create Setters and Getters for other methods since we're just doing a subset of the functionality.
        public uint GetShield()
        {       return Shield;  }

        public void SetShield(uint s)
        {       Shield = s;     }

Step 2: Item class and subclasses

The next step is to create an Item class and then subclasses for each item that the Sprite could carry. It would be tedious to create the whole set of items, so I am just going to have you do two of each category. I have already created Item.cs for you. It is defined as follows:
public class Item
{
        private string name;
        protected Sprite holder;

        public Item(string n, Sprite h)
        //, int hc, int sc, int ec,
        //      uint mh, uint ms, bool i, uint s, uint md)
        {
                name = n;
                holder = h;
        }

        public virtual Projectile Use()
        {
                return null;
        }
}

The only common thing for all items is that they have a name and a Sprite is holding them. In addition, the player holding them can use them. The Use method is what is different for each item type. Therefore, that is declared virtual in the base class. It merely returns null. You will need to redefine (override) this definition in each subclass. In addition, you need to add two methods to Item: the Equals method and GetHashCode method so that it can be used in the Dictionary class.

For some items, like potions, bandages, and med kits, when the holder uses them,they affect the holder's health and/or shield. However, for weapons that are aimed at other players, there is no effect on the holder - instead, something occurs if their aim is accurate enough to hit that other player. For this purpose, I have created a Projectile class.

This Projectile class. is for any actions that result in a projectile (firing a weapon). The purpose of the Projectile class is to provide all of the information necessary for when the projectile hits its target. The projectile can be a bullet from a weapon, which would do damage when it hits, meaning it has a negative value for health or shield. There is also the chance of a "healing" weapon, which will have a positive value. Because healing items sometimes have limits on how much health or shield can result from it, there is a maxHealth and maxShield value. If there is no limit, then the max is 100.

You might be wondering where the projectile goes. If we were implementing a full game, that would be the next step. However, because I want to keep the assignment tractable, we are not implementing making the projectile fly and detecting whether or not it hits anyone on its way.

As an example, I have partially implemented the SmallShieldPot class. The code properly applies changing the shield of the holder Sprite. However, it doesn't yet decrement the inventory of the holder. For the pots, medkit, and bandage, you need to decrement the inventory if it is used successfully (the checks for using it pass like having less than 100 health in order to use bandage or medkit).

In this part, you need to complete the SmallShieldPot class and implement the following classes:

  • LargeShieldPot
  • MedKit
  • Bandage
  • BandageBazooka - shoots a projectile that contains one bandage (15 health) and there is no maximum on the health that can be obtained from the bandage bazooka. It makes no change to the person; it only does the projectile. In addition, it does not decrement how many are in the inventory - we haven't programmed in the distinction between a weapon and its ammunition, so we'll just simplify and say it has infinite ammunition. Distance is 50, speed is 100. You may ignore the velocity number (it would be calculated from direction and speed). You do not need to set it.
  • AssaultRifle - shoots a projectile that contains one bullet (-20 shield) Distance is 60, speed is 5. You do not need to set velocity in this assignment. Note that is something takes -20 from shield, and there is no shield (or sheild < 20), then the rest is taken off health. In addition, it does not decrement how many are in the inventory - we haven't programmed in the distinction between a weapon and its ammunition, so we'll just simplify and say it has infinite ammunition.

Step 3: UseQuickSlotItem

Now you need to adjust the Sprite to use these new Item objects.

First, now Inventory and QuickSlot hold Item objects, not just strings. When you read in the file of what items are in the inventory / quickslot, you will create Items of the appropriate type to place in the inventory.

Next, you need a public Projectile UseQuickSlotItem(uint slot) method that calls the Use method on the Item stored in that QuickSlot (if it exists). Make sure you initialize the quick slot array properly so that empty is set to null pointers and that you check for null before trying to call Use on an item.

Submit

Submit once the autograder comes on line.