[C++] Black Jack in the Console. 4 Player.
I went to a college visit on Friday, talked to the head of the computer science department and this is their final project for Computer Science 1. He gives these guys a month to make this thing, I sat here in 2 hours and typed it out from start to finish and emailed it too him. And I'm suppose to pay fucking $28/year for this stuff I already know.. Anyways, here is my source, just compile it in an C++ compiler. Will only work in windows I believe, due to the includes.
Code:
#include <iostream>
#include <ctime>
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <sstream>
using namespace std;
void gotoPosition(int x, int y)
{
HANDLE hConsole = GetStdHandle ( STD_OUTPUT_HANDLE );
if ( INVALID_HANDLE_VALUE != hConsole )
{
int top_margin = 1;
COORD pos = {x, y + top_margin};
SetConsoleCursorPosition ( hConsole, pos );
}
}
void clearRow(int y)
{
gotoPosition(0, y);
cout << " " << endl;
}
int main()
{
int Cards[52], picked[52];
char CardTypes[13] = {'A', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'K', 'Q'};
char CardSuits[4] = {char(3), char(4), char(5), char(6)};
srand(time(NULL));
// Build the stack of cards.
for(int i = 0; i<52; i++)
{
int RandNumber = rand() % 52;
while(picked[RandNumber] == 1)
RandNumber = rand() % 52;
picked[RandNumber] = 1;
Cards[i] = RandNumber;
}
////
// Display out shat now.
// Row 1 is empty/margin from gotoPosition
// Row 2 is players current score
// Row 3 are player names/ids
// Rows 4-9 are meant for cards AKA the 'five card trick' for blackjack.
// Row 10 is where questions will be asked
////
int Scores[5] = {0, 0, 0, 0, 0};
int DeckPosition = 0;
// Margins of 15 on left and right, then 10 for dealer and each player
gotoPosition(14, 1);
cout << " Dealer " << " Player 1 " << " Player 2 " << " Player 3 " << " Player 4 " << endl;
// Print the first 2 cards for each person
for(int i = 0; i < 10; i++)
{
char CardValue = CardTypes[Cards[i] % 13];
char CardSuit = CardSuits[Cards[i] / 13];
int PlayerID = i % 5;
int x = (PlayerID * 10) + 18;
int y = 2;
DeckPosition += 1;
if(i > 4)
y = 3;
// Store their score
Scores[PlayerID] += Cards[i] % 13;
if(Cards[i] % 13 == 0) // If an ace.
Scores[PlayerID] += 1;
// If on the final row, print out their value above their name
if(y == 3)
{
gotoPosition(x, 0);
cout << Scores[PlayerID];
}
// Print out their second card
gotoPosition(x, y);
cout << CardValue << CardSuit << endl;
}
bool Continue = true;
int CurrentPlayer = 1; // Start at Player 1, then go all the way to Player 4 and then switch to dealer which is considered player 0
int PlayerCardRow = 4; // First 2 cards have already been dealt out, so we start at our 3rd.
bool hit = false;
while(Continue)
{
if(CurrentPlayer == 0) // If current player is the dealer..
{
if(Scores[CurrentPlayer] <= 16) // if the dealers hand is less than 16 then we have to hit.
hit = true;
else
{
hit = false;
Continue = false; // We can stop the loop because the dealer goes last.
}
}
else // Other players choose what they want to do.
{
if(Scores[CurrentPlayer] < 21) // If they are at 21 or higher, no reason to ask them..
{
bool correctAnswer = false;
string strHit;
// Continue asking until they answer either y or n (caps doesn't matter.)
while(correctAnswer == false)
{
clearRow(10);
gotoPosition(0, 10);
cout << "Player " + static_cast<ostringstream*>( &(ostringstream() << CurrentPlayer) )->str() << ", would you like to hit? (y or n)";
cin >> strHit;
if(strHit == "y" || strHit == "Y")
{
correctAnswer = true;
hit = true;
}
if(strHit == "n" || strHit == "N")
{
correctAnswer = true;
hit = false;
}
}
}
else
hit = false;
}
// Now control the cards.
if(hit)
{
if(PlayerCardRow < 9)
{
char CardValue = CardTypes[Cards[DeckPosition] % 13];
char CardSuit = CardSuits[Cards[DeckPosition] / 13];
int x = (CurrentPlayer * 10) + 18;
int y = PlayerCardRow;
// Store their score
Scores[CurrentPlayer] += Cards[DeckPosition] % 13;
if(Cards[DeckPosition] % 13 == 0) // If an ace.
Scores[CurrentPlayer] += 1;
// print out their value above their name
gotoPosition(x, 0);
cout << Scores[CurrentPlayer];
// Print out their next card
gotoPosition(x, y);
cout << CardValue << CardSuit << endl;
DeckPosition += 1;
PlayerCardRow += 1;
if(Scores[CurrentPlayer] >= 21) // If they bust or hit 21, goto next person
hit = false;
}
else
{
hit = false;
}
}
if(hit == false) // would be an else, but hit could have changed in the above structure.
{
// Swap to dealer if the new player would be player 5.
PlayerCardRow = 4;
if(CurrentPlayer == 0) // Not sure why, but on a rare occasion I need this, so it'll stay
Continue = false;
CurrentPlayer += 1;
if(CurrentPlayer > 4)
CurrentPlayer = 0;
}
}
////
// Game is over, let's find our winner.
////
bool tie = false;
int winners[2] = { -1, -1 };
int winningScore = 0;
int Player = 0;
for each(int Score in Scores)
{
if((Score < 22) && (Score > winningScore))
{
winningScore = Score;
winners[0] = Player;
tie = false;
// Compare to each other score.
int ComparedPlayer = 0;
for each(int ComparedScore in Scores)
{
if((ComparedScore < 22) &&
(ComparedScore >= Score)) // Either a tie or the compared score is winning
{
if(ComparedScore > Score)
{
winningScore = ComparedScore;
winners[0] = ComparedPlayer;
tie = false;
}
if(ComparedScore == Score)
{
winners[1] = ComparedPlayer;
tie = true;
}
}
ComparedPlayer += 1;
}
Player += 1;
}
}
clearRow(10);
gotoPosition(0, 10);
if(winners[0] == winners[1])
tie = false;
string winner1Name = "Player " + static_cast<ostringstream*>( &(ostringstream() << winners[0]) )->str();
string winner2Name = "Player " + static_cast<ostringstream*>( &(ostringstream() << winners[1]) )->str();
if(winners[0] == 0)
winner1Name = "Dealer";
if(winners[1] == 0)
winner2Name = "Dealer";
if(tie)
cout << "TIE! Our winners are " << winner1Name << " and " << winner2Name << " with a score of ";
else
cout << "Our winner is " << winner1Name << " with a score of ";
cout << winningScore << endl;
gotoPosition(0, 11); // Don't have the closing message erase data..
system("pause");
return 0;
}