Thread: Making a Blackjack game..

  1. #46
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Looks like you have a "using namespace std" that is incorrectly spelled, or an error in the headerfile before that - such as a missing semicolon. These are the type of errors that can be quite hairy to sort out.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #47
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I eliminated two errors by getting rid of all my namespace declarations..

    I eliminated another 2 by fixing a '{' that was supposed to be a '('
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  3. #48
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I've gotten all the main game components to work properly, I can play a game of blackjack without any bugs, I havn't added betting into the system yet but that will come soon. What I'm working on now is an updatable IO system that I can place in the main game loop.

    First I needed to make a way so I can output complex data on the screen, such as a hand of cards. I made a base class called data for such complex data. All data will need a lookup table and a method to read back the output in the form of a string based on the lookup table.

    Code:
    class Data // this is the class that will define how we output certain data sets on the screen
    {
    public:
    	typedef std::vector<string> lookup;
    	// everytime we create a class that is derived from Data it will run this function
    	Data()
    	{
    		initialize();
    	}
    
    	void add_to_lookup(lookup table, string word)
    	{
    		table.push_back(word);
    	}
    
    	virtual void initialize(){}// function to initialize a specific lookup.
    	virtual void read_data(){} // function to output specific data.
    };
    Here is an example of a class that is derived from the base class Data:

    Code:
    #ifndef PLAYER_H
    #define PLAYER_H
    #include "Data.h"
    #include "Deck.h"
    #include "IO.H"
    class Hand : public Data
    {
    	void draw(Card card)
    	{
    		hand.push_back(card);
    	}
    
    	std::vector<Card> get_cards()
    	{
    		return hand;
    	}
    
    	string read_cards()
    	{
    		show_hand.erase();
    		for(unsigned int loop = 0; loop < hand.size(); loop++)
    		{
    			show_hand.append(values[hand[loop].Value]);
    			show_hand.append(" of ");
    			show_hand.append(suits[hand[loop].Suit]);
    			show_hand.append("		");
    		}
    		show_hand.append("\n");
    		return show_hand;
    	}
    
    	void initialize()
    	{
    		add_to_lookup(suits, "Clubs");
    		add_to_lookup(suits, "Diamonds");
    		add_to_lookup(suits, "Hearts");
    		add_to_lookup(suits, "Spades");
    		add_to_lookup(values, "Two");
    		add_to_lookup(values, "Three");
    		add_to_lookup(values, "Four");
    		add_to_lookup(values, "Five");
    		add_to_lookup(values, "Six");
    		add_to_lookup(values, "Seven");
    		add_to_lookup(values, "Eight");
    		add_to_lookup(values, "Nine");
    		add_to_lookup(values, "Ten");
    		add_to_lookup(values, "Jack");
    		add_to_lookup(values, "Queen");
    		add_to_lookup(values, "King");
    		add_to_lookup(values, "Ace");
    	}
    	
    private: // lookups
    	friend class Dealer;
    	friend class Game;
    	lookup suits;
    	lookup values;
    	string show_hand;
    	vector<Card> hand;
    };
    This is where I initialize the lookup table for each individual card, since I figured I would only be showing cards as output in the form of a hand it made sense for the lookup table to be here I think. I want to set it up so that after every loop of the game I can update the output system and flush the previous screen and then output everything, kindof like a 3d renderer, only for text only :d.

    Here is the IO class. This is the class that holds an output queue and will eventually manage all the output in the console app, and eventually all of the input as well.

    Code:
    class IO
    {
    	void add_output(std::string o)
    	{
    		output.push_back(o);
    	}
    
    	void display_output()
    	{
    		for(unsigned int loop = 0; loop < output.size(); loop++)
    		{
    			std::cout << output[loop].c_str() << std::endl;
    		}
    	}
    	std::vector<string> output;
    };
    I need a bit more functionality though, I suppose if I update the output vector with calls from specific game functions like draw cards and such...

    I guess the output engine needs to know what state the game is in, and then needs to know what happens in terms of game logic, and then the result. Then we can flush the vector at the end of the game loop and rebuild it.

    So yeah any suggestions? How do I keep track of what element of the output vector is what kind of output? Like if element #3 is showing the player's hand and I want to update it only how do I make sure it updates item 3 again? Or do I just rebuilt the vector from start to finish every update? I'm just not sure here.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  4. #49
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Congratulations . . . 750 posts . . . .

    If you're clearing the screen for every loop of the game loop, then you don't really need to save the output into a vector. You can just cout all of the data directly. On the other hand, if you have the ability to update certain parts of the screen (like with a cursor-moving function like gotoxy()), you can make things more efficient. Record the state of the screen as it "is", in other words how it looked when you last repainted it. Then take another data structure and record how you want the screen to look now. (You could initialize this new array to the "current" array.) Then, when you update the screen, you can write only the characters that have changed.

    I've used this approach for graphics before -- it works quite well.

    Of course, a library like ncurses does it all for you. You should seriously consider using a library. It will probably be more efficient, have more features, less bugs, and generally make your life a lot easier.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #50
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I was thinking of maybe having a static ID variable for each string I pass to the output vector, then when I want to update it it will first check to see if the id is already in the output vector, if so then just update it, if not insert the string where it should be in terms of where it should be on the screen.

    Do you think an ID for every string I push into the vector would solve my problem?

    I'm thinking about HUD's in an FPS, and how this might work in a similar way.
    Last edited by Shamino; 11-26-2007 at 10:51 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  6. #51
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    On a side note do you support the ability to double down on your bet and split the hand if you get two similar cards back to back?

  7. #52
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Nope never thought of that Bubba, I'm not really a player of blackjack, just a programmer, so I didn't know any special rules or anything, but maybe once I get the output and input working like I want I can add those things...
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  8. #53
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well in order to code it you have to understand the game a bit.

    You should also decide what number the dealer will stand on. This plays an important role in the strategy of the game.

  9. #54
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Hey Bubba, tell me more about blackjack lol, what is the betting system like? Does the dealer always stay or can he fold too? etc etc?
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  10. #55
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    here are some (copy/pasted rules) from blackjack-primer

    Code:
    Basic Rules of Blackjack
    
    The object of Blackjack is very simple: to achieve a total that is greater than that of the dealer, and which does not exceed 21. Even if other players are present at the table, the dealer is your only opponent in the game.
    
    There are relatively few decisions to make when playing Blackjack. You must consider your cards and your dealer's card and remember, if you go over 21, you "bust", and if you "bust" you lose.
    
    Play progresses as follows:
    
       1. A card is dealt, face up, to each player in turn and then one to the dealer. The dealer's card is face down and called the "hole" card.
       2. A second card is then dealt, again face up, to each player.
       3. Starting from the player to the left of the dealer, each player decides whether to draw further cards.
       4. After all players have completed their hands, the Dealer proceeds to draw cards to complete the Dealer's hand. 
    
    You win if:
    
        * Your total is higher than the Dealer's total
        * The Dealer goes over 21 or "busts". 
    
    If your total is the same as the Dealer's total it is a "stand-off" and you neither win nor lose.
    
    If you go over 21, or the Dealer's total is greater, you lose.
    
    The Values of the Cards
    
    Cards in Blackjack are assigned the following point valies:
    
        * Picture Cards (Jack, Queen and King) each count as 10 points.
        * An Ace counts as 1 point or 11 points, whichever is better for owner of the hand.
        * All other cards have their numerical face value. 
    
    Jokers are not used when playing Blackjack. (More on Card Values)
    
    What is a Blackjack?
    
    Blackjack is a combination of an Ace and any 10 or picture card with your first two cards. It pays one and a half times your bet unless the dealer also draws Blackjack, in which case you have a "stand-off". (More on Blackjack)
    
    Restrictions on the Dealer
    
    The dealer plays according to a strict set of rules. Dealers must take another card if their hand totals 16 or less. Dealers must stand (not take any more cards) if their hand totals 17 or more.
    
    Splitting
    
    If your first two cards are of equal value you may split these to form up to three separate hands. Aces may be split to form only two hands. You will receive an additional card for each hand, however a wager equal to your original bet must be placed each time you split.
    
    Casino rules vary concerning splitting hands, so check with your dealer first. (More on Splitting Pairs)
    
    Doubling Down
    
    You may place an additional bet (not exceeding your original bet) if your first two cards total 9,10 or 11 (without aces). You will be dealt one additional card when you double.
    
    Again, rules may vary at some casinos, so be sure to ask your dealer. (More on Doubling Down)
    
    Insurance
    
    If the first card dealt to the dealer is an ace, the dealer will announce "Insurance". You may then place an insurance bet of no more than half your original bet, to insure your hand should the dealer make Blackjack.
    
    An insurance bet is paid at odds of 2 to 1 and will only win if the dealer makes Blackjack. If the dealer does not make Blackjack the insurance bet is lost. (More on Insurance)

  11. #56
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    Grand realizations into the realm of OOP (LOL)

    Hey everybody, I'm trying to change up this output thing here. Right now the IO class has an IO io; in my card_game class. If I want there to only be 1 io instance running at a time for my game, I need it to be somewhere else. I want to set it up so that any event can add a string to the output queue. So I need pointers to a single IO class, where should I put it really?


    Card_Game:
    Code:
    class Card_Game
    {
    public:
    
    	Card_Game(int nplayers);
    
    	void play_game(void);
    
    private:
    
    	void initialize_players(int nplayers);
    	int blackjack();
    
    	Deck deck;
    	IO io;
    	std::vector<Player> players;
    
    };
    And trying to use it in the player class, uh oh!
    Code:
    void Player::draw(Deck & deck, int number)
    {
    	for(int loop = 0; loop < number; loop++)
    	{
    		hand->card_list.push_back(deck.cards.back());
    		deck.cards.pop_back();
    	} 
    	io.insert_output(show_hand()); // Player doesn't know what io is, because it's up there instead
    }
    This simply will not do.
    Last edited by Shamino; 12-16-2007 at 10:16 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  12. #57
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Oh, I didn't mention it before, but I changed ALOT of stuff, here is my new code structure.


    Hand:
    Code:
    • Hand(){}
    • std::string & read_cards(void);
    • int get_hand_value(void);
    • std::vector<Card> card_list;
    • std::string show_hand;


    Player
    Code:
    • Player(
    • int pid);
    • void draw(Deck & deck, int number);
    • std::string & Player::show_hand();
    • void bet(Pot & pot, int bet);
    • int playerid;
    • int cash;
    • std::string hand_string;
    • Hand * hand;

    Game
    Code:
    • Card_Game(
    • int nplayers);
    • void play_game(void);
    • void initialize_players(int nplayers);
    • int blackjack();
    • Deck deck;
    • IO io;
    • std::vector<Player> players;

    Card
    Code:
    • Card(
    • int suit, int value);
    • int get_face_value(void) const;// function to output numeric data
    • std::string get_card_name(void) const; // function to output string data
    • void initialize();
    • std::vector<std::string> suits_lookup;
    • std::vector<std::string> card_lookup;
    • std::vector<int> face_value_lookup;
    • int suit;
    • int value;
    • std::string card_name;
    • int face_value;
    Deck
    Code:
    • Deck();
    • void shuffle_deck();
    • std::vector<Card> cards;

    IO
    Code:
    • int insert_output(std::string out);
    • void display_output();
    • int get_input();
    • void clear_screen();
    • std::vector<std::string> output;
    • int input;
    • int string_id;


    So yeah, alot of updates.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Should I use a game engine in making a RPG game?
    By m3rk in forum Game Programming
    Replies: 6
    Last Post: 01-26-2009, 04:58 AM
  2. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  3. PC Game project requires c++ programmers
    By drallstars in forum Projects and Job Recruitment
    Replies: 2
    Last Post: 02-22-2006, 12:23 AM
  4. blackjack game Please, please help!!
    By collegegal in forum C Programming
    Replies: 4
    Last Post: 03-11-2002, 08:02 PM
  5. Lets Play Money Making Game
    By ggs in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 09-04-2001, 08:36 PM