#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LOOPS (1000) /* 試行回数 */

/* 関数のプロトタイプ宣言 */
void shuffle();
double kruskal(int);
int last_card(int);

/* J,Q,Kを何の数字とみなすかを表すフラグ定数 */
enum{
  JQK_ORIGINAL, /* 11,12,13とみなす */
  JQK_10,       /* 10とみなす */
  JQK_5         /* 5とみなす */
};

int cards[52];  /* 山札 */

int main(){
  /* 乱数の初期化 */
  srand(time(NULL));

  /* 結果の表示 */
  printf("JQK = 11,12,13 : %f%%\n", kruskal(JQK_ORIGINAL) * 100);
  printf("JQK = 10       : %f%%\n", kruskal(JQK_10) * 100);
  printf("JQK = 5        : %f%%\n", kruskal(JQK_5) * 100);

  return 0;
}

/* Kruskal count を行い最終カードが一致する確率を求める */
/* 引数には，J,Q,Kを何の数字とみなすかのフラグをとる */
double kruskal(int JQK){
  int i,j;

  /* 山札の初期化 */
  for(i=0;i<13;i++){
    for(j=0; j<4; j++){
      if(i<10){
        cards[4*i+j] = i+1;
      }else{
        switch(JQK){
          case JQK_ORIGINAL:
            /* J,Q,Kに11,12,13を割り当て */
            cards[4*i+j] = i+1;
            break;
          case JQK_10:
            /* J,Q,Kに10を割り当て */
            cards[4*i+j] = 10;
            break;
          case JQK_5:
            /* J,Q,Kに5を割り当て */
            cards[4*i+j] = 5;
            break;
        }
      }
    }
  }

  /* Kruscal count を繰り返し実行 */
  int cnt=0;  /* 最終カードが一致した回数 */
  for(i=0; i<LOOPS; i++){
    /* ランダムにnを2つ選ぶ */
    int n1 = rand()%10;
    int n2 = rand()%10;

    /* カードをシャッフル */
    shuffle();

    /* 最終カードの確認 */
    if(last_card(n1) == last_card(n2)){
      cnt++;
    }
  }

  /* 最終カードの一致確率を返す */
  return cnt * 1.0 / LOOPS;
}

/* 最終カードを求める */
int last_card(int n){
  int cur = n;
  while(cur+cards[cur] < 52){
    cur += cards[cur];
  }
  return cur;
}

/* 山札をシャッフルする */
/* Fisher-Yates シャッフルを利用 */
void shuffle(){
  int i,r,tmp;
  for(i=51;i>=1;i--){
    r = rand() % (i+1);
    tmp = cards[i];
    cards[i] = cards[r];
    cards[r] = tmp;
  }
}
