CS 70

Homework 3: Define the Sprite Class

Sprites are normally colorful little creatures, but for us they’ll just be a simple ASCII image.

In this step, we will define a new Sprite class. A sprite is a collection of characters which will be displayed in our asciimation. Together, this collection of characters forms an image that we will eventually move around the screen as it is displayed.

Your Task

The Sprite class is, conceptually, a wrapper around one thing—a fixed-size image, where its width denotes the number of columns it uses and its height denotes the number of rows.

The Sprite class has the following public data members:

  1. A static constexpr int SPRITE_WIDTH that stores the (fixed) width of Sprites we can support.
  2. A static constexpr int SPRITE_HEIGHT that stores the (fixed) height of Sprites we can support.
  3. A private data member that you need to add.

    • An array of characters of length SPRITE_WIDTH * SPRITE_HEIGHT called contents_ that holds the contents of the image. This array should exist directly inside of the Sprite object.

To build our asciimations, non-Sprite objects will need to be able to read the contents of our sprites. That information is stored in a private data member, which is good—it means that other objects can’t change it unless we let them! We will provide access to their contents through the public getCharAt(int row, int col) member function that returns the cth character in the rth row of the sprite’s character array.

We’ve given you the start of a parameterized constructor for a Sprite. It takes one parameter—a reference to a string that represents the filename containing the characters we should read into the Sprite’s contents. This file will always contain one line that consists of all the characters of the sprite. You can assume that the file has the right number of characters.

The parameterized constructor is currently unfinished. It is up to you to complete it so that it creates a valid Sprite object. The hints below may be helpful.

You should also disable the default constructor.

Helpful Hints

  • LHS Cow speaking

    These hints will help you write your Sprite class!

Reading a File One Character at a Time

When reading in the characters for the Sprite, you’ll want to create an ifstream like you did in the previous homework. However, you won't want to use >>, because that operator reads in entire words at a time (rather than the one character at a time we need here). Instead, you can use the ifstream function get(char&) in a loop to read one character at a time. The function takes a reference to a char, and will set the value of that char to the character it reads from the file. So, if you have an ifstream fileIn, you can use it as

char c;
fileIn.get(c);
// Now c has the next character in the file

Rows and Columns Versus Array Index

For the getCharAt function, a little array arithmetic should get you the right offset into the one-dimensional character array.

Consider drawing a picture of your sprite as a 2-D grid and number each item with its index in the array. What formula will turn the row and column into the index?

Invalid Inputs

Think about what you want your getCharAt function to do if it’s given an invalid row or column. From the standpoint of the assignment specification, passing an incorrect value isn't allowed.

But the question is, what should you do if someone breaks the rules? As you know, in the C++ language, it often just refuses to tell you specifically what will happen (a.k.a., undefined behavior). But you need to make a decision about what should happen if people break the rules.

One option is to just assume that you’ll always get good inputs. But other choices might make debugging easier. For example, you might choose a deterministic character that you’ll always return if you get bad inputs to the function. Or you might print an error and throw an exception; for example,

cerr << "A helpful message" << endl;

...

throw std::invalid_argument("Another helpful message");

Your choice here won’t affect your grade, but might make your coding process smoother.

Disabling the Default Constructor

Once you disable the default constructor, you won't be able to compile asciimation.o until you finish step 4, because the starter code we gave you will try to call the default Sprite constructor. (Why and where do you think that is happening?)

To Complete This Part of the Assignment...

You'll know you're done with this part of the assignment when you've done all of the following:

(When logged in, completion status appears here.)