---------------- 1:main.cpp ----------------

#include "Game.h"
#include "Bag.h"
#include "Ball.h"
#include <cstdlib> // srand()
#include <ctime> // time()
#include <iostream>
using namespace std;

void main()
{
    int   i;
    Game  theGame;
    Bag  *pickedBag;
    Ball *firstPickedBall, *secondPickedBall;
    int   totalCount = 0;
    int   secondIsAlsoRed = 0;

    srand(time(0));

    for (i=0; i<10000; i++)
    {
        pickedBag = theGame.getABag();
        firstPickedBall = pickedBag->getABall();
        if (firstPickedBall->isRed())
        {
            totalCount++;
            if ((secondPickedBall=pickedBag->getABall())->isRed())
                secondIsAlsoRed++;
            pickedBag->putABallBack(secondPickedBall);
        }
        pickedBag->putABallBack(firstPickedBall);
    }

    cout << "The probability that remaining ball is red = " 
         << ((double)secondIsAlsoRed/totalCount) << "\n";
}

---------------- 2:Game.h ----------------

#ifndef GAME_H
#define GAME_H

class Bag;

class Game
{
public:
    Game();
    ~Game();
    Bag *getABag(); // do not release ownership
private:
    Bag *m_bags[3];
};

#endif

---------------- 3:Game.cpp ----------------

#include "Game.h"
#include "Bag.h"
#include "Ball.h"
#include <cstdlib> // rand()

Game::Game()
{
    m_bags[0] = new Bag(Ball::Red, Ball::Red);
    m_bags[1] = new Bag(Ball::Red, Ball::White);
    m_bags[2] = new Bag(Ball::White, Ball::White);
}

Game::~Game()
{
    int i;
    for (i=0; i<3; i++)
        delete m_bags[i];
}

Bag *Game::getABag()
{
    return m_bags[rand()%3];
}

---------------- 4:Bag.h ----------------

#ifndef BAG_H
#define BAG_H

#include "Ball.h"

class Bag
{
public:
    Bag(Ball::Colors color1, Ball::Colors color2);
    ~Bag();
    Ball *getABall(); // release ownership
    void putABallBack(Ball *ball);
private:
    Ball *m_balls[2];
    int m_numberOfBalls;
};

#endif

---------------- 5:Bag.cpp ----------------

#include "Bag.h"
#include "Ball.h"
#include <cassert>
#include <cstdlib> // rand()

Bag::Bag(Ball::Colors color1, Ball::Colors color2)
    : m_numberOfBalls(2)
{
    m_balls[0] = new Ball(color1);
    m_balls[1] = new Ball(color2);
}

Bag::~Bag()
{
    delete m_balls[0];
    delete m_balls[1];
}

Ball *Bag::getABall()
{
    assert(m_numberOfBalls > 0);

    if (m_numberOfBalls == 1)
    {
        m_numberOfBalls = 0;
        return m_balls[0];
    }
    else
    {
        int iPicked = rand()%2;
        Ball *pickedBall = m_balls[iPicked];
        if (iPicked == 0)
            m_balls[0] = m_balls[1];
        m_numberOfBalls = 1;
        return pickedBall;
    }
}

void Bag::putABallBack(Ball *ball)
{
    assert(m_numberOfBalls < 2);
    m_balls[m_numberOfBalls++] = ball;
}

---------------- 6:Ball.h ----------------

#ifndef BALL_H
#define BALL_H

class Ball
{
public:
    enum Colors {Red, White};

    Ball(Colors color);
    bool isRed();
private:
    Colors m_color;
};

#endif

---------------- 7:Ball.cpp ----------------

#include "Ball.h"

Ball::Ball(Colors color)
    : m_color(color)
{
}

bool Ball::isRed()
{
    if (m_color == Red)
        return true;
    else
        return false;
}


---------------- 8:SixBall2.cpp ----------------


// Assuming there are 3 bags (each with (Red,Red), (Red,White), and (White,White))
// assuming these three bags occur uniformly, ie. each with probability 1/3

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void main()
{
    long i;
    int draw1, draw2, choice, tmp;
    long totalCount=0L, redCount=0L;

    srand(time(NULL));
    for (i=0; i<100000L; i++)
    {
        draw1 = rand() % 3; // take one kind of bags

        if (draw1 == 0) // (Red, Red)
        {
            totalCount++;
            redCount++;
        }
        else if (draw1 == 1) // (Red, White)
        {
            draw2 = rand() % 2;
            if (draw2 == 0) // the first is Red
                totalCount++;
            else // the first is White
                /* do nothing */;
        }
    }

    printf("Pr(2nd is red | 1st is red)=%lf\n", 
        (double)redCount / (double)totalCount);
}