\documentstyle[cprog]{simslide}
\tallslides
\uppercorners{Data Structures in C++}{\thepage}
\lowercorners{Classes and Object-Oriented Programming}{Chapter 2}
\begin{document}

\slide{}

{\Huge \bf
\begin{center}
$\;$ \\ $\;$ \\
Data Structures \\
in C++ \\ $\;$ \\
Chapter 2 \\ $\;$ \\
Tim Budd \\ $\;$ \\
Oregon State University \\
Corvallis, Oregon \\
USA \\
\end{center}
}

\slide{Classes and Object-Oriented Programming}

Purpose of this chapter
\begin{itemize}
\item
Introduce classes
\item
Introduce idea of object-oriented programming
\item
Programming using software components
\item
Characterising software by behavior
\end{itemize}

We will introduce these by means of an extended example program.

\slide{The Card game War}

\setlength{\unitlength}{3.2mm}
\begin{center}
\begin{picture}(46,10)
\put(0,6){\makebox(15,3){\em player 1}}
\put(0,0){\framebox(4,6){}}
\put(0,3){\makebox(4,3){ace}}
\put(0,0){\makebox(4,3){spade}}
\put(6,0){\framebox(4,6){}}
\put(6,3){\makebox(4,3){7}}
\put(6,0){\makebox(4,3){heart}}
\put(12,0){\framebox(4,6){}}
\put(12,3){\makebox(4,3){3}}
\put(12,0){\makebox(4,3){club}}
\put(21,0){\framebox(4,6){\em deck}}
\put(21,6){\line(1,1){1}}
\put(25,6){\line(1,1){1}}
\put(25,0){\line(1,1){1}}
\put(21.25,6.25){\line(1,0){4}}
\put(21.5,6.6){\line(1,0){4}}
\put(21.75,6.75){\line(1,0){4}}
\put(22,7){\line(1,0){4}}
\put(25.25,0.25){\line(0,1){6}}
\put(25.5,0.5){\line(0,1){6}}
\put(25.75,0.75){\line(0,1){6}}
\put(26,1){\line(0,1){6}}
\put(30,6){\makebox(15,3){\em player 2}}
\put(30,0){\framebox(4,6){}}
\put(30,3){\makebox(4,3){8}}
\put(30,0){\makebox(4,3){club}}
\put(36,0){\framebox(4,6){}}
\put(36,3){\makebox(4,3){ace}}
\put(36,0){\makebox(4,3){spade}}
\put(42,0){\framebox(4,6){}}
\put(42,3){\makebox(4,3){king}}
\put(42,0){\makebox(4,3){heart}}
\end{picture}
\end{center}

During each round
both players select one of their three cards, and places it face up.
If ranks are the same, then both players
retain their cards (setting them aside).  Otherwise, 
player with largest ranking card keeps both cards.
Each player draws one card from the deck to
replace the card just played.  The game ends when the deck is exhausted,
and the player with the most cards wins.

\slide{Nouns and Verbs}

The nouns in the problem description identify the components of the
game, the verbs identify what they do.

Components:

\begin{itemize}
\item
Card -- know its rank and suit
\item
Deck -- shuffle, draw, know when empty
\item
Player -- draw card from hand, keep own score
\end{itemize}

Will make software component for each.

\slide{The Class Card}

\begin{cprog}

enum suits {diamond, club, heart, spade};

class Card {
public:
		// constructors
	Card	( );
	Card	(suits, int);

		// data fields
	int  	rank;
	suits	suit;
};

\end{cprog}

\slide{Constructors}

A special type of function, used to combine {\em creation} and 
{\em initialization}, thereby ensuring that every object is properly
initialized.  Invoked automatically when object is declared.

\begin{cprog}

Card::Card	( )
	// initialize a new Card
	// default value is the ace of spades
{
	rank = 1;
	suit = spades;
}

Card::Card 	(suits sv, int rv)
	// initialize a new Card using the argument values
{
	rank = rv;
	suit = sv;
}

\end{cprog}

\slide{Overloaded Names}

A function with more than one name is said to be {\em overloaded}.

Note how constructor is overloaded.

Each version of an overloaded function must have unique argument types.

Other overloaded function we have seen -- operator $<<$.

\slide{Test our Abstraction}

\begin{cprog}

void main() {
	Card cardOne;
	Card cardTwo(diamond, 7);

	cout << "Card one\n";
	cout << cardOne.rank << "\n";
	cout << "Card two\n";
	cout << cardTwo.rank << "\n";
}

\end{cprog}

Not very nice, aces and face cards are numbers, not text, and can't
print suits.   Should be able to do better.

\slide{Output operator for Card}

\begin{cprog}

ostream & operator << (ostream & out, Card & aCard)
	// output a textual representation of a Card
{
	switch (aCard.rank) {	// first output rank
		case 1:
			out << "Ace";
			break;
		case 11:
			out << "Jack";
			break;
		case 12:
			out << "Queen";
			break;
		case 13:
			out << "King";
			break;
		default:	// output number
			out << aCard.rank;
			break;
		}


	switch (aCard.suit) {	// then output suit
		case diamond:
			out << " of Diamonds";
			break;
		case spade:
			out << " of Spades";
			break;
		case heart:
			out << " of Hearts";
			break;
		case club:
			out << " of Clubs";
			break;
		}
	return out;
}

\end{cprog}

We have overloaded the $>>$ operator by providing a new meaning for
printing when using Cards.

\slide{New Test Program}

\begin{cprog}

void main() {
	Card cardOne;
	Card cardTwo(diamond, 7);

	cout << "Card One:" << cardOne << "\n";
	cout << "Card Two:" << cardTwo << "\n";
}

\end{cprog}

Much nicer output.

\slide{Pass-by-Reference}

Note use of ampersand in declaration -- signifies pass-by-reference.

Used when passing large structures (such as streams) that are modifed
in the function.

Alternative, if nothing specified, is pass-by-value, which 
creates a {\em copy} of the argument.

Use pass-by-reference when you don't want to make a copy of the argument.
(unless argument is integer, float, pointer, or something else trivial
to copy).

\slide{The Class Deck}

\begin{itemize}
\item
A deck must maintain a collection of cards
\item
The deck must be able to shuffle the cards it holds
\item
The deck must be able to tell the user whether or not it is empty
\item
The user of the deck must be able to draw a card (assuming the deck is 
nonempty)
\end{itemize}

\begin{cprog}

class Deck {
public:
		// constructor
	Deck();

		// operations on a deck
	void	shuffle	();
	bool	isEmpty	();
	Card	draw  	();

protected:
	Card	cards[52];
	int 	topCard;
};

\end{cprog}

\slide{Protected and Public}

Protected are things that can be accessed only by functions associated with
the class.

Public features can be accessed outside of the class.

We have ``hidden'' the direct access to the data fields -- this is a good idea.

\slide{Arrays and Initialization}

\begin{cprog}

class Deck {
public:
		// constructor
	Deck();

		// operations on a deck
	void	shuffle	();
	bool	isEmpty	();
	Card	draw  	();

protected:
	Card	cards[52];
	int 	topCard;
};

\end{cprog}

Elements of the array are initialized using no-argument constructor
(termed the {\em default} constructor).

Will be given other values by the constructor for {\tt Deck}.

\slide{Deck Constructor}

\begin{cprog}
	
Deck::Deck ( )
	// initialize a deck by creating all 52 cards
{
	topCard = 0;
	for (int i = 1; i <= 13; i++) {
		Card c1(diamond, i), c2(spade, i), c3(heart, i), c4(club, i);
		cards[topCard++] = c1;
		cards[topCard++] = c2;
		cards[topCard++] = c3;
		cards[topCard++] = c4;	
		}
}

\end{cprog}

Note use of local variables. 

increment/subscript idiom -- very common in C and C++ programs.

\slide{To Shuffle, Need Random Numbers}

To shuffle, need a source of random numbers.  C++ run-time library
provides one function, but not exactly what we need.  But we can build
what we need.  First problem, rand() returns an arbitrary integer.
How would we convert this into a value between larger than or equal
to zero and smaller than max?

\begin{cprog}

		// rand() returns a random integer
		// take remainder when divided by max
		// to produce value in desired range
	unsigned int rval = rand();
	return rval % max;

\end{cprog}

\slide{Function Objects}

Now the next part is a bit tricky.  The library function we want to
call requires an OBJECT that ACTS like a function.   But function
calling is an operator in this language, so we can write this as
follows:

\begin{cprog}

class randomInteger {
	public:
		unsigned int operator () (unsigned int);
};

\end{cprog}

An object that can be used like a function is called
a function object.

\slide{Body of the randomInteger class}

Note carefully the various parts of the random integer object.

\begin{cprog}

unsigned int randomInteger::operator () (unsigned int max)
{
		// rand return random integer
		// convert to unsigned to make positive
		// take remainder to put in range
	unsigned int rval = rand();
	return rval % max;
}

\end{cprog}

\slide{The old Shuffle routine}

\begin{cprog}

randomInteger randomizer; // global variable randomizer object

void Deck::shuffle ( )
	// randomly shuffle the cards array, 
	// using the generic algorithm random_shuffle
{
	random_shuffle (cards, cards+52, randomizer);
}

\end{cprog}

Uses a {\em generic algorithm} provided by the
standard C++ library.  This algorithm needs a pointer to the front
and back of the array, as well as the function object that
can be used as the random number generator.

\setlength{\unitlength}{3.4mm}
\begin{center}
\begin{picture}(54,7)(8,0)
\put(0,0){\framebox(8,3){\tt card[0]}}
\put(8,0){\framebox(8,3){\tt card[1]}}
\put(16,0){\framebox(8,3){\tt card[2]}}
\put(24,0){\framebox(10,3){\tt ...}}
\put(34,0){\framebox(8,3){\tt card[50]}}
\put(42,0){\framebox(8,3){\tt card[51]}}
\put(0,3){\makebox(2,2){$\downarrow$}}
\put(8,3){\makebox(2,2){$\downarrow$}}
\put(16,3){\makebox(2,2){$\downarrow$}}
\put(34,3){\makebox(2,2){$\downarrow$}}
\put(42,3){\makebox(2,2){$\downarrow$}}
\put(50,3){\makebox(2,2){$\downarrow$}}
\put(0,4){\makebox(4,2){\tt cards}}
\put(8,4){\makebox(4,2){\tt cards+1}}
\put(16,4){\makebox(4,2){\tt cards+2}}
\put(34,4){\makebox(4,2){\tt cards+50}}
\put(42,4){\makebox(4,2){\tt cards+51}}
\put(50,4){\makebox(4,2){\tt cards+52}}
\end{picture}
\end{center}

\slide{Qualified Names}

\begin{cprog}

void Deck::shuffle ( )
	// randomly shuffle the cards array, 
	...

\end{cprog}

Note the name of the function being defined.

A qualified name describes both the class name and the member function
name -- neither by itself is sufficient to fully identify the function.

Similar to the way we use first names and last names to identify people.

\slide{Draw a Card}

\begin{cprog}

Card Deck::draw ( )
	// return one card from the end of the deck
{
	if (! isEmpty())
		return cards[--topCard];
	else {	  // otherwise return ace of spades
		Card spadeAce(spade, 1);
		return spadeAce;
		}
}

\end{cprog}

Note defensive programming -- always assume if somebody can use your
software component incorrectly, they will.

Note call on {\em isEmpty} -- asking ``am I empty?''

\slide{Testing to see if Deck is Empty}

\begin{cprog}

bool Deck::isEmpty ( )
	// return true if the deck has no cards
{
	return topCard <= 0;
}

\end{cprog}

\slide{In-line Function Definitions}

\begin{cprog}
	
class Deck {
public:
		// constructor
	Deck ( );

		// operations
	void	shuffle ( )
		{ random_shuffle (cards, cards+52, randomizer); }
	bool	isEmpty ( )
		{ return topCard < 0; }
	Card	draw ( );

protected:
	Card	cards[52];
	int 	topCard;
};

\end{cprog}

Should be used only for very short function bodies.

\slide{The class Player}

\begin{cprog}

class Player {
public:
		// constructor
	Player (Deck &);

		// operations
	Card	draw ( );
	void	addPoints (int);
	int 	score ();
	void	replaceCard (Deck &);

protected:
	Card	cards[3];
	int 	myScore;
	int 	removedCard;
};

\end{cprog}

\slide{Constructor for Player}

\begin{cprog}

Player::Player (Deck & aDeck)
	// initialize the data fields for a player
{
	myScore = 0;
	for (int i = 0; i < 3; i++)
		cards[i] = aDeck.draw();
	removedCard = 0;
}

\end{cprog}

\slide{Draw a Card from Hand}

\begin{cprog}

Card Player::draw ( )
	// return a random card from our hand
{
	removedCard = randomizer(3);
	return cards[removedCard];
}

\end{cprog}

Note this function is same name as one in {\tt Deck}, but no confusion
can arise (at least to the computer, won't talk about the programmer).

\begin{cprog}

void	Player::replaceCard (Deck & aDeck)
	// replace last card played with new card
{
	cards[removedCard] = aDeck.draw();
}

\end{cprog}

\slide{Keeping Score}

\begin{cprog}

void	Player::addPoints (int howMany)
	// add the given number of points to the current score
{
	myScore += howMany;
}

int	Player::score ( )
	// return the current score
{
	return myScore;
}

\end{cprog}

Functions to access or update a data field are called {\em accessor
functions} and {\em mutators}.

\slide{The Big Game}

\begin{cprog}

void main() {
	Deck theDeck; // create and shuffle the deck
	theDeck.shuffle();

	Player player1(theDeck); // create the two
	Player player2(theDeck); // players

	while (! theDeck.isEmpty() ) {
		Card card1  = player1.draw();
		cout << "Player 1 plays " << card1 << "\n";
		Card card2 = player2.draw();
		cout << "Player 2 plays " << card2 << "\n";

		if (card1.rank == card2.rank) { // tie
			player1.addPoints(1);
			player2.addPoints(1);
			cout << "Players tie\n";
			}
		else if (card1.rank > card2.rank) {
			player1.addPoints(2);
			cout << "Player 1 wins round\n";
			}
		else {
			player2.addPoints(2);
			cout << "Player 2 wins round\n";
			}
	}
	cout << "Player 1 score " << player1.score() << "\n";
	cout << "Player 2 score " << player2.score() << "\n";
}

\end{cprog}

\slide{An Interactive Game}

Wouldn't it be better if the game were interactive?

\begin{verbatim}
	. . .
	You current hold in your hand:
	a) Ace of spades
	b) 3 of clubs
	c) seven of diamonds
	which one do you want to play? b
	Human plays 3 of clubs
	Computer plays 7 of spades
	Computer wins round
	You currently hold in your hand:
	a) Ace of spades
	b) 4 of diamonds
	c) seven of diamonds
	which one do you want to play?
	. . .
\end{verbatim}

\slide{The Human Player class}

Make a class called {\tt HumanPlayer}, that is exactly the same as
the class {\tt Player}, only the {\tt draw} method does something
different.

Simply replace the first declaration of {\tt Player} in our game
with {\tt HumanPlayer}, and keep everything else the same.

Illustrates the great advantage of programming using components,
called {\em encapsulation}.

\slide{The Human Player Draw routine}

\begin{cprog}
Card	HumanPlayer::draw ()
	// draw one card from the current hand
{
	cout << "You currently hold in your hand:\n";
	cout << "a) " << cards[0] << "\n";
	cout << "b) " << cards[1] << "\n";
	cout << "c) " << cards[2] << "\n";
	cout << "Which one do you want to play? ";
	char answer[80];
	removedCard = -1;
	while (removedCard == -1) {
		cin >> answer;	// read response
		if (answer[0] == 'a') 
			removedCard = 0;
		else if (answer[0] == 'b')
			removedCard = 1;
		else if (answer[0] == 'c')
			removedCard = 2;
		if (removedCard != -1)
			return cards[removedCard];
		cout << "please specify a, b or c\n";
		}
}
\end{cprog}



\end{document}
