Thread: Okay, so I almost made a blackjack game, then...

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    Okay, so I almost made a blackjack game, then...

    I decided to rework my engine LOL. I just started switching things around a bit to model what I think my card game engine should look like. I realize that there are a few key boolean or numerical values that may be used when working out game logic. Things such as, if all bets are going against the house (like in blackjack), or not, (like in poker).

    Here is the basis of the system, the Card_Game class.

    Code:
    #ifndef GAME_H
    #define GAME_H
    #include <vector>
    #include "Player.h"
    #include "Hand.h"
    #include "Resource_Manager.h"
    #include <list>
    
    class Card_Game
    {
    public:
    	void init();
    	void cleanup();
    
    	Card_Game();	
    
    	virtual void turn_logic(std::string player_id);
    	virtual void menu_logic();
    	std::vector<std::string> m_vPlayer_List;
    
    private:
    	int calculate_winnings();
    
    	void initialize_players()
    	{
    		for(unsigned int loop = 0; loop < m_vPlayer_List.size(); loop++)
    		{
    			Player * new_player = new Player(m_vPlayer_List[loop]);
    			m_rPlayers.manage_resource( m_vPlayer_List[loop], new_player );
    		}
    	}
    	// Give player id a new hand
    	void give_player_hand(std::string player_id)
    	{
    		Hand * p_hand = new Hand();
    		m_rHands.get_resource(player_id).px->push_back(p_hand);
    	}
    
    	void shuffle_deck(int deck_id)
    	{
    		m_vDeck[deck_id]->shuffle_deck();
    	}
    
    	// Draw how_many cards to player id's hand_id from deck_idntyd
    	void draw_card(std::string player_id, int hand_id, int deck_id, int how_many)
    	{
    		for(int loop = 0; loop < how_many; loop++)
    		{	
    			m_rHands.get_resource(player_id).px->at(hand_id)->add_card(m_vDeck[deck_id]->draw_card());
    		}
    	}
    
    	void place_bet(std::string player_id, int bet)
    	{
    		int * p_bet = &bet;
    		m_rBets.manage_resource(player_id, &(p_bet));
    		m_rPlayers.get_resource(player_id).px->m_cash -= bet;	
    	}
    	// Split player's active hand
    	void split_hand(std::string player_id, int hand_id)
    	{
    		give_player_hand(player_id);
    		m_rHands.get_resource(player_id).px->back()->add_card(m_rHands.get_resource(player_id).px->at(hand_id)->take_card());
    	}
    
    	// check if hand value > check_value
    	bool check_hand_value(std::string player_id, int hand_id, int check_value)
    	{
    		if (m_rHands.get_resource(player_id).px->at(hand_id)->point_value() > check_value)
    		{
    			return true; // hand is over check
    		}
    		else
    		{
    			return false; // hand is under check
    		}
    	}
    
    	Resource_Manager< Player > m_rPlayers;
    	Resource_Manager< std::vector<Hand*> > m_rHands;
    	Resource_Manager< int* > m_rBets;
    	Resource_Manager< Deck* > m_rDecks;
    	std::vector< Deck* > m_vDeck;	
    
    };
    #endif
    Those are all the functions I find pertinent to a blackjack card_game at this point in time, you'll notice what is missing, certain settings like the minimum bet, this internal betting switch I've told you about, and other internal switches that might be needed during runtime.

    I may use another resource manager for the job, and create another object called setting. I could derive a few types of settings like an intsetting, bool setting, etc etc.

    Then I can populate this list of settings with a virtual card_game constructor, what do you guys think about this solution?

    By the way, here is how I've defined the blackjack turn logic, its kindof incomplete at the moment still, but here it is
    Code:
    void Card_Game::turn_logic(std::string player_id)
    {
    	using namespace std;
    	while(!(cin >> m_result))
    	{
    		cin.clear();
    		cin.ignore();
    	}
    
    	switch(m_result)
    	{	
    	case 1: 
    
    		draw_card(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 0, 1);
    		if(check_hand_value(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 21))
    		{
    			m_rPlayers.get_resource(player_id).px->m_winner = false;
    		}
    		break;
    	case 2: // stay hand
    		// while dealer has hand value less than 18
    		while(check_hand_value("Dealer", 0, 18))
    		{
    			draw_card("Dealer", 0, 0, 1); // (for dealer draw to 0 hand, from 0 deck, 1 card)
    		}
    		// if the dealer goes over 21
    		if (check_hand_value("Dealer", 0, 21))
    		{
    			// player wins
    			m_rPlayers.get_resource(player_id).px->m_winner = true;
    		//	state_manager->change_state( Deal_State::instance(), game );
    		}
    		// if player's hand value is greater than the dealer's
    		else if( check_hand_value(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, m_rHands.get_resource("Dealer").px->at(0)->point_value()))
    		{
    			// player wins
    			m_rPlayers.get_resource(player_id).px->m_winner = true;
    		//	state_manager->change_state( Deal_State::instance(), game );
    		}
    		else 
    		{
    			// player loses
    			m_rPlayers.get_resource(player_id).px->m_winner = false;
    		//	state_manager->change_state( Deal_State::instance(), game );
    		}
    		break;
    		
    	case 3: // double down?
    		if (m_rHands.get_resource(player_id).px->at(m_rPlayers.get_resource(player_id).px->m_active_hand)->get_size() == 2)
    		{
    			//game->m_players[1].bet(game->m_players[1].m_bets[game->m_players[1].m_active_hand]);
    			draw_card(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 0, 1);
    
    			if( check_hand_value(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, m_rHands.get_resource("Dealer").px->at(0)->point_value()))  
    			{
    				// player wins
    				m_rPlayers.get_resource(player_id).px->m_winner = true;
    			//	state_manager->change_state( Deal_State::instance(), game );
    			}
    			else
    			{
    				// player loses
    				m_rPlayers.get_resource(player_id).px->m_winner = false;
    			//	state_manager->change_state( Deal_State::instance(), game );
    			}
    		}
    		else { break; }
    	
    	case 4:// split hand
    		split_hand(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand);
    		break;	
    	case 5: // fold
    		// player loses
    		m_rPlayers.get_resource(player_id).px->m_winner = false;
    		//state_manager->change_state( Deal_State::instance(), game );
    		break;
    	default:// invalid entry
    		cout << "Please enter 1 or 2.\n";
    		break;
    	}
    
    }
    Right now state changing has been disabled, this isn't really something I'm worried about at the moment, basically I also need to rethink what should be a gamestate and what shouldn't.
    Last edited by Shamino; 02-10-2008 at 11:03 PM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Type casting error, Card_Game * to Blackjack_Game *

    Errors, trying to derive a Blackjack_Game class from Card_Game, getting errors when passing the Blackjack_Game pointer to a function that takes a Card_Game pointer.

    Code:
    error C2243: 'type cast' : conversion from 'Blackjack_Game *' to 'Card_Game *' exists, but is inaccessible
    error C2243: 'type cast' : conversion from 'Blackjack_Game *' to 'Card_Game *' exists, but is inaccessible
    error C2243: 'type cast' : conversion from 'Blackjack_Game *' to 'Card_Game *' exists, but is inaccessible
    error C2243: 'type cast' : conversion from 'Blackjack_Game *' to 'Card_Game *' exists, but is inaccessible
    Card_Game.h:
    Code:
    class Card_Game
    {
    public:
    	Card_Game(){}
    	~Card_Game(){}
    	virtual void init(){}
    	virtual void cleanup(){}
    	virtual void turn_logic(std::string player_id);
    
    	std::vector<std::string> m_vPlayer_List;
    
    	int calculate_winnings();
    	void new_setting(std::string name, Setting * new_setting);
    	void initialize_players();
    	// Give player id a new hand
    	void give_player_hand(std::string player_id);
    	void shuffle_deck(int deck_id);
    	// Draw how_many cards to player id's hand_id from deck_idntyd
    	void draw_card(std::string player_id, int hand_id, int deck_id, int how_many);
    	void place_bet(std::string player_id, int bet);
    	// Split player's active hand
    	void split_hand(std::string player_id, int hand_id);
    	// check if hand value > check_value
    	bool check_hand_value(std::string player_id, int hand_id, int check_value);	
    
    protected:
    
    	Resource_Manager< Player > m_rPlayers;
    	Resource_Manager< std::vector<Hand*> > m_rHands;
    	Resource_Manager< int* > m_rBets;
    	Resource_Manager< Deck* > m_rDecks;
    	Resource_Manager< Setting* > m_rSettings;
    	std::vector< Deck* > m_vDeck;	
    
    };
    And Blackjack_Game.h
    Code:
    class Blackjack_Game : private Card_Game
    {
    public:
    	Blackjack_Game(){}
    	virtual void init()
    	{
    		new_setting( "Minimum Bet", new Integer_Setting(25) );
    	}
    	virtual void cleanup(){}
    	virtual void turn_logic(std::string player_id)
    	{
    		int m_result;
    		switch(m_result)
    		{
    		case 1: 
    			draw_card(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 0, 1);
    			if(check_hand_value(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 21))
    			{
    				m_rPlayers.get_resource(player_id).px->m_winner = false;
    			}
    			break;
    		case 2: // stay hand
    			// while dealer has hand value less than 18
    			while(check_hand_value("Dealer", 0, 18))
    			{
    				draw_card("Dealer", 0, 0, 1); // (for dealer draw to 0 hand, from 0 deck, 1 card)
    			}
    			// if the dealer goes over 21
    			if (check_hand_value("Dealer", 0, 21))
    			{
    				// player wins
    				m_rPlayers.get_resource(player_id).px->m_winner = true;
    				//state_manager->change_state( Deal_State::instance(), game );
    			}
    			// if player's hand value is greater than the dealer's
    			else if( check_hand_value(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 
    				m_rHands.get_resource("Dealer").px->at(0)->point_value()))
    			{
    				// player wins
    				m_rPlayers.get_resource(player_id).px->m_winner = true;
    				//state_manager->change_state( Deal_State::instance(), game );
    			}
    			else 
    			{
    				// player loses
    				m_rPlayers.get_resource(player_id).px->m_winner = false;
    				//state_manager->change_state( Deal_State::instance(), game );
    			}
    			break;
    		
    		case 3: // double down?
    			if (m_rHands.get_resource(player_id).px->at(m_rPlayers.get_resource(player_id).px->m_active_hand)->get_size() == 2)
    			{
    				//game->m_players[1].bet(game->m_players[1].m_bets[game->m_players[1].m_active_hand]);
    				draw_card(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand, 0, 1);
    
    				if( check_hand_value(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand,
    					m_rHands.get_resource("Dealer").px->at(0)->point_value()))  
    				{
    					// player wins
    					m_rPlayers.get_resource(player_id).px->m_winner = true;
    					//state_manager->change_state( Deal_State::instance(), game );
    				}
    				else
    				{
    					// player loses
    					m_rPlayers.get_resource(player_id).px->m_winner = false;
    					//state_manager->change_state( Deal_State::instance(), game );
    				}
    			}
    			else { break; }
    		case 4:// split hand
    			split_hand(player_id, m_rPlayers.get_resource(player_id).px->m_active_hand);
    			break;	
    		case 5: // fold
    			// player loses
    			m_rPlayers.get_resource(player_id).px->m_winner = false;
    			//state_manager->change_state( Deal_State::instance(), game );
    			break;
    		default:// invalid entry
    			std::cout << "Please enter 1 or 2.\n";
    			break;
    		}
    	}
    };
    Any ideas?
    Last edited by Shamino; 02-11-2008 at 09:49 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You may want to consider breaking those long lines somewhere. That will make the rest of your post more readable as well, if you don't happen to have a 19" high-spec wide-screen LCD.

    --
    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.

  4. #4
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Sorry I use high res full screen to write code, just do a little scrolly scrolly this time

    Mmk, I fixed it, I just noticed it went off the screen on my compiler too LOL
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Also interesting to see what line of code caused the erros to occure.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Ah yes how silly of me, this one here:

    Code:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	srand ( unsigned(time(NULL)) );
    	Blackjack_Game * game = new Blackjack_Game();
    	game->init();
    
    	State_Manager state_manager;
    	state_manager.change_state( Menu_State::instance(), game );
    
    	while ( state_manager.running() )
    	{
    		state_manager.update(game);
    		state_manager.print(game);
    		state_manager.handle_events(game);
    	}
    
    	game->cleanup();
    
    	return 0;
    }
    Here is that function in detail:

    Code:
    void Gamestate::change_state(State_Manager * state_manager, Gamestate * state, Card_Game * game)
    {
    	state_manager->change_state(state, game);
    }
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  7. #7
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    I fixed it, Blackjack_Game needed to use public inheritence.
    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. Oh shnap, i made a game
    By s3abass in forum C++ Programming
    Replies: 15
    Last Post: 05-11-2009, 10:33 AM
  2. Simple Blackjack Program
    By saber1357 in forum C Programming
    Replies: 1
    Last Post: 03-28-2009, 03:19 PM
  3. beach bar (sims type game)
    By DrKillPatient in forum Game Programming
    Replies: 1
    Last Post: 03-06-2006, 01:32 PM
  4. Game Designer vs Game Programmer
    By the dead tree in forum Game Programming
    Replies: 8
    Last Post: 04-28-2005, 09:17 PM
  5. BlackJack Game
    By Squintz in forum C Programming
    Replies: 3
    Last Post: 11-12-2002, 03:31 PM