2. private:
enum class GameState
{
Wager,
FirstRound, //check for blackjack and allow
double down; splitting COULD also go here; might be better to
have isFirstRound bool
PlayerInput,
DealerReveal, //let player surrender
DealerInput,
EndRound,
Exit
};
const int DECK_NUMBER; // not actually used
should delete
string message;
string error;
3. int input;
string name; //PLAYER NAME needed for persistent
stats (not implemented) should be constructor parameter
default:"Player"
BlackJackDeck deck;
BlackJackHand player;
BlackJackHand dealer;
int playerChips;
int playerWager;
//stuff for persistant stats (not implemented) maybe
make it an array which can be passed to the main.cpp menu
which will handle the user profile txt
unsigned long int handsPlayed;
unsigned long int handsWon;
unsigned long int handsLost;
unsigned long int chipsWon;
unsigned long int chipsLost;
8. void BlackJack::Input()
{
string sInput;
getline(cin, sInput);
stringstream linestream(sInput);
linestream >> input;
}
void BlackJack::Processing()
{
//CHECK IF DECK IS EMPTY HERE
error = "";
message = "";
//new round state?
if (state == GameState::Wager)
9. {
//player betting screen
if (input < 1 )
{
error += "You must bet at least one chip. ";
}
else if (input > playerChips)
{
error += "You cannot bet more chips than you
have. ";
}
else
{
playerWager = input;
playerChips -= input;
stringstream linestream;
linestream << "Player wagers " << playerWager
<< " chips. ";
10. message = linestream.str();
state = GameState::PlayerInput;
DealCards();
}
}
else if (state == GameState::PlayerInput)
{
//player input menu
//may have to split GameState::FirstRound where we
let player double down and check for blackjack
switch (input)
{
case 1:
{
BlackJackCard card =
deck.DrawCard();
11. player.AddCard(card);
message += "Player drew ";
message += card.ToString();
message += ". ";
if (player.GetBust())
{
message += "Player busts.
";
dealer.FlipFirstCard();
state =
GameState::EndRound;
}
else if (player.GetHandValue()
== 21)
{
dealer.FlipFirstCard();
state =
GameState::DealerInput;
12. }
break;
}
case 2:
{
message += "Player stands.
Dealer hand is revealed. ";
dealer.FlipFirstCard();
state = GameState::DealerInput;
break;
}
/* case 3: //betting not
implemented
break;
case 4:
break; */
default:
error += "Invalid Option ";
}
26. { //throw out of range exception with description
stringstream strOut;
strOut << "Rank argument: " << rank
<< " is out of range. Rank must be between "
<< MIN_RANK << " and " << MAX_RANK
<< ". ";
throw out_of_range(strOut.str());
}
else
{
myRank = rank;
}
}
void BlackJackCard::SetSuit(Suit suit)
{
if(suit < MIN_SUIT || suit > MAX_SUIT)
{ //throw out of range exception with description
stringstream strOut;
27. strOut << "Suit argument: " << suit
<< " is out of range. Suit must be between "
<< MIN_SUIT << " and " << MAX_SUIT <<
". ";
throw out_of_range(strOut.str());
}
else
{
mySuit = suit;
}
}
string BlackJackCard::ToString()
{
stringstream strOut;
if (isFaceUp)
{
strOut << SUITS[GetSuit()] << RANKS[GetRank()];
46. ValidInput::CinGetInteger(input,"Enter Choice: ","");
switch(input)
{
case1:
state =DeckNumber;
break;
case2:
state =Exit;
break;
default:
error ="Invalid Option";
}
}
elseif(state ==DeckNumber)
{
cout <<"How many decks do you want to play with? n
nnn"<<"1. (1)n2. (2)n3. (4)n4. (6)n5. (8)"<< endl;
cout << error << endl;
error ="";
ValidInput::CinGetInteger(input,"Enter Choice: ","");
switch(input)
{
case1:
deckNumber =1;
state =Game;
break;
47. case2:
deckNumber =2;
state =Game;
break;
case3:
deckNumber =4;
state =Game;
break;
case4:
deckNumber =6;
state =Game;
break;
case5:
deckNumber =8;
state =Game;
break;
default:
error ="Invalid Option";
}
}
elseif(state ==Game)
{
BlackJack game(deckNumber);
game.Run();
state =MainMenu;
}
system("CLS");
}
return0;
}
blackjackrevised2/ValidInput.h
48. //Nick Pierson
//Validation and Utility Functions
#ifndef _VALIDINPUT
#define _VALIDINPUT
#include <sstream>
#include <string>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <climits> // for limits of a int INT_MIN and
INT_MAX
#include <cfloat> // for limits of a double DBL_MIN and
DBL_MAX
using namespace std;
namespace ValidInput
49. {
bool IsStringInteger(string);
int StringToInteger(string);
bool CinGetInteger(int& value, string preText = "Please
enter an integer: ", string postText = "nPlease enter a valid
integer.n");
//
double GetValidDouble(const double MIN = -DBL_MAX,
const double MAX = DBL_MAX);
/** ClearInputBuffer function
* Clears the input buffer and resets the fail state of an
istream object.
*
* @param in (istream object by ref) - the object
to clear & reset; defaults to cin.
* @return none.
*/
void ClearInputBuffer(istream &in = cin); // function
prototype
50. bool IsStringInteger(string sInput)
{
char character = 0;
int number = 0;
stringstream linestream(sInput);
return ((linestream >> number) && !(linestream >>
character));
}
int StringToInteger(string sInput)
{
int number = 0;
if (IsStringInteger(sInput))
{
stringstream linestream(sInput);
53. cin >> validNumber; // try to get input
if(cin.fail()) // if user input fails...
{
// reset the cin object and clear the buffer.
ClearInputBuffer();
// report the problem to the user.
cerr << "nInvalid input. Please try again and enter
a numeric value.n";
// Try again by calling the function again
(recursion)
validNumber = GetValidDouble(MIN, MAX);
}
else if(validNumber < MIN || validNumber > MAX)//
if value is outside range...
{
// report the problem to the user.
cerr << "nInvalid input. Please try again and enter
a value between "
<< MIN << " and " << MAX << ".n";
// Try again by call the function again (recursion)
54. validNumber = GetValidDouble(MIN, MAX);
}
return validNumber; // returns a valid value to the
calling function.
}
void ClearInputBuffer(istream &in)
{
char characterFromBuffer; // a char variable to hold
input from the buffer
// if the in object has failed...
if(in.fail())
{
in.clear(); // clear the fail state of the object
characterFromBuffer = in.get(); // attempt to
read a character
// while the character read is not new-line or not
end-of-file
while (characterFromBuffer != 'n' &&
characterFromBuffer != EOF)
{
// therefore something was read from the
55. buffer
// attempt to read another character
characterFromBuffer = in.get();
} // end of while
}// end of if
} // end of ClearInputBuffer
}
#endif