Asher Leask
Asher Leask

Reputation: 39

Game of Craps do while loop not meeting exit condition

I'm trying to simulate a game of Craps using C++ where many iterations of the game is carried out and each win, loss, and number of rolls done for each game is recorded.

Rules for each game:

Roll 2 dice and sum the result. 2, 3, or 12 = lose (1 roll), 7 or 11 = win (1 roll). If neither of these, the summed dice are rolled again until either the player rolls a 7 (loss) or rolls their original score again (win).

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<vector>    // Allows use of vectors

double random();    // Returns random double between 0 and 1
int dice(double x); // Converts a double between 0 and 1 into an int between 1 and 6
int two_dice(int die_one, int die_two); // Sums 2 ints together, in this case dice rolls


int main()
{
    // Sets the seed for rand using the current time, i.e. rand() 
    // will now always generate from a different starting point 
    std::srand(std::time(nullptr));

    // Vectors to store the results of win/lose
    std::vector<int> won;
    std::vector<int> lose;

    for (int i = 0; i < 10; i++)
    {
        int num_throws = 1;

        // Roll two dice
        double x = random(), y = random();
        int die_one = dice(x);
        int die_two = dice(y);
        int roll = two_dice(die_one, die_two);

        std::cout << "\nRoll " << i + 1 << " = " << roll << "\n";

        if (roll < 4 || roll == 12)   // Instant loss
        {
            lose.push_back(num_throws);
        }
        else if (roll == 7 || roll == 11)     // Instant win
        {
            won.push_back(num_throws);
        }
        else     // Begin looping rolls until a 7 or original roll is rolled again
        {
            int point = roll;     // First roll 
            std::cout << "Point is " << point << "\n";

            do {
                num_throws++;     
                double x = random(), y = random();
                int die_one = dice(x);
                int die_two = dice(y);
                int roll = two_dice(die_one, die_two);     // Roll dice again
                std::cout << "Next roll = " << roll << "\n";
                std::cout << "Point is " << point << "\n";
            } while (roll != 7 || roll != point);

            if (roll == 7)
            {
                lose.push_back(num_throws);
                std::cout << "lose\n";
            }
            else if (roll == point)
            {
                won.push_back(num_throws);
                std::cout << "win\n";
            }
            else
            {
                std::cout << "\n\nERROR\n\n";
            }

            std::cout << "Number of throws was " << num_throws << "\n";
        }
    }

    std::cout << "Number of throws for each win:\n";
    for (auto i: won)
        std::cout << i << "\n";

    std::cout << "\nNumber of throws for each lose:\n";
    for (auto i : lose)
        std::cout << i << "\n";

    return 0;
}

double random() // Returns random double between 0 and 1
{
    double rand_num = rand() % 1000 + 1;
    return rand_num / 1000;
}

int dice(double x)  // Converts a double between 0 and 1 into an int between 1 and 6
{
    double dice_roll = (x * 6) + 1;
    return dice_roll;
}

int two_dice(int die_one, int die_two)  // Sums 2 ints together, in this case dice rolls
{
    return die_one + die_two;
}

When running the code the do-while loop exit condition is never met, even when the roll does in fact = 7 or point. It just loops continuously. I've also tried changing int point to const int point, neither works. Does anyone know why this could be?

I know this may be over-commented but this is for the sake of anyone quickly trying to read the code, and I've included lots of print statements so you best try and work out what's not working.

Edit: my query has been solved, thanks for all the answers!

Upvotes: 0

Views: 380

Answers (1)

Clonk
Clonk

Reputation: 2070

The problem comes from this line while (roll != 7 || roll != point);.

Assuming points is not equal to 7; If roll is equal to 7 then roll != points evaluate to true and thus the loop continue. Vice versa if roll == points then roll != 7 is true and the loop continue.

Since you are testing the result after the while loop anyway, I would suggest to use a breakstatement:

do {
    num_throws++;     
    double x = random(), y = random();
    int die_one = dice(x);
    int die_two = dice(y);
    int roll = two_dice(die_one, die_two);     // Roll dice again
    std::cout << "Next roll = " << roll << "\n";
    std::cout << "Point is " << point << "\n";
    if (roll == 7)
    {
        lose.push_back(num_throws);
        std::cout << "lose\n";
        break;
    }
    else if (roll == point)
    {
        won.push_back(num_throws);
        std::cout << "win\n";
        break;
    }
} while (true);

Upvotes: 3

Related Questions