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_backandpush_frontwill work (you already did so in the previous part of the assignment!). - Think about how
pop_frontwill 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
.jpgfile (either a photo of your nodes, whiteboard session, or a screenshot of your digital drawing), adding it to thePlanningfolder in your repository asPhase_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
IntVectorwithIntListinintlist-test.cpp. - Change the
#includedirective at the top of the file to includeintlist.hppinstead ofintvector.hpp. - Edit the
Makefileto change the dependencies of- The
intlist-test.cpptarget to requireintlist.hppinstead ofintvector.hpp. - The
intlist-testtarget to depend onintlist.oinstead ofintvector.o.
- The
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.
Woo-hoo! It works! And I'm getting better at the game, too!
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.
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.
So we need MORE functionality in our
IntListclass!!!
Meh. I thought it was good enough. I was totally ready to pack up and get out of here.
Helpful Hints
Gah! I got a segfault! What do I do now?!
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.
(When logged in, completion status appears here.)