Hey I've been making a blackjack game, I'm doing pretty well but I've run into a problem that I think may stem from how I'm passing function variables around, value not reference? or vice versa? I'll post alot of code: and a few sample outputs:
IO Class: Handles input and output for the game
Code:
#ifndef IO_H
#define IO_H
#include <iostream>
#include <string>
#include <map>
class IO
{
public:
typedef std::map<std::string, std::string> output;
void update_output(std::string id, std::string & update)
{
output::iterator index = coutput.find(id);
if (index == coutput.end())
{
coutput.insert(std::make_pair(id, update));
}
else
{
(*index).second = update;
}
}
void display_output()
{
for( output::iterator index = coutput.begin(); index != coutput.end(); ++index)
{
cout << (*index).second << std::endl;
}
}
int get_input()
{
std::cin >> input;
return input;
}
void clear_screen()
{
system("cls");
}
output coutput;
int input;
};
#endif
Game class: this is where the main game loop runs and ties alot of the code together and makes it work.
Code:
#ifndef GAME_H
#define GAME_H
#include "Dealer.h"
#include <vector>
#include <iostream>
#include "IO.H"
#include "Player.h"
class Game
{
public:
Game()
{
dealer = new Dealer;
deck = new Deck;
io = new IO;
init_players(1);
}
void play_game()
{
dealer->shuffle_deck((*deck));
dealer->draw((*deck), 2);
players[0]->draw((*deck), 1);
int gameloop = 1;
while(gameloop != 0)
{
io->update_output("dealer_cards", dealer->hand->read_cards());
io->update_output("player_cards", players[0]->hand->read_cards());
io->display_output();
gameloop = blackjack(io->get_input());
io->clear_screen();
}
}
private:
int blackjack(int result)
{
if (result == 1)
{
players[0]->draw((*deck), 1);
if (get_hand_value(players[0]->hand->hand) > 21)
{
return 0;
}
else { return 1; }
}
else if (result == 2)
{
if(get_hand_value(players[0]->hand->hand ) > get_hand_value(dealer->hand->hand))
{
return 0;
}
else { return 0; }
}
else if (result == 3)
{
return 0;
}
return 0;
}
int get_hand_value(vector<Card> hand)
{
sum = 0;
for (unsigned int loop = 0; loop < hand.size(); loop++)
{
sum += hand[loop].read_numeric_data();
}
return sum;
}
void init_players(unsigned int number)
{
for (unsigned int loop = 0; loop < number; loop++)
{
Player * player = new Player;
//player id will increment with the number of players
player->playerid = loop + 1;
players.push_back(player);
}
}
int sum;
Dealer * dealer;
Deck * deck;
IO * io;
vector<Player*> players;
};
#endif
This is how I output card strings, the hand class, the player class, and the deck class.
Code:
#ifndef PLAYER_H
#define PLAYER_H
#include "Data.h"
#include "Deck.h"
#include "IO.H"
class Hand
{
public:
Hand()
{
}
string & read_cards()
{
show_hand.erase();
for(unsigned int loop = 0; loop < hand.size(); loop++)
{
show_hand.append(hand[loop].read_string_data());
show_hand.append(" ");
}
show_hand.append("\n");
return show_hand;
}
vector<Card> hand;
private: // lookups
friend class Dealer;
friend class Game;
string show_hand;
};
class Player
{
public:
Player()
{
hand = new Hand;
}
void draw(Deck & deck, int number)
{
for(int loop = 0; loop < number; loop++)
{
hand->hand.push_back(deck.cards.back());
deck.cards.pop_back();
}
}
int playerid;
Hand * hand;
};
#endif
And the deck/cards
Code:
// This header file declares the deck class and all of its functions,
// as well as the card structure.
#ifndef DECK_H
#define DECK_H
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cassert>
#include "Data.h"
using namespace std;
class Card : public Data
{
public:
Card(int suit, int value)
{
initialize();
text_data.erase();
text_data.append(values[value]);
text_data.append(" of ");
text_data.append(suits[suit]);
numeric_data = points[value];
}
private:
void initialize()
{
add_to_string_lookup(suits, "Clubs");
add_to_string_lookup(suits, "Diamonds");
add_to_string_lookup(suits, "Hearts");
add_to_string_lookup(suits, "Spades");
add_to_string_lookup(values, "Two");
add_to_string_lookup(values, "Three");
add_to_string_lookup(values, "Four");
add_to_string_lookup(values, "Five");
add_to_string_lookup(values, "Six");
add_to_string_lookup(values, "Seven");
add_to_string_lookup(values, "Eight");
add_to_string_lookup(values, "Nine");
add_to_string_lookup(values, "Ten");
add_to_string_lookup(values, "Jack");
add_to_string_lookup(values, "Queen");
add_to_string_lookup(values, "King");
add_to_string_lookup(values, "Ace");
add_to_int_lookup(points, 2);
add_to_int_lookup(points, 3);
add_to_int_lookup(points, 4);
add_to_int_lookup(points, 5);
add_to_int_lookup(points, 6);
add_to_int_lookup(points, 7);
add_to_int_lookup(points, 8);
add_to_int_lookup(points, 9);
add_to_int_lookup(points, 10);
add_to_int_lookup(points, 10);
add_to_int_lookup(points, 10);
add_to_int_lookup(points, 10);
add_to_int_lookup(points, 11);
}
string_lookup suits;
string_lookup values;
int_lookup points;
int Suit;
int Value;
};
class Deck
{
public:
Deck()
{
unsigned int x = 0;
unsigned int y = 0;
unsigned int z = 0;
for (y = 0; y < 4; y++)
{
for (x = 0; x < 13; x++)
{
Card c(y,x);
cards.push_back(c);
}
}
assert(cards.size() == 52);
}
vector<Card> cards;
};
#endif
Here is the dealer class, i might remove it since it's only unique member is shuffle_deck..
Code:
#ifndef DEALER_H
#define DEALER_H
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "Deck.h"
#include "Player.h"
class Dealer
{
public:
Dealer()
{
hand = new Hand;
playerid = 0;
}
void shuffle_deck(Deck & deck)
{
random_shuffle(deck.cards.begin(), deck.cards.end());
}
void draw(Deck & deck, int number)
{
for(int loop = 0; loop < number; loop++)
{
hand->hand.push_back(deck.cards.back());
deck.cards.pop_back();
}
}
Hand * hand;
int playerid;
friend class Game;
};
#endif
Here is some sample output: The dealer's card's are the first line of cards, and the players is the second, I can hit 1, 2, or 3, 1 draws a card and checks to see if I'm over 21, 2 compares my cards with the dealers and declares a winner, and 3 folds my cards.
Code:
Nine of Clubs Two of Diamonds
Eight of Clubs
Notice how there are two clubs, I've noticed that there is almost always two of something... In this next bit of output I'll draw a few cards, look what happens:
Code:
Nine of Hearts Ten of Diamonds
Three of Spades Three of Clubs Three of Diamonds
OMG three three's?
some more output..
Code:
Jack of Clubs Six of Clubs
Eight of Hearts Two of Spades King of Clubs
Maybe this is normal? I dunno..
Anyways, can anyone help me clean up my code a little bit and get this random shuffle thing to work right?