/* Game of 21 program */

#include <iostream.h>
#include <lvp\random.h>
#include "utility.h"
//--------------------------------------------------------------------------------
int DealCard()
/*	Returns a random card value
	Post: A value from 1 to 10 returned */
{
	return(random(10)+1);
}
//--------------------------------------------------------------------------------
int DealUser()
/*	Asks the user how many cards are desired, and deals them,
	returning the sum
	Post: Cards have been displayed, and their sum returned       */
{
	int NumCards;
	cout << "How many cards do you want? ";
	NumCards = GetInt(1, 20);
	cout << "You: ";
	int CardCount, Card, SumCards = 0;
	for (CardCount=0; CardCount < NumCards; CardCount++) {
		Card = DealCard();
		cout << Card << " ";
		SumCards+=Card;
	}
	cout << " = " << SumCards << endl;
	return(SumCards);
}
//--------------------------------------------------------------------------------
int DealComputer()
/*	Deals cards to the computer and returns the sum
	Post: Three cards have been displayed, and their sum returned */
{
	const int NumCards = 3;
	cout << "Computer: ";
	int CardCount, Card, SumCards = 0;
	for (CardCount=0; CardCount<NumCards; CardCount++) {
		Card = DealCard();
		cout << Card << " ";
		SumCards+=Card;
	}
	cout << " = " << SumCards << endl;
	return(SumCards);
}
//--------------------------------------------------------------------------------
int FindWinner(int UserSum, int ComputerSum)
/*	Determines winner and returns code indicating winner.
	Post: Winner determined according to rules in the specification and
	code returned indicating the winner: 0=Draw  1=User Won
	2=Computer Won                                                                                  */
{
	const int Limit = 21;
	if ((UserSum==ComputerSum) || ((UserSum>Limit)
		&& (ComputerSum>Limit)))
		return(0);
	else if ((ComputerSum>Limit) || ((UserSum>ComputerSum)
		&& (UserSum<=Limit)))
		return(1);
	else
		return(2);
}
//--------------------------------------------------------------------------------
void ReportResult(int Result)
/*	Reports the result of the game
	Pre: Result is either 0, 1, or 2
	Post: Result has been displayed. */
{
	if (Result == 0)
		cout << "A draw! \n";
	else if (Result == 1)
		cout << "You win! \n";
	else
		cout << "Computer wins! \n";
}
//--------------------------------------------------------------------------------
int PlayGame()
/*	Plays one game of 21 and returns an indication of the winner
	Post: One game has been played, and a code returned indicating
	the winner: 0=Draw  1=User Won  2=Computer Won                  */
{
	int UserSum = DealUser();
	int ComputerSum = DealComputer();
	int Winner = FindWinner(UserSum, ComputerSum);
	ReportResult(Winner);
	return(Winner);
}
//--------------------------------------------------------------------------------
void UpdateCount(int Result, int &Wins, int &Losses, int &Draws)
/*	Increments one of the counters as determined by Result
	Pre: Result is either 0, 1, or 2
	Post: Either Wins, Losses, or Draws has been incremented based
	upon whether Result is 1, 2, or 0 respectively                                    */
{
	if (Result==0)
		Draws++;
	else if (Result==1)
		Wins++;
	else
		Losses++;
}
//--------------------------------------------------------------------------------
char AskRepeat()
/*	Asks the user if another game is desired and returns response
	Post: User has been asked and has responded with Y, y, N, or n.
	The response is returned.                                                                */
{
	char Answer;
	cout << "Would you like to play again? (Y/N)? ";
	cin >> Answer;
	while ((Answer != 'Y') && (Answer != 'y') && (Answer != 'N')
	  && (Answer != 'n')) {
		cout << "Answer Y or N please: ";
		cin >> Answer;
	}
	return(Answer);
}
//--------------------------------------------------------------------------------
void Report(int Wins, int Losses, int Draws)
/*	Reports the current results
	Pre: Wins, Losses, Draws represent the current results
	Post: The current results have been displayed                */
{
	cout << "Your wins = " << Wins << endl;
	cout << "Computer wins = " << Losses << endl;
	cout << "Draws = " << Draws << endl;
}
//--------------------------------------------------------------------------------
int main()
{
	randomize();
	int Wins = 0, Losses = 0, Draws = 0;
	char Answer;
	do {
		int Result;  // 0=draw  1=user win  2=computer win
		Result = PlayGame();
		UpdateCount(Result, Wins, Losses, Draws);
		Answer = AskRepeat();
	} while ((Answer != 'N') && (Answer != 'n'));
	Report(Wins, Losses, Draws);
	return(0);
}

