Advertisement

poker game

Started by November 01, 2024 12:29 AM
175 comments, last by pbivens67 1 day, 12 hours ago

pbivens67 said:

It helps a little I just get a compiler error at the hand variable

Damn, you've said this twice, now.
This one I don't know what to say.
I use VisualStudio2022. I almost always set the C++ Language Standard to C++20 and the C Standard to C17.
Basically, bump them to the latest. I start with an Empty Project/Solution, toss on an int main() and just code from there. So, obviously configured as a console app. Nothing else that I do except set my output and intermediate directories to something that I prefer. (ie. bin and obj) But I can't see any of that being the problem.
Don't know. Maybe it's how you copy the code from github. Try copying from the raw link or download from the code button. It's said to be a bad idea to copy from the selected html.

Dev careful. Pixel on board.

Here's another one. I'll work on the rest at a later time. Chiselling away at it, so to speak.

https://github.com/sjhalayka/poker

bool is_possible_one_pair(const vector<card>& sorted_hand, const vector<card>& remaining_unflipped_cards)
{
	const size_t num_wildcards = MAX_NUM_CARDS_PER_HAND - sorted_hand.size();

	map<short unsigned int, size_t> value_counts;

	for (size_t i = 0; i < sorted_hand.size(); i++)
		value_counts[sorted_hand[i].value]++;

	for (map<short unsigned int, size_t>::const_iterator ci = value_counts.begin(); ci != value_counts.end(); ci++)
	{
		if (ci->second >= 2)
			return true;
		else if (get_value_count(ci->first, remaining_unflipped_cards) >= 1)
			return true;
	}

	// If we made it this far then we're dealing with 
	// making a pair purely out of the remaining unflipped cards
	if(num_wildcards >= 2)
	{
		value_counts.clear();

		for (size_t i = 0; i < remaining_unflipped_cards.size(); i++)
			value_counts[remaining_unflipped_cards[i].value]++;

		for (map<short unsigned int, size_t>::const_iterator ci = value_counts.begin(); ci != value_counts.end(); ci++)
			if (ci->second >= 2)
				return true;
	}

	return false;
}
Advertisement

Here is the two-pair code. I am hoping there are no bugs. @pbivens67 do you mind if I post the code here, for posterity?

bool is_possible_two_pair(const vector<card>& sorted_hand, const vector<card>& remaining_unflipped_cards)
{
	const size_t num_wildcards = MAX_NUM_CARDS_PER_HAND - sorted_hand.size();

	map<short unsigned int, size_t> value_counts;

	for (size_t i = 0; i < sorted_hand.size(); i++)
		value_counts[sorted_hand[i].value]++;

	size_t pair_count = 0;

	for (map<short unsigned int, size_t>::const_iterator ci = value_counts.begin(); ci != value_counts.end(); ci++)
	{
		if (ci->second >= 2)
			pair_count++;
		else if (get_value_count(ci->first, remaining_unflipped_cards) >= 1)
			pair_count++;
	}

	if (pair_count >= 2)
		return true;

	// If we made it this far then we're dealing with 
	// making two pair purely out of the remaining unflipped cards

	const size_t num_wildcards_needed = 2 * (2 - pair_count);

	if (num_wildcards >= num_wildcards_needed)
	{
		value_counts.clear();

		for (size_t i = 0; i < remaining_unflipped_cards.size(); i++)
			value_counts[remaining_unflipped_cards[i].value]++;

		for (map<short unsigned int, size_t>::const_iterator ci = value_counts.begin(); ci != value_counts.end(); ci++)
			if (ci->second >= 2)
				pair_count++;
	}

	if (pair_count >= 2)
		return true;

	return false;
}

@NubDevice well I finally got the flush to work YEAH!!! now I have to work on the straight

I am getting a similar problem the straight text is overwriting the high card text the problem is in the if/else statements at the bottom, here is my code

			if (player_hand.rank == 0)
			{
				if (arr[0] == 1 && arr[1] == 2 && arr[2] == 3 && arr[3] == 4 && arr[4] == 5)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 2 && arr[1] == 3 && arr[2] == 4 && arr[3] == 5 && arr[4] == 6)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 3 && arr[1] == 4 && arr[2] == 5 && arr[3] == 6 && arr[4] == 7)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 4 && arr[1] == 5 && arr[2] == 6 && arr[3] == 7 && arr[4] == 8)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 5 && arr[1] == 6 && arr[2] == 7 && arr[3] == 8 && arr[4] == 9)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 6 && arr[1] == 7 && arr[2] == 8 && arr[3] == 9 && arr[4] == 10)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 7 && arr[1] == 8 && arr[2] == 9 && arr[3] == 10 && arr[4] == 11)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 8 && arr[1] == 9 && arr[2] == 10 && arr[3] == 11 && arr[4] == 12)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 9 && arr[1] == 10 && arr[2] == 11 && arr[3] == 12 && arr[4] == 13)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}
				if (arr[0] == 10 && arr[1] == 11 && arr[2] == 12 && arr[3] == 13 && arr[4] == 1)
				{
					surface_fourteen = TTF_RenderText_Solid(font, text_seven, textColor);
					SDL_BlitSurface(surface_fourteen, NULL, gScreenSurface, &score_one);
				}

				if (flush_found == false)
				{
				surface_one = TTF_RenderText_Solid(font, text, textColor);
				SDL_BlitSurface(surface_one, NULL, gScreenSurface, &score_one);
				}
				else
				{
	   	  		surface_thirteen = TTF_RenderText_Solid(font, text_six, textColor);
				SDL_BlitSurface(surface_thirteen, NULL, gScreenSurface, &score_one);
				}
			}

http://gamedev.net/forums/topic/717647-poker-game/5467610/?page=7
Re-read that. Since you recently have a slightly better understanding of some of the things demonstrated.
Focus on trying to limit the code duplication.

Then look at this again.
http://gamedev.net/forums/topic/717647-poker-game/5467512/?page=6
Focus on the text blit happening only after your hand rank information is known

Then we'll try again.

Dev careful. Pixel on board.

Advertisement

The code is complete. It is at: https://github.com/sjhalayka/poker

Now to test it thoroughly.

Is this code appropriate for straights i have also watched a video on straights and it seems similar

 // check for straight -----------------------------------------------------------------------
   std::sort(hand->cards, hand->cards + 5, 
       [](const int& first, const int& second) -> bool
       {   // keeping connection to deck representation (handle Ace later)
           int a = first % 13;
           int b = second % 13;
           return a < b;
       }
   );
   straight_found = true; // default true for sequential test
   if ((hand->cards[4] % 13 == 12) && (hand->cards[0] % 13 == 0))
   {   // King is present. rotate Ace to the back.
       make_ace_high = true;
       std::rotate(&hand->cards[0], &hand->cards[0]+1, &hand->cards[5]);
   }
   for (int i = 0; i < 4; i++)
   {
       int a = hand->cards[i] % 13;
       int b = hand->cards[i + 1] % 13;
       if (make_ace_high)
       {
           if (a == 0) a = 13;
           if (b == 0) b = 13;
       }
       if( b - a != 1 )
       {
           straight_found = false;
       }
   }
  

yup, that's it.
Sort first.
Rotate the Ace to the back if the King is currently in the back.
That makes the Ace work as {A, 2, 3, 4, 5} or {10, J, Q, K, A}
Lastly, do a math trick accounting for Ace being 0 or 13.
The math concept is, if the cards are sequential, they will all be the value 1 more than the previous.
If this is not the case somewhere along the way, set the bool to false.

Would you agree that's a tad more elegant than if, if, if, if, if, if, if if, if, if, if….

Only after all of that would I consider drawing my text. (and in a separate draw function)
Let the work finish completely doing all the checks you want.
Then paint text based on saved results/flags that can be used/considered together.

Something else that has not been said really yet is never change the original data represented value.
If we need to morph our value like we're doing with the Ace here, do it with a temporary variable.
Same with when we pull our 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A from the deck value 1 thru 52
We let val % 13 be assigned to a temp value and work with that so we don't lose our knowledge of what suit range it is.
I like that better than having to track two elements. (The value and suit separately)
I feel it makes things easier in other places in our code and improves readability/debugging.

Dev careful. Pixel on board.

I switched to using std::random_shuffle

I fixed major bugs in :

is_possible_three_of_a_kind, is_possible_four_of_a_kind, is_possible_two_pair, is_possible_one_pair

I used the get_windows() function when calculating straights:

void get_windows(vector<window> &windows, vector<card> sorted_hand)
{
	windows.clear();

	bool is_all_five_or_less_except_ace = true;

	for (size_t i = 0; i < sorted_hand.size(); i++)
		if (sorted_hand[i].value > 5 && sorted_hand[i].value != ACE)
			is_all_five_or_less_except_ace = false;

	if (is_all_five_or_less_except_ace)
		for (size_t i = 0; i < sorted_hand.size(); i++)
			if (sorted_hand[i].value == ACE)
				sorted_hand[i].value = 1;

	short unsigned min_value = ACE + 1;
	short unsigned max_value = 0;

	for (size_t i = 0; i < sorted_hand.size(); i++)
	{
		if (sorted_hand[i].value < min_value)
			min_value = sorted_hand[i].value;

		if (sorted_hand[i].value > max_value)
			max_value = sorted_hand[i].value;
	}

	size_t spread = max_value - min_value;

	if (spread > 4)
		return;

	long signed int start_window_pos = max_value - 4;
	long signed int end_window_pos = min_value + 4 - 1;

	if (start_window_pos < 1)
		start_window_pos = 1;

	const long unsigned int initial_window_pos = start_window_pos;

	while(1)
	{
		window w;
		w.value0 = static_cast<short unsigned int>(start_window_pos);
		w.value1 = static_cast<short unsigned int>(start_window_pos) + 1;
		w.value2 = static_cast<short unsigned int>(start_window_pos) + 2;
		w.value3 = static_cast<short unsigned int>(start_window_pos) + 3;
		w.value4 = static_cast<short unsigned int>(start_window_pos) + 4;

		windows.push_back(w);

		start_window_pos++;

		if (w.value4 > end_window_pos)
			break;
	}

	//cout << "Window vector size " << windows.size() << endl;

	//for (size_t i = 0; i < windows.size(); i++)
	//	cout << windows[i].value0 << " " << windows[i].value4 << endl;

}
Advertisement