A few good books for reading and learning about design are listed here, these are probably better as resources once you know about programming and some C++ rather than for the beginning programmer. Most of the books assume that you'll be using inheritance since this is basic to OO Design and Programming, but inheritance is not part of the AP C++ subset. However, the books below are still useful.
The two most important concepts to keep in mind are:
We'll use three steps to arrive at an initial design that we'll then take to a prototype stage. Your first task is to get into a group with up to three people; please work together on this. After each of the three steps below we'll stop and talk about where we are before going to the next step.
A version of hangman that reflects a combination of several group designs is available. The directory for the project/class header files and implementations is accessible.
| Bet | Odds |
|---|---|
| red or black | 1 to 1 |
| odd or even | 1 to t |
| single number | 35 to 1 |
| two consecutive numbers | 17 to 1 |
| three consecutive numbers | 11 to 1 |
Design a program that allows a player to make bets on roulette until either all money is lost or the player decides to retire. The player should be given an initial bankroll and then be prompted repeatedly for a bet. After each spin of the wheel the player should be appraised of the money available and asked if the game should be continued or chips cashed in.
Note that if the secret word is "tooth", the guess "pores" has one letter in common: 'o', the guess "tease" has one letter in common: 't', and the guess "spoof" has two letters in common: 'o' and 'o'.
Design a program that allows the user to play with the computer so that both competitors try to guess each other's word. It's very easy to come up with a strategy for the computer that does well without much intelligence: after every guess, eliminate every word that can't be the secret word. For example, if the guessed word (at random) has two letters in common, then eliminate every word that doesn't have exactly two letters in common with the secret word. Your program should make it straightforward to plug in new computer strategies.
I suggest implementing hangman since it's more interesting to play, although Jotto is also interesting in seeing how well a so-called "dumb" strategy does.
You should use the environment you'll be using during the year if that's available. You should specify C++ Console App, or the closest equivalent, when creating the project. We'll provide information about where ap classes are located as well as the location of a project that is used to create a library of useful classes. You should add this library,  aplib.lib to your project. From my perspective in thinking about the most important things to get across about using environments, a library is the single most important concept you should work on, we'll discuss whether I'm correct, an idiot, or simply addle-brained.
For discussion, we'll envision fish living in a 2D grid world. Every time-step of the simulation, the fish move in a random direction. We'll assume initially that this is north, south, east, west, i.e., fish move at right angles, but in designing classes you can assume that at some point fish will move diagonally too, i.e., there will be eight possible directions.
The world has edges (it's pre-Columbian) so fish can't move off an edge, and don't wrap around when moving, although it's possible that this will change too, so that at some point the world will be toroidal rather than flat.
For the first design, assume that there's an initial distribution of fish that might come from a file, or be random, or be hardwired into the program. Fish move at random, one-at-a-time, i.e., it is not the case that the fish all move at once, they take turns. A fish cannot move onto another fish. Fish live forever.
Come up with an initial design of classes/responsibilities/collaborators. We'll think about this in groups, then discuss, then go back to groups to think more about the design.
After the initial design there will be some changes. Among the changes might be the following, determine how your design will change as a result of these changes.
The program we're using is   people.cpp. A run is shown below, user input in italics (see 98subgroup for the datafile).
Don Allen Highschool M 125 Bill Burden Highschool M 203 Debbie Carter Highschool F 151 Ron Colby Highschool M 771 Theresa Cuprak Highschool F 217 Ann Fleury College F 618 Mark Stehlik College M 543 David Kay College M 345 Laurie White College F 929 Owen Astrachan College M 101 ------ 10 total people search for: (return to quit) C matches follow Debbie Carter Highschool F 151 Ron Colby Highschool M 771 Theresa Cuprak Highschool F 217 ------ 3 total people search for: (return to quit) ll matches follow Debbie Carter Highschool F 151 Ron Colby Highschool M 771 Theresa Cuprak Highschool F 217 Don Allen Highschool M 125 ------ 4 total people search for: (return to quit) n matches follow Debbie Carter Highschool F 151 Ron Colby Highschool M 771 Theresa Cuprak Highschool F 217 Don Allen Highschool M 125 Don Allen Highschool M 125 Bill Burden Highschool M 203 Owen Astrachan College M 101 ------ 7 total people search for: (return to quit) K matches follow Debbie Carter Highschool F 151 Ron Colby Highschool M 771 Theresa Cuprak Highschool F 217 Don Allen Highschool M 125 Don Allen Highschool M 125 Bill Burden Highschool M 203 Owen Astrachan College M 101 David Kay College M 345 ------ 8 total people search for: (return to quit) searching over
Your first task is to get into a group with up to three people; please work together on this. Look at the code in   people.cpp, if you have any questions about the code, or whether some part of the code is in the official AP C++ subset, please ask. You should come up with a list of comments or questions that you will bring up before the entire group. Of course you can get answers to questions from each other too. In addition to your own questions, please try to answer the questions below.
You want the list printed by the function Colletion::Print to be sorted by last name (and first name if the last names are equal).
We'll discuss methods for sorting by different criteria using templates in standard and advanced ways. We'll also discuss issues in searching and collecting.
In the case of Swap, the template parameter Type must support assignment. It would be illegal, for example, to try to swap two streams. If you do this in Codewarrior, for example, the error message below appears indicating that the assignment operator for streams is not public, hence streams cannot be swapped.
Error : illegal access to protected/private member sortall.cpp line 24 v[j] = v[k]; Error : illegal access to protected/private member sortall.cpp line 25 v[k] = temp;
In general, it can be difficult to ascertain only from error messages why a template instantiation fails since the error appears in the templated function, NOT in the instantiation which actually causes the error.
As documented in the header file for  sortall.h, elements being sorted must be comparable using the less-than operator <, but for merge and quick sorts the operator <= is used. We'll discuss alternatives to overloading operators using classes that work like function objects. These are shown in  dosort.cpp. We'll discuss how function objects work --- then you should do the following group problems by writing code or struct/class declarations.
Put solutions to all the problems on transparencies.
reading c:\data\shakes\hamlet.txt
read 31956 words, non-unique = 7234
union size: 10832
intersection size:2297
reading c:\data\shakes\errors.txt
read 16201 words, non-unique = 3721
union size: 12508
intersection size:1186
reading c:\data\shakes\macbeth.txt
read 18232 words, non-unique = 4813
union size: 14747
intersection size:892
reading c:\data\shakes\errors.txt
read 16201 words, non-unique = 3721
union size: 14747
intersection size:892
reading c:\data\shakes\allswell.txt
read 24372 words, non-unique = 5336
union size: 17016
intersection size:781
First, as a group, determine what member functions and operations the class apset should have. Don't worry about implementation details, just the member functions (or non-member functions) that you think should exist to support a good set abstraction.
Make a list of the functions you think should be included. When you're done with the list, try to rank the three or four functions you think will be hardest to implement.
Complete versions of an apset class using unsorted vectors to
store elements are in apset.h and apset.cpp. This implementation is extremely
slow, contrast it with the the binary search tree implementation of the
class in apset3.h and apset3.cpp.
In the current version, the function interHelp uses an inorder
traversal which leads to a degenerate tree (like a linked list) for the
result of the intersection. In the workshop this was shown to
participants, they were asked to reason about why the tree is bad/time
is slow, and to think about which of pre-order and post-order traversals
would be better alternatives to the inorder traversal shown.
A version is also accessible
that uses a sorted vector with binary search, the .h file is the same as
the original implementation, but there is a different .cpp file: apset2.cpp.
The run below shows   bigfact.cpp using a version of the BigInt class that is augmented to print a message each time a constructor or destructor is called. This version has a copy constructor and an assignment operator to illustrate all the things that happen when the BigInt class is used. The augmented code is accessible in  bigint.cpp.
Warning: do not ask your students to do this exercise, it isn't necessary to trace every single call, but it is a worthwhile experience for indepth knowledge of what's happening with C++. However, in my experience it isn't worth covering the class in this kind of detail. I can only hope that the AP test will not test this, and if it does, I'd suggest skipping the question.
Find the line that calls every printed constructor, destructor, assignment operator in the two runs below. For example, the first line of output is caused when the local variable BigInt b in main is constructed. The last line is caused when this variable goes out of scope when main exits. The hexadecimal number preceding each line of output is this, the address of the object being constructed, destructed, or assigned to.
User-entered input in italics.
0x0012ff58 default constructor called
enter first last numbers for factorial: 3 4
0x0012ff24 int constructor called 1
0x0012fefc copy constructor called with 1
0x0012ff38 copy constructor called with 1
0x0012fefc destructor called for 1
assignment operator called with 1
0x0012ff38 destructor called for 1
0x0012fefc copy constructor called with 1
0x0012ff38 copy constructor called with 2
0x0012fefc destructor called for 2
assignment operator called with 2
0x0012ff38 destructor called for 2
0x0012fefc copy constructor called with 2
0x0012ff38 copy constructor called with 6
0x0012fefc destructor called for 6
assignment operator called with 6
0x0012ff38 destructor called for 6
0x0012ff78 copy constructor called with 6
0x0012ff24 destructor called for 6
assignment operator called with 6
0x0012ff78 destructor called for 6
3! = 6
0x0012ff24 int constructor called 1
0x0012fefc copy constructor called with 1
0x0012ff38 copy constructor called with 1
0x0012fefc destructor called for 1
assignment operator called with 1
0x0012ff38 destructor called for 1
0x0012fefc copy constructor called with 1
0x0012ff38 copy constructor called with 2
0x0012fefc destructor called for 2
assignment operator called with 2
0x0012ff38 destructor called for 2
0x0012fefc copy constructor called with 2
0x0012ff38 copy constructor called with 6
0x0012fefc destructor called for 6
assignment operator called with 6
0x0012ff38 destructor called for 6
0x0012fefc copy constructor called with 6
0x0012ff38 copy constructor called with 24
0x0012fefc destructor called for 24
assignment operator called with 24
0x0012ff38 destructor called for 24
0x0012ff78 copy constructor called with 24
0x0012ff24 destructor called for 24
assignment operator called with 24
0x0012ff78 destructor called for 24
4! = 24
0x0012ff58 destructor called for 24
(program terminates)
Here's another pair of runs, but the line that updates result in the
function fact is replaced by:
0x0012ff58 default constructor called
enter first last numbers for factorial: 3 4
0x0012ff34 int constructor called 1
0x0012ff78 copy constructor called with 6
0x0012ff34 destructor called for 6
assignment operator called with 6
0x0012ff78 destructor called for 6
3! = 6
0x0012ff34 int constructor called 1
0x0012ff78 copy constructor called with 24
0x0012ff34 destructor called for 24
assignment operator called with 24
0x0012ff78 destructor called for 24
4! = 24
0x0012ff58 destructor called for 24
(program terminates)
0x0012ff58 default constructor called
enter first last numbers for factorial: 11 11
0x0012ff34 int constructor called 1
0x0012ff14 int constructor called 11
0x0012fea0 copy constructor called with 3628800
0x0012feb0 int constructor called 0
0x0012fe78 copy constructor called with 3628800
0x0012fecc copy constructor called with 3628800
0x0012fe78 destructor called for 3628800
0x0012fe68 int constructor called 0
0x0012fe68 destructor called for 0
0x0012fecc destructor called for 3628800
0x0012fe78 copy constructor called with 36288000
0x0012fecc copy constructor called with 36288000
0x0012fe78 destructor called for 36288000
0x0012fe68 int constructor called 0
0x0012fe68 destructor called for 0
0x0012fecc destructor called for 36288000
assignment operator called with 39916800
0x0012feb0 destructor called for 39916800
0x0012fea0 destructor called for 362880000
0x0012ff14 destructor called for 11
0x0012ff78 copy constructor called with 39916800
0x0012ff34 destructor called for 39916800
assignment operator called with 39916800
0x0012ff78 destructor called for 39916800
11! = 39916800
0x0012ff58 destructor called for 39916800
(program terminates)
cout << k << "! = \t" << fact(k) << endl;
How will the output change for calculating 3 and 4 factorial using the result *= k method?
We'll first engage in a paper-and-pencil debugging exercise. I claim that using two other people and the code on paper will find the bug here faster than individuals who use a computer. If anyone would like to try to prove/disprove this claim we'll make arrangements.
The code in   linkbig.h and   linkbig.cpp uses a singly-linked list without a header node to implement a class LBigInt. The only changes to the code from the original BigInt class are in the functions listed below:
enter first last numbers for factorial: 1 7 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040However, if the for loop runs down from last to first, i.e., the commented-out for loop is used instead, the output is incorrect as shown below:
enter first last numbers for factorial: 1 7 7! = 5040 6! = 5720 5! = 5120 4! = 5124 3! = 5126 2! = 5122 1! = 5121
However, if the same downto for loop is used, but the variable BigInt b is printed instead of BigInt a, then the output will be correct.
You are to find the bug that causes this problem. As an aid in finding the bug, there is a comment in the copy constructor that indicates that swapping only the lines below in terms of which is commented out, will yield a correctly running program.
while (rtemp != NULL)
// for(int k=1; k < rhs.myNumDigits; k++)
As a further aid, if the definitions of local variables LBigInt a,b are moved inside the for loop in main, the output will be correct.
When and if you find the problem, you may be able to come up with some ideas for optimizing the use of nodes. We'll discuss these. We'll also discuss why arithmetic operations are much slower using linked lists and how you might speed them up.
To minimize the use of new, you can use a global variable defined in the file  linkbig.cpp or you can use a static variable in the BigInt class. You could use a global stack, for example. Instead of calling delete in the destructor, for example, you can push a node onto the stack. Instead of calling new, check the stack to see if it's empty --- if not, pop a node instead of calling new. You'll want to use a stack of pointers to nodes.
To time the differences in using this method, you'll want to use the class SysTimer declared in  systimer.h that's part of the library you're using. Using this class, calculate some large factorial values or raise a number to a power. We'll discuss changes and results when we get together after lab.
First we'll discuss issues of college credit and the similarity of AP courses to college courses. We'll also discuss how to use classes in an A course and how classes will be used on the exam (although on this last item there's no inside information.)
We'll discuss classes and how they're used by looking at the 1998 exam in C++. This can be found at the web site http://www.cs.duke.edu/~ola/ap.html , and is mirrored locally for the purposes of the workshop: 1998 Exam in C++.
We'll look at the questions that appear on the A exam. These are/should be indicative of how classes will be used on the 1999 exam when C++ is used for the first time. Look over the questions in groups of two/three and ask if there are questions. Some questions to guide your inquiry are given below:
In a group of two to three people, hopefully with college people collaborating with high school people, come up with an artifact/resource that will be useful to those involved with AP. This must be something written, preferably in electronic format. It doesn't have to be in HTML format, it can be in Microsoft Word, plain text, PDF, etc. If you include code (and in many cases you will), please make sure the code compiles and runs. This means you should provide driver programs for any functions and classes you use.
Although it would be great if you finished something during this workshop, it's not anticipated that you'll have a polished product. Something more than a germ of an idea, but less than a full blown, finished document would be great.
Suggestions for resources: