#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SimTime 5000000

/* 0と1の間の実数乱数を発生する関数 */
double random01()
{
    return (double)rand()/((double)RAND_MAX+1);
}

void Sim(double p_a, double p_b)
{
    int a_live1 = 0; //囚人aが恩赦された回数
    int a_live2 = 0; //看守にbが処刑されると明かされた回数
    int a_live3 = 0; //看守にcが処刑されると明かされた回数
    int a_live4 = 0;
       //看守にbが処刑されると明かされて，かつ囚人aが恩赦された回数
    int a_live5 = 0;
       //看守にcが処刑されると明かされて，かつ囚人aが恩赦された回数
    char be_pardoned; //各々の試行において誰が恩赦されるか 
    char be_revealed; //看守が与える情報
    int i;
    double r;

    for(i = 0;i < SimTime;i++){
        /* 誰が恩赦されるか */
        r = random01();
        if(r <= p_a) be_pardoned = 'a';
        else if(r <= p_a+p_b) be_pardoned = 'b';
        else be_pardoned = 'c';
        
        /* 看守が与える情報(BとCのどちらが処刑される囚人か) */
        if(be_pardoned == 'a'){/* aが恩赦されるとき */
            r = random01();
            if(r <= 0.5) be_revealed = 'b';
            else be_revealed = 'c';
        }
        /* bが恩赦されるとき */
        if(be_pardoned == 'b') be_revealed = 'c';
        /* cが恩赦されるとき */
        if(be_pardoned == 'c') be_revealed = 'b';
        
        if(be_pardoned == 'a') a_live1++;
        if(be_revealed == 'b') a_live2++;
        if(be_revealed == 'c') a_live3++;
        if(be_pardoned == 'a' && be_revealed == 'b') a_live4++;
        if(be_pardoned == 'a' && be_revealed == 'c') a_live5++;
    }
    /* シミュレーションの結果出力 */
    printf("恩赦される確率: a=%f, b=%f, c=%f\n", 
                p_a, p_b, 1.0-p_a-p_b);
    printf("看守に情報を貰わなかった場合にAが助かる確率%f\n",
               (double)a_live1/(double)SimTime);
    printf("Bが処刑されると明かされた場合にAが助かる確率%f\n",
               ((double)a_live4)/(double)a_live2);
    printf("Cが処刑されると明かされた場合にAが助かる確率%f\n\n", 
               ((double)a_live5)/(double)a_live3);
}

int main()
{
    srand((unsigned)time(NULL));
    double p_a = 1.0/3;    //aが恩赦される確率
    double p_b = 1.0/3;    //bが恩赦される確率
    Sim(p_a, p_b);
    return 0;
}
