CS 70

Implementing the IntList Class (Phase 1)

We're now finally ready to start implementing the IntList class!

In the intlist.cpp file, you'll find that we've already implemented the default constructor, destructor, empty(), size(), swap, front(), and clear(). All these functions are either trivial or merely use the other functions you'll be writing.

Your Task, Part 1: Planning the Implementation

The implementation of the IntList class is pretty straightforward if you have a clear idea of how it is supposed to work and what the edge cases are. So, we require you to take some time to stop and think carefully about how the IntList class will work before you start writing code.

You will need to do the following:

  • Think about how push_back and push_front will work (you already did so in the previous part of the assignment!).
  • Think about how pop_front will work.
  • Make sure you've thought about the three edge cases we saw in the invariants discussion (and in particular, whether something special needs to happen when the list moves between these cases):
    • When the list is empty,
    • When the list has one element,
    • When the list has two or more elements.
  • Capture evidence of your planning as a .jpg file (either a photo of your nodes, whiteboard session, or a screenshot of your digital drawing), adding it to the Planning folder in your repository as Phase_1.jpg.

To give an example of the what planning evidence might look like, the Planning folder already contains a file called Phase_0.jpg that shows some planning for the default constructor and empty() function.

Your Task, Part 2: Implementing and Testing

Implementing the Missing Functions

Now, implement the following functions in intlist.cpp:

  • push_back(int value)
  • push_front(int value)
  • pop_front()
  • front() const

Make sure to call check_invariants() at the end of each function, as described in the previous part of the assignment.

Updating the Test Cases

Currently, the test cases in intlist-test.cpp are using IntVector in place of IntList. We'll fix that now.

  • Use search-and-replace to replace all occurrences of IntVector with IntList in intlist-test.cpp.
  • Change the #include directive at the top of the file to include intlist.hpp instead of intvector.hpp.
  • Edit the Makefile to change the dependencies of
    • The intlist-test.cpp target to require intlist.hpp instead of intvector.hpp.
    • The intlist-test target to depend on intlist.o instead of intvector.o.

Running the Test Cases

Now, run your test cases:

cs70-make -H intlist-test
./intlist-test

(You could just use make rather than cs70-make -H, but using cs70-make -H will catch more errors if you make a mistake updating the Makefile.)

If all the tests pass, great! But if not, running using valgrind will give you a backtrace that will help you find the problem:

valgrind --leak-check=full ./intlist-test

See the helpful hints section below for more ideas for debugging. Remember that you can always ask for help on Piazza, during grutoring hours, or during lab. It's important to get this part working before moving on to the next part of the assignment.

Your Task, Part 3: Switching the Snake Game to Use IntList

Now that we have a working IntList class, let's switch the Snake game to use it instead of IntVector. Open config.hpp and replace the code in the marked section with the following new code:

#define COORDLIST_USES_INTLIST 1

It's also probably easiest at this point to just generate all the Makefile dependencies from scratch, to make sure everything is correct. Run

clang++ -MM *.cpp

and then copy the output into the Makefile, replacing the existing dependency lines.

Then run

cs70-make -H snake
./snake

Hopefully the game will still work (and maybe even feel just a tiny bit snappier because it never has to copy large vectors around). If the game doesn't work, that may indicate that you have a bug in your IntList class that wasn't captured by your test cases. You might be able to get some insight by running the game under valgrind, but do not spend significant time trying to understand the internal logic of the Snake game. If you can't find anything obviously wrong with your IntList class, ask for help on Piazza, during grutoring hours, or during lab, but you can move on to the next part of the assignment without getting this part working—the Snake game is meant to be a fun application of your data structure, not a joyless debugging quagmire.

  • Dog speaking

    Woo-hoo! It works! And I'm getting better at the game, too!

  • Horse speaking

    Hay! I noticed something, though. In the ASCII-cast on the main assignment page, when you die in the game, the snake turns red and turns into xs. But in our game that doesn't happen.

  • LHS Cow speaking

    Yes, that's right. To change all the segments of the snake, we don't just need to be able to add and remove segments at the front and back, we also need to be able to iterate through all the segments.

  • Pig speaking

    So we need MORE functionality in our IntList class!!!

  • Goat speaking

    Meh. I thought it was good enough. I was totally ready to pack up and get out of here.

Helpful Hints

  • Hedgehog speaking

    Gah! I got a segfault! What do I do now?!

  • LHS Cow speaking

    Segfaults are a common symptom of pointer bugs.

If you use valgrind to run your test cases, it will give you a backtrace that shows you where the segfault happened, which often gives you a clue about what went wrong.

If you're still stuck, we now have a whole page of debugging tips that you can use to help you track down the problem.

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.)