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!