본문 바로가기

Development

Monty Hall Simulator Source Codes

/*
 Monty Hall Simulator by 3735943886
 Using Microsft Cryptography APIs for random generations
 License : GPL
*/


#include <iostream>
#include <windows.h>
#include <wincrypt.h>

#pragma comment(lib, "advapi32.lib")

using namespace std;

// Number of doors
const unsigned int MaxDoor = 3;

// Boolean flag for Host's will
const bool ExcludeCorrectDoor = false;

enum
{
    car = 0,
    guest = 1,
    host = 2,
    guest2 = 3
};

int main()
{
    // Variables for Random Numbers
    HCRYPTPROV hCryptProv;
    DWORD dwRandomNum[4];

    // Boolean flag for playing game or not
    bool Selecting = false;

    // Total number of Games
    unsigned int TryNum;

    // Number of correct answers (guest switched choice)
    unsigned int CorrectChanged = 0;

    // Number of correct answers (guest didn't switch choice)
    unsigned int CorrectUnchanged = 0;

    cout << "Monty Hall Simulator by 3735943886" << endl;
    cout << "Input : "; cin >> TryNum;

    if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0))
    {
        CorrectChanged = 0; CorrectUnchanged = 0;
        for(unsigned int i = 0; i < TryNum; i++)
        {
            Selecting = true;   // True if game is playing
            while(Selecting)
            {
                Selecting = false;

                // Generating Random Number
                if(!CryptGenRandom(hCryptProv, sizeof(dwRandomNum), (LPBYTE)dwRandomNum))
                    break;

                // Convert the random number to door number
                dwRandomNum[car] %= MaxDoor; dwRandomNum[guest] %= MaxDoor;

                if(ExcludeCorrectDoor)
                {
                    // Host doesn't select the correct door
                    if(dwRandomNum[car] == dwRandomNum[guest])
                    {
                        // If guest selected correct door
                        CorrectUnchanged++;
                    }
                    else
                    {
                        // If guest selected wrong door

                        // Host should select another door
                        dwRandomNum[host] %= (MaxDoor - 2);
                        if(dwRandomNum[host] >= dwRandomNum[car] ||
                         dwRandomNum[host] >= dwRandomNum[guest])
                            dwRandomNum[host]++;
                        if(dwRandomNum[host] >= dwRandomNum[car] &&
                         dwRandomNum[host] >= dwRandomNum[guest])
                            dwRandomNum[host]++;

                        // Guest select door again
                        dwRandomNum[guest2] %= (MaxDoor - 2);
                        if(dwRandomNum[guest2] >= dwRandomNum[guest] ||
                         dwRandomNum[guest2] >= dwRandomNum[host])
                            dwRandomNum[guest2]++;
                        if(dwRandomNum[guest2] >= dwRandomNum[guest] &&
                         dwRandomNum[guest2] >= dwRandomNum[host])
                            dwRandomNum[guest2]++;

                        // If correct,
                        if(dwRandomNum[guest2] == dwRandomNum[car])
                            CorrectChanged++;
                    }
                }
                else
                {
                    // Host doesn't know which door is correct
                    if(dwRandomNum[car] == dwRandomNum[guest])
                    {
                        // If guest selected correct door
                        CorrectUnchanged++;
                    }
                    else
                    {
                        // If guest selected wrong door,

                        // Host should select another door
                        dwRandomNum[host] %= (MaxDoor - 1);
                        if(dwRandomNum[host] >= dwRandomNum[guest])
                            dwRandomNum[host]++;

                        // If Host opened Car door, try again
                        if(dwRandomNum[host] == dwRandomNum[car])
                        {
                            Selecting = true;
                        }
                        else
                        {
                            // Guest select door again
                            dwRandomNum[guest2] %= (MaxDoor - 2);
                            if(dwRandomNum[guest2] >= dwRandomNum[guest] ||
                             dwRandomNum[guest2] >= dwRandomNum[host])
                                dwRandomNum[guest2]++;
                            if(dwRandomNum[guest2] >= dwRandomNum[guest] &&
                             dwRandomNum[guest2] >= dwRandomNum[host])
                                dwRandomNum[guest2]++;

                            // If correct,
                            if(dwRandomNum[guest2] == dwRandomNum[car])
                                CorrectChanged++;
                        }
                    }
                }
            }
        }

        cout << endl << "Total : " << TryNum << " tries" << endl;
        cout << "If the guest switched the choice : " << CorrectChanged * 100 / TryNum <<
         "% (" << CorrectChanged << "/" << TryNum << ")" << endl;
        cout << "If the guest didn't switch the choice : " << CorrectUnchanged * 100 / TryNum <<
         "% (" << CorrectUnchanged << "/" << TryNum << ")" << endl;
    }
    return 1;
}