Question about engine design.
Hey fellow programmers, for a while I've been working on this Blackjack project and it seems that no matter how close to completion I come I always see design flaws in my code. Right now I have my classes setup so that the Player class owns the draw function, the betting function, and a function for splitting a hand. The deck class has a method for shuffling the deck. Basically I feel like I have a bunch of functions that might be a little out of place. Not to mention how my gamestate classes look, they're a pile of jumbled code that look like this:
Code:
void Play_State::handle_events(State_Manager * state_manager, Card_Game * game)
{
using namespace std;
while(!(cin >> m_result))
{
cin.clear();
cin.ignore();
}
switch(m_result)
{
case 1: // draw a card
game->m_players[1].draw(game->m_players[1].m_active_hand, *(game->m_deck), 1);
if (game->m_players[1].m_player_hands[game->m_players[1].m_active_hand].value() > 21)
{
game->winner() = false;
state_manager->change_state( Deal_State::instance(), game );
}
break;
case 2: // stay hand
// while dealer has hand value less than 18
while(game->m_players[0].m_player_hands[0].value() < 18)
{
// draw cards for the dealer
game->m_players[0].draw(game->m_players[0].m_active_hand, *(game->m_deck), 1);
}
// if the dealer goes over 21
if (game->m_players[0].m_player_hands[0].value() > 21)
{
// player wins
game->winner() = true;
state_manager->change_state( Deal_State::instance(), game );
}
// if player's hand value is greater than the dealer's
else if(game->m_players[0].m_player_hands[0].value() < game->m_players[1].m_player_hands[game->m_players[1].m_active_hand].value())
{
// player wins
game->winner() = true;
state_manager->change_state( Deal_State::instance(), game );
}
else
{
// player loses
game->winner() = false;
state_manager->change_state( Deal_State::instance(), game );
}
break;
case 3: // double down?
if (game->m_players[1].m_player_hands[game->m_players[1].m_active_hand].m_card_list.size() == 2)
{
game->m_players[1].bet(game->m_players[1].m_bets[game->m_players[1].m_active_hand]);
game->m_players[1].draw(game->m_players[0].m_active_hand, *(game->m_deck), 1);
if(game->m_players[0].m_player_hands[0].value() < game->m_players[1].m_player_hands[1].value())
{
// player wins
game->winner() = true;
state_manager->change_state( Deal_State::instance(), game );
}
else
{
// player loses
game->winner() = false;
state_manager->change_state( Deal_State::instance(), game );
}
}
else { break; }
case 4:// split hand
break;
case 5: // fold
// player loses
game->winner() = false;
state_manager->change_state( Deal_State::instance(), game );
break;
default:// invalid entry
cout << "Please enter 1 or 2.\n";
break;
}
}
Essentially I see alot of this code could be conformed into functions in the actual game engine (Card_Game class). I could change up my draw function to require a parameter of player, hand, and deck, and move it to the engine. I think things would be alot neater and maybe a little more logically and object oriented design wise.
Take a look at my print function for the play state, its oogly:
Code:
void Play_State::print(State_Manager * state_manager, Card_Game * game)
{
using namespace std;
cout << game->m_players[0].show_hand(0);
for( unsigned int loop = 0; loop < game->m_players[1].m_player_hands.size(); loop++)
{
cout << game->m_players[1].show_hand(loop);
}
if (game->m_betting_toggle == true)
{
cout << "The current jackpot is " << game->m_players[1].m_bets[game->m_players[1].m_active_hand] << " dollars!\n";
}
cout << "\nWhat would you like to do?\n";
cout << "1. Hit me\n";
cout << "2. Stay\n";
if (game->m_players[1].m_player_hands[game->m_players[1].m_active_hand].m_card_list.size() == 2)
{
cout << "3. Double down\n";
}
cout << "4. Fold\n";
}
Should another system entirely handle output data? Like game->output->display_hands.
Any input would be greatly appreciated!