bucky
bucky

Reputation: 1

I can't figure out why this value calculates in one function but not the other

Hi I'm new and I've been working on this Blackjack program for a while now, I've been trying to make simple games like this to practice. I'm just about finished but I've run into a small problem that's been making me go crazy all night. There's a Game, Player, Deck, and Card class. I'll try to post just the relevant code, I really don't want to make it long and hard to read. I think just these functions in the Game class explain the problem.

Game.cpp:

void Game::createPlayers(int p) //creates p players and stores in players vector
{
    for (int x = 0; x < p; x++)
    players.push_back(Player(x + 1));
}

void Game::startRound() //deals 2 cards to each player and prints their hand
{

    dealer.hit(deck.draw());
    dealer.hit(deck.draw());
    cout << "Dealer's hand: " << endl << "Face down card" << endl;

    dealer.printDealer();

    for (int x = 0; x < players.size(); x++)
    {
        players[x].hit(deck.draw());
        players[x].hit(deck.draw());

        players[x].calcTotal();
        cout << "Total: " << players[x].getTotal() << endl;
        cout << "Player " << players[x].getSeat() << "'s hand:" << endl;
        players[x].printHand();
    }
}

void Game::playerChoice(Player x) //while user enters 1, keeps adding cards to hand
{
    int action = 0;
    x.calcTotal();
    if (x.getTotal() == 21)
    {
        cout << "Player " << x.getSeat() << " has a blackjack!" << endl;
        return;
    }
    else
    {
        cout << "Player " << x.getSeat() << "'s turn: 1 to hit, 2 to stay: ";
        cin >> action;
    }

    while (action == 1)
    {
        cout << endl;
        x.hit(deck.draw());
        x.calcTotal();
        x.printHand();

        if (x.getTotal() == 0)
        {
            cout << "Player " << x.getSeat() << " has busted\n\n";
            action = 2;
        }

        if (action == 1)
        {
            cout << "Enter 1 to hit again, 2 to stay: ";
            cin >> action;
        }
        cout << endl;
    }

    cout << "Player " << x.getSeat() << "'s total: " << x.getTotal() << endl;
}

void Game::collectWinnings() //compares the player's hand total to the dealer's
{
    for (int i = 0; i < players.size(); i++)
    {
            players[i].calcTotal();
        if (players[i].getTotal() > dealer.getTotal())
        {
            cout << "Player " << players[i].getSeat() << " wins." << endl;
                players[i].winBet();
        }
        else if (players[i].getTotal() < dealer.getTotal())
        {
            cout << "Player " << players[i].getSeat() << " loses." << endl;
            players[i].loseBet();
        }
        else
            cout << "Player " << players[i].getSeat() << " ties." << endl;
    }
}

I'm really sorry if it's too messy or too much. My problem is that in collectWinnings(), when I use calcTotal() then getTotal() it always returns only the total from the initial 2 cards they were given in startRound(). However, if I use calcTotal() then getTotal() at the end of playerChoice() it returns the total of the entire hand. Somehow it doesn't count the entire hand when I do it in collectWinnings(). Is there a reason for this? Am I trying to do something that C doesn't allow?

Upvotes: 0

Views: 46

Answers (1)

SleuthEye
SleuthEye

Reputation: 14579

In Game::playerChoice(Player x), you are passing Player x by value. In other words, a local copy is created for the duration of the function. As the control returns to the caller, the changes (e.g. the new cards added to the player's deck) are lost since they were not made on the original Player instance (the one stored in the players vector used in startRound() and collectWinnings()).

To avoid this problem, you could pass the Player by reference:

void Game::playerChoice(Player & x)
//                            ^^^

changes made to x are then made on the original Player instance in the caller scope. So, if you were calling playerChoice in something such as:

void Game::allPlayersChoice()
{
  for (int x = 0; x < players.size(); x++)
  {
    playerChoice(players[x]);
  }
}

Then the Player instances players[x] of the Game object would be updated. Since collectWinnings() also uses those same players[x] instances, the calls to players[i].calcTotal() in collectWinnings() would then be done on an updated Player, which would account for the entire hand.

Upvotes: 1

Related Questions