I need to write a poker game that simulates a penalty kick in a soccer match. Three cards are drawn randomly.

void DrawCard(int& numberOne, int& numberTwo, int& numberThree)
{
	RandNoGen();	//init random number generator

	numberOne = rand() % 13 + 1;	//random number in [1, 13]
	do 
	{ 
	    numberTwo = rand() % 13 + 1;
	    numberThree = rand() % 13 + 1;
	}
	while (numberOne == numberTwo);   //Their values randomly from 1 to 13, the first two values cannot be the same

	while(true)	//inner forever loop
	{	
		cout << "\nThe two goalposts are " << numberOne << " and " << numberTwo << "\n";   
		//And act as the goalposts while the third value represents the third card
		cout << "Press any key to kick action.\n";
		cin >> key;
		cout << "The third goalpost is " << numberThree << "\n";   

		if (numberOne < numberThree &&  numberThree < numberTwo || numberTwo < numberThree && numberThree < numberOne) 
		{
			cout << "Goal!! You win $" << betMoney << ".\n";
			break;
		}
			
		else if (numberThree == numberOne || numberThree == numberTwo) 
		{
			cout << "Amazing... You hit the goalpost! You lose $" << moneyLostSame << ".\n";
			break;
		}
		
		else 
		{
			cout << "Oh! It's out, you lose $" << betMoney << ".\n";
			break;
		}
	}

}

But instead of showing A, 2, ..., J, Q, K, it shows 1 to 13.
How can I convert 1, 11, 12, 13 back to A, J, Q, K?


Also, there's a Game Menu before starting the betting game.

char GameMenu()
{ 
	cout << "\n=== Penalty kick game ===\n\n";
	cout << "[r] The record of your game\n";
	cout << "[s] Start betting\n";
	cout << "[b] Back to the betting room\n";
	cout << "Enter your choice (r, s or b) :";
	cin >> secondChoice;
	return secondChoice;
}
	
void ChoiceGameMenu()
{
	while(true)
	{
		switch (GameMenu())
	    {
		    case 'r': cout << "\nNumber of times that you won: " << x << "\n";
			          cout << "Number of times that you lost: " << y << "\n";
					  break;

        	case 'R': cout << "\nNumber of times that you won: " << x << "\n";
			          cout << "Number of times that you lost: " << y << "\n";
					  break;

	        case 's': if (moneyInAccount < 100)
	                  { 
			              cout << "\nNo sufficient money to bet the game!\a\n";
	                      continue; 
		              }
	  
	                  else if (moneyInAccount >= 100)
	                  {
	                      cout << "\nPlease enter the amount of money to bet: $";
	                      cin >> betMoney;
                          
						  if (betMoney < 100)
	                      { 
				              cout << "\nA hundred dollars is minimum, please input again.\a\n";
			              }
	    
                          else if (betMoney >= 100)
                          { 
							  MoneyBet(moneyInAccount);
							  DrawCard(numberOne, numberTwo, numberThree);
						  }
					  }
 

			case 'S': if (moneyInAccount < 100)
	                  { 
			              cout << "\nNo sufficient money to bet the game!\a\n"; 
		              }
	  
	                  else if (moneyInAccount >= 100)
	                  {
	                      cout << "\nPlease enter the amount of money to bet: $";
	                      cin >> betMoney;
                          
						  if (betMoney < 100)
	                      { 
				              cout << "\nA hundred dollars is minimum, please input again.\a\n";
			              }
	    
                          else if (betMoney >= 100)
                          { 
							  MoneyBet(moneyInAccount);
							  DrawCard(numberOne, numberTwo, numberThree);
						  }
					  }

			case 'b': return;   //Back to Welcome Menu

			case 'B': return;
		
			default: cout << "\nInvalid input, please enter again!\a\a";
                     return; 
		}
	}
}

Can I make it simplier by combining small and capital letter into one option?
i.e. combining case 'b' and case 'B' together, just using one case.

I have a welcome menu before the game menu. After playing the betting game for one time, it should return to the Game Menu instead of Welcome Menu. What's wrong here?

Also, why does the betting game play for two consecutive times before return instead of one time only?

Dani AI

Generated

A few focused fixes that address the three issues seen in the thread.

Keep card values as integers and convert only when printing. The OP's AJQK() attempted to overwrite numeric game state with character literals (and also set all three cards at once), which stores ASCII codes in the ints and is why it “didn't work.” A simple helper that returns the printable label is safer and avoids changing the game state:

std::string cardLabel(int n) {
    switch (n) {
        case 1:  return "A";
        case 11: return "J";
        case 12: return "Q";
        case 13: return "K";
        default: return std::to_string(n);
    }
}

Use cout << cardLabel(numberOne) etc. If a string version of the card must be stored, keep separate std::string variables (or convert once at display time).

Normalize menu input so uppercase and lowercase are handled with one branch. Instead of duplicating case 's' and case 'S', read the char and call std::tolower() before switching:

char readMenuChoice() {
    char c; std::cin >> c;
    return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
}

Then switch(readMenuChoice()) { case 's': ... }.

Missing break; statements were the source of the two-consecutive-plays and the unexpected return. As noted, switch fall-through happens when a break is omitted; in the original code the s case fell through into the b/return case. Add break; where appropriate and only use return; in the b case if the intent is to leave the Game menu and go back to Welcome.

break vs return: break exits the innermost loop or switch and continues the current function. return exits the entire function and hands control back to the caller (so a return in ChoiceGameMenu goes back to ChoiceWelcomeMenu). To stay in the Game menu after one play, do not return from the s case — let the switch break and the menu loop continue.

Small debugging tips: seed srand() once at program start, avoid mixing cin >> and getline without cin.ignore(), and for a simple “press any key” use std::getline into a dummy string or cin.get() (watch newline handling). Credit to for suggesting an indexed lookup and to for pointing out the fall-through behavior; the helper and input-normalization above implement those ideas cleanly.

Recommended Answers

All 3 Replies

>>But instead of showing A, 2, ..., J, Q, K, it shows 1 to 13.
How can I convert 1, 11, 12, 13 back to A, J, Q, K?

You'll have to use conditionals (i.e. an "if" statement) and alter the output based on the value.

>>Can I make it simplier by combining small and capital letter into one option?
i.e. combining case 'b' and case 'B' together, just using one case.

Yes and no. You can not assign more than one value to a specific case. But, you can create more than one case and let the execution "fall through" the appropriate cases.

switch(someSelection) {
 case 1:
   //some code...
   break;
 case 2:
 case 3:
   //some more code...
   break;
 default:
   //even more code...
}

In this example, if someSelection is one (1), "some code" will execute, then when it hits the break execution will exit the switch. If some selection is either 2 or 3, "some more code" will execute instead. This works because there is no break; in case 2, so execution "falls through" to case 3 and executes case 3's code until it hits the break; .

See if you can apply this idea to your code...

>>I have a welcome menu before the game menu. After playing the betting game for one time, it should return to the Game Menu instead of Welcome Menu. What's wrong here?
You haven't posted a section of code that appears to be relevant to this question. If I had to guess, you have your main application loop messed up, you're probably calling the wrong function.

>>Also, why does the betting game play for two consecutive times before return instead of one time only?
You don't have any breaks (that I can see) in your 's' and 'S' cases. You're probably getting unintentional "fall through" (which I talked about above).

Thank you very much!
But there are some more questions.

I tried to write an 'If' statement for converting 1, 11, 12, 13 into A, J, Q, K, but it doesn't work. Do I need to use something like 'Passed by Reference' in order to achieve this?

void AJQK()
{
	if(numberOne == 1 || numberTwo == 1 || numberThree == 1)
	{
		numberOne = 'A';
		numberTwo = 'A';
		numberThree = 'A';
	}
	
	else if(numberOne == 11 || numberTwo == 11 || numberThree == 11)
	{
		numberOne = 'J';
		numberTwo = 'J';
		numberThree = 'J';
	}

	else if(numberOne == 12 || numberTwo == 12 || numberThree == 12)
	{
		numberOne = 'Q';
		numberTwo = 'Q';
		numberThree = 'Q';
	}

         	else if(numberOne == 13 || numberTwo == 13 || numberThree == 13)
	{
		numberOne = 'K';
		numberTwo = 'K';
		numberThree = 'K';
	}
}

I have tried on the suggestion on simplifying the cases and it works.


Maybe I first show the part including the Welcome Menu...

char WelcomeMenu()   //Welcome Menu
{
   cout << "\n=== Welcome to 2011 betting room ===\n\n";
   cout << "[m] Money left in your account\n";
   cout << "[p] Put money into your account\n";
   cout << "[g] Go to the Penalty Kick betting game\n";
   cout << "[q] Quit\n\n";
   cout << "Enter your choice (m, p, g or q) :";
   cin >> firstChoice;   //For user to input their choice
   return firstChoice;
}

void ChoiceWelcomeMenu()   //What will happen when choosing different choices in the Welcome Menu
{
	moneyInAccount = 1000;
	while(true)   //Inner forever loop; Unless user choose those designated options, they cannot do anything else
    {
        switch( WelcomeMenu())
		{
       		case 'm': cout << "\nMoney left in your account: $" << moneyInAccount << "\n";   //Provide options with small letter

                      break;   //exit from this loop
 
		    case 'M': cout << "Money left in your account: $" << moneyInAccount << "\n";   //Provide options with capital letter

                      break;

			case 'p': MoneyDeposit(moneyInAccount);   //Calling function
				      cout << "\nUpdated amount of money in your account: $" << moneyInAccount << "\n";  
				      break;
			
			case 'P': MoneyDeposit(moneyInAccount);
                      cout << "\nUpdated amount of money in your account: $" << moneyInAccount << "\n";        
				      break;

			case 'g': ChoiceGameMenu();
				      break;

			case 'G': ChoiceGameMenu();
                      break;

			case 'q': cout << "\nThank you for playing!";
					  cout << "\nBye Bye!\n";
					  exit(1);   //End the program
			
			case 'Q': cout << "\nThank you for playing!";
				      cout << "\nBye Bye!\n";
                      exit(1);

            default: cout << "\nInvalid input, please enter again!\a\a\n";   
			//When the user input options other than those designated, the loop will run again
		}        
    }
}

After I add in the 'break' in 's' and 'S' cases, it does return after playing for one time. But it still returns to the Welcome Menu instead of the Game Menu. Is there any problem in the loop?

Also, what is the difference between 'return' and 'break'? It seems that there is no difference between them when they are used in those loops.

>>But instead of showing A, 2, ..., J, Q, K, it shows 1 to 13.
How can I convert 1, 11, 12, 13 back to A, J, Q, K?

You'll have to use conditionals (i.e. an "if" statement) and alter the output based on the value.

I would use an array instead.
Now it's showing 1 to 13. Set up an array string cardVal[] = "A", "1", "2",... "10", "J", "Q", "K"}; and use the value that is currently being displayed as an index into the above array and print the string instead.

commented: Not a bad idea. :) +13
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.