Exemple #1
0
//=========================================================
//    フルハウス ( P6  16点 )                          
//=========================================================
int Full_house( const int hd[], int cg, int us ){
  int i, j, k;                // 反復変数
  int a, b;
  int ret = -1;
  double hand_pro[5] = {0};
  double min = 1;
  int chng_num = 0;
  struct card  deck[13] = {0};// 山札の構造体

  for( i=0; i< 4; i++ ){ deck[i].mark = 13-(sut[i] + udsut[i]); }  // (手札と捨て札から)山札のマーク残り数を求める
  for( i=0; i<13; i++ ){ deck[i].num = 4-(Num[i] + udNum[i]); }    // (手札と捨て札から)山札の数字の残り数を求める

  if( poker_point(hd) > P6 ){ return -1; }  /* 2ペア,3ペアが既に揃っている */
  if( poker_point(hd) == P0){ One_pair(hd,cg,us); } // ワンペアもできていない
  if( poker_point(hd) == P1){ Two_pair(hd,cg,us); } // ツーペアもできていない
  
  /*  以下は2ペア以上ができていれば入る */
  /*----- 既に 3枚揃っている場合 (ただ、 ツーペア以下は無視 より無意味)--------------- */
//*
  for( i=0; i<13; i++ ){
    if( Num[i] == 3 ){               // 1組目(i番目)が 3枚ある
      for( k=0; k<HNUM; k++ ){
        if( hand[k].num != i ){  // 手札中の 3枚セットの数字以外の手札を交換
          hand_pro[k] = (double)deck[hand[k].num].num/(52-us-HNUM);
        }else{
          hand_pro[k] = 1.0;
        }
      }
      for( i=0; i<HNUM; i++ ){  // 出る確率の低いマークを探す
        if( hand_pro[i] < min ){ min = hand_pro[i]; chng_num = i; }
      }
      ret = chng_num;
      return ret;
    }
  }

//*/
/*----- 2枚が2組ある場合 -------------------- */  
//*    
  for( i=0; i<13; i++ ){
    if( Num[i] == 2 ){               // 1組目(i番目の数)が 2枚ある
      for( j=i+1; j<13; j++ ){
        if( Num[j] == 2 ){           // 2組目(j番目の数)が 2枚ある
          for( k=0; k<HNUM; k++ ){
            if( hand[k].num != i && hand[k].num != j ){  // 手札中の 1組目 と 2組目 の数字以外の手札を交換
              return k;
            }
          }
        }
      }
    }
  }
  return -1;
}
Exemple #2
0
void calcexp( int hd[], int cg, int tk, int pointhd[], int pointnum, int deck[], int decknum, int recursioncount, int starthd ) {
  int nexthd[HNUM];
  int nextdeck[CNUM];
  int point = 0;
  int i, j;

  for ( i = starthd; i < HNUM; i++) {
    if ( pointnum != -1 ) {
      //printf("%d, %d, %d\n", pointnum, i, decknum);
    }
    for ( j = 0; j < CNUM; j++) {
      if ( deck[j] == 0 ) {
        arr_copy( nexthd, hd, HNUM );
        nexthd[i] = j;
        arr_copy( nextdeck, deck, CNUM );
        nextdeck[j] = -1;

        if ( pointnum == -1 ) {
          // 一手目の期待値の加算
          //pointhd[i] += poker_point(nexthd)*(decknum*(LIMIT+1-recursioncount));
          pointhd[i] += poker_point(nexthd)*decknum;
          //pointhd[i] += pointconvert(poker_point(nexthd))*decknum;
        } else {
          // 二手目以降の期待値の加算
          point = poker_point(nexthd);
          //point = pointconvert(poker_point(nexthd));

          pointhd[pointnum] += point;

          if ( pointnum < i ) {
            pointhd[i] += point;
          }
        }

        //if ( tk < 1 || tk > 3 ) { continue; }
        if ( cg > 7 - LIMIT ) { continue; }
        if ( recursioncount >= LIMIT ) { continue; }

        if ( pointnum == -1 ) {
          calcexp( nexthd, cg+1, tk, pointhd, i, nextdeck, decknum-1, recursioncount+1, i );
        } else {
          calcexp( nexthd, cg+1, tk, pointhd, pointnum, nextdeck, decknum-1, recursioncount+1, i );
        }

      }
    }
  }
}
Exemple #3
0
int strategy( const int hd[], const int fd[], int cg, int tk, const int ud[], int us) {
  int myhd[HNUM];
  int select = -1;
  int hdcopy[CNUM];
  int udcopy[us];
  int currentpoint = 0;
  int deck[CNUM] = { 0 };
  int decknum = CNUM;
  int k;
  int lastchangehd = 0;

  // 最初から高い点なら手札を変えずに終了
  arr_copy( hdcopy, hd, HNUM);
  currentpoint = poker_point(hdcopy);
  if ( currentpoint >= P6 ) { return -1; }

  arr_copy( udcopy, ud, us );
  decknum = make_deck( hdcopy, udcopy, us, deck );
  if ( tk == 4 && decknum <= 7 - cg ) {
    //LAST_RECURSION_LIMIT = decknum;
    select = select_card_last( hdcopy, cg, tk, udcopy, us, deck, decknum );
  } else {
    select = select_card( hdcopy, cg, tk, udcopy, us, deck, decknum );
  }
  return select;
  
}
Exemple #4
0
//=========================================================
//    ツーペア ( P2  2点 )                             
//=========================================================
int Two_pair( const int hd[], int cg, int us ){
  int i, j, k;       // 反復変数
  int ret = -1;
  double hand_pro[5] = {0};
  double min = 1;
  int chng_num = 0;
  struct card  deck[13] = {0};// 山札の構造体

  for( i=0; i< 4; i++ ){ deck[i].mark = 13-(sut[i] + udsut[i]); }  // (手札と捨て札から)山札のマーク残り数を求める
  for( i=0; i<13; i++ ){ deck[i].num = 4-(Num[i] + udNum[i]); }    // (手札と捨て札から)山札の数字の残り数を求める
  
  if( poker_point(hd) > P2 ){ return -1; }
  
  for( i=0; i<13; i++ ){
    if( Num[i] == 2 ){               // i番目が2枚ある
      for( k=0; k<5; k++ ){
        if( hand[k].num != i ){  // 手札中の 2枚セットの数字以外の手札を交換
          hand_pro[k] = (double)deck[hand[k].num].num/(52-us-HNUM);
        }else{
          hand_pro[k] = 1.0;
        }
      }
      for( i=0; i<HNUM; i++ ){  // 出る確率の低いマークを探す
        if( hand_pro[i] < min ){ min = hand_pro[i]; chng_num = i; }
      }
      ret = chng_num;
      return ret;
    }
  }
  return -1;
}   
Exemple #5
0
int strategy( int hd[], int fd[], int cg, int tk, int ud[], int us) {
  int myhd[HNUM];
  int select = -1;
  int point;

  int i;


  //高い役の時終了
  point = poker_point( hd ); //手札の点数
  if ( point == P9 ) { return -1; } //ロイヤルストレートフラッシュ
  if ( point == P8 ) { return -1; } //ストレートフラッシュ
  if ( point == P7 ) { return -1; } //フォーカード
  if ( point == P5 ) { return -1; } //フラッシュ
  if ( point == P6 ) { return -1; } //フルハウス
  if ( point == P4 ) { return -1; } //ストレート

  //フラッシュ     
  select = flash_judge( hd );

  if ( select != -1 ) {
    return select;
  }

  //ストレート
  select = straight( hd );
  if ( select >= 0 ) { return select; }

  //ペア  
  select = pair_count( hd );
  return select; //-1=交換を止める

  return -1;
}
Exemple #6
0
int select_card( int hd[], int cg, int tk, int ud[], int us, int deck[], int decknum ) {
  int hightexp = ( decknum > 1 ) ? poker_point(hd)*decknum*(decknum-1) : poker_point(hd)*decknum;
  int select = -1;
  int recursioncount = 1;
  int pointhd[HNUM] = { 0 }; // 期待値を格納
  int i;

  calc_exp( hd, cg, tk, pointhd, -1, deck, decknum, recursioncount, 0);

  for ( i = 0; i < HNUM; i++) {
    if ( pointhd[i] > hightexp ) {
      hightexp = pointhd[i];
      select = i;
    }
  }
  return select;
}
Exemple #7
0
int take6_hand(int hd[], int ud[], int us) {
  int i, j, k, a, b, c, d, find_flag, point; int maxpoint = 0;
  int remain_cards[25] = {-1};
  int hand_a[5]; int hand_remain[5];
  k = 0;
  for (i=0; i<51; i++) {
    find_flag = 0;
    for (j=0; j<us; j++) {
      if (ud[j] == i) { find_flag = 1; break; }
    }
    if (find_flag == 0) {
      remain_cards[k] = i; k++;
    }
  }
  for (i=0; i<k-4; i++) {
    for (j=i+1; j<k-3; j++) {
      for (a=j+1; a<k-2; a++) {
        for (b=a+1; b<k-1; b++) {
          for (c=b+1; c<k; c++) {
            hand_a[0] = remain_cards[i];
            hand_a[1] = remain_cards[j];
            hand_a[2] = remain_cards[a];
            hand_a[3] = remain_cards[b];
            hand_a[4] = remain_cards[c];
            point = poker_point(hand_a);
            if (point > maxpoint) {
              for (d=0; d<5; d++) {
                hand_remain[d] = hand_a[d];
              }
              maxpoint = point;
            }
          }
        }
      }
    }
  }
  if (maxpoint <= poker_point(hd)) { return -1; }
  for (i=0; i<HNUM; i++) {
    find_flag = 0;
    for (j=0; j<5; j++) {
      if (hd[i] == hand_remain[j]) { find_flag = 1; break; }
    }
    if (find_flag == 0) { return i; }
  }
  return -1;
}
Exemple #8
0
// テイクによる制限をかける関数 制限する必要が無いならDEFAULT_NUM(10)を返す
int limit_take(int cg, int tk, Handcard hands[], Cards remain_card, Cards hand_card, Cards deck_card, int hd[])
{
  int t;
  int k; // 反復変数
  int flag = 0; 

  if ( tk == 0 ) {
    if ( check_straight(remain_card, hand_card) >= 1 ) { flag = 1; }
    for ( k = 0; k < 4; k++ ) { if ( hand_card.sut[k] >= 4 ) { flag = 1; } }
    if ( poker_point(hd) >= P3 ) { flag = 1; }
    if ( flag == 0 ) { return -1; }
  }

  if ( tk == 1 ) {
    for ( k = 0; k < 4; k++ ) { if ( hand_card.sut[k] >= 4 ) { flag = 1; } }
    if ( check_straight(remain_card, hand_card) >= 3 ) { flag = 1; }
    if ( poker_point(hd) >= P3 ) { flag = 1; }
    if ( flag == 0 ) { return -1; }
  }

  if ( tk == 4 && deck_card.amount <= 11 ) { return -1; }
  if ( tk == 3 && deck_card.amount <= 22 ) { return -1; }
  /* if ( tk == 2 && deck_card.amount <= 33 ) { return -1; } */

  // テイクによる交換回数の制限
  if ( tk < 3 && cg >= 4 ) {
    for ( k = 0; k < 4; k++ ) {
      if ( hand_card.sut[k] >= 4 ) {
        return flush(hands, hand_card, deck_card, cg);
      }
    }
    if ( check_straight(remain_card, hand_card) >= 1 ) {
      return straight(hands, remain_card, hand_card, deck_card, cg);
    }
    if ( poker_point(hd) >= P3 ) {
      return pair(hands, hand_card, deck_card, remain_card);
    }
    return -1;
  }
  // 最後のtakeは別関数
  if ( tk == 5 ) { return final_attack(hands, remain_card, hand_card, deck_card, cg); }
  return DEFAULT_NUM;
}
Exemple #9
0
void calc_exp( int hd[], int cg, int tk, int pointhd[], int pointnum, int deck[], int decknum, int recursioncount, int starthd ) {
  int nexthd[HNUM];
  int nextdeck[CNUM];
  int point = 0;
  int i, j;

  for ( i = starthd; i < HNUM; i++) {
    for ( j = 0; j < CNUM; j++) {
      // 山札にカードがあれば
      if ( deck[j] == 0 ) {
        // 手札とデッキの複製
        arr_copy( nexthd, hd, HNUM );
        nexthd[i] = j;
        arr_copy( nextdeck, deck, CNUM );
        nextdeck[j] = -1;

        if ( recursioncount == 1 ) {
          // 一手目の期待値の加算
          pointhd[i] += point_convert(poker_point(nexthd))*decknum;
        } else {
          // 二手目の期待値の加算
          point = point_convert(poker_point(nexthd));
          pointhd[pointnum] += point;
          if ( pointnum < i ) {
            pointhd[i] += point;
          }
        }

        if ( cg > 7 - RECURSION_LIMIT ) { continue; }
        if ( recursioncount >= RECURSION_LIMIT ) { continue; }

        // 再帰呼び出し
        if ( pointnum == -1 ) {
          calc_exp( nexthd, cg+1, tk, pointhd, i, nextdeck, decknum-1, recursioncount+1, i );
        } else {
          calc_exp( nexthd, cg+1, tk, pointhd, pointnum, nextdeck, decknum-1, recursioncount+1, i );
        }
      }
    }
  }
}
Exemple #10
0
int strategy(const int hd[], const int fd[], int cg, int tk, const int ud[], int us) {
  int i, k, decide;
  int sut[4] = {0};
  int num[13] = {0};
  int usut[4] = {0};
  int unum[13] = {0};
  for ( k = 0; k < HNUM; k++ ) { i = hd[k] / 13; sut[i]++; }
  for ( k = 0; k < HNUM; k++ ) { i = hd[k] % 13; num[i]++; }
  for ( k = 0; k < us; k++ ) { i = ud[k] / 13; usut[i]++; }
  for ( k = 0; k < us; k++ ) { i = ud[k] % 13; unum[i]++; }
  if (tk == 5 && us-cg >= 37) { return take6_hand(hd, ud, us); }
  if (poker_point(hd) >= 16) { return -1; }
  if (poker_point(hd) >= 8 && tk < 4) { return -1; }
  decide = flashreach(hd, sut, usut);
  if (decide != -1) {
    return decide;
  }
  decide = straight(hd, num, unum, sut, usut);
  if (decide != -1) {
    return decide;
  }
  if (tk < 2) { return -1; }
  decide = flash(hd, num, unum, sut, usut);
  if (decide != -1) {
    return decide;
  }
  if (tk == 4 && 52-5-us <= 11) {
    return -1;
  }
  if (tk == 3 && 52-5-us <= 22) {
    return -1;
  }
  decide = pair(hd, num, unum,sut);
  if (decide != -1) {
    return decide;
  }
  return -1;
}
Exemple #11
0
//=========================================================
//    スリーカインズ ( P3  8点 )                      
//=========================================================
int Three_of_a_kind( const int hd[], int cg, int us ){
  int i, j;    // 反復変数
  
  if( poker_point(hd) > P3 ){ return -1; }

  for( i=0; i<13; i++ ){                  // 2枚1組 の数字を探す
    if( Num[i] == 2 ){ break; }           // i番目の手札が 2枚1組 になっている
  }
  
  for( j=0; j<5; j++ ){                   // 小さい数字から手札の番号を導く
    if( hand[j].num == i ){ return j; }
  }

  return -1;
}    
Exemple #12
0
int final_attack(Handcard hd[], Cards remain_card, Cards hand_card, Cards deck_card, int cg)
{
  int k1;
  int len = 0;
  int flag;
  int disc_num;
  int hand[HNUM]; // 特別  役判定に用いる
  
  // 判定用の手札を作成
  for ( k1 = 0; k1 < HNUM; k1++ ) { hand[k1] = hd[k1].num_val; }

  // ロイヤルストレート
  if ( poker_point(hand) >= P9 ) { return -1; }
  disc_num = royal_straight_flush(hd, remain_card, deck_card, cg);
  if ( disc_num != -1 ) { return disc_num; }

  // ストレートフラッシュ
  if ( poker_point(hand) >= P8 ) { return -1; }
  disc_num = straight_flush(hd, hand_card, deck_card, cg);
  if ( disc_num != -1 ) { return disc_num; }

  // フォーカード
  if ( poker_point(hand) >= P7 ) { return -1; }
  disc_num = four_of_a_kind(hd, remain_card, hand_card, deck_card, cg);
  if ( disc_num != -1 ) { return disc_num; }

  // ストレート
  flag = 0;
  if ( poker_point(hand) >= P4 ) { return -1; }
  for ( k1 = 0; k1 < 13; k1++ ) {
    if ( remain_card.num[k1] >= 1 ) { len++; }
    else { len = 0; }
    if ( len >= 5) { flag = 1; }
  }
  if ( flag ) { return straight(hd, remain_card, hand_card, deck_card, cg); }

  flag = 0;
  // フラッシュ
  if ( poker_point(hand) >= P5 ) { return -1; }
  for ( k1 = 0; k1 < 4; k1++ ) {
    if ( remain_card.sut[k1] >= 5 ) { flag = 1; }
  }
  if ( flag ) {
    disc_num = flush(hd, hand_card, deck_card, cg);
    return disc_num;
  }
  // フルハウス ペア系
  if ( poker_point(hand) >= P6 ) { return -1; }
  for (k1 = 0; k1 < HNUM; k1++ ) {
    if ( remain_card.num[hd[k1].num] == 1 ) { return k1; }
  }
  for (k1 = 0; k1 < HNUM; k1++ ) {
    if ( remain_card.num[hd[k1].num] == 2 ) { return k1; }
  }
  return disc_num;
}
Exemple #13
0
int poker_take(const int stock[], int tk, int used[], int *us)
{
  //----  局所変数
  int field[FNUM];            // 場札
  int hand[HNUM];             // 手札
  int state[CHNG+1][HNUM];    // 局面(手札の列)
  int ope[CHNG];              // 打手札
  int the;                    // 打手
  int cg;                     // チェンジ回数
  int take_p;                 // テイク得点
  int k;                      // 反復変数

  //----  テイクの準備
  if ( *us +5 < CNUM ) {
    arr_copy(hand, &stock[*us], HNUM); // 手札の配布(5枚)
    arr_copy(state[0], hand, HNUM);    // 局面の記録
  } else {
    return 0;
  }

  //----  テイクの最中(チェンジの繰返し)
  for ( cg = 0; cg < CHNG; cg++ ) {
    if ( *us < CNUM-5 ) {
      the = strategy(hand, field, cg, tk, used, *us);  // 戦略により捨札を決定
    } else {
      the = -1; break;
    }
    ope[cg] = hand[the];                  // 打手札の記録
    if ( the < 0 ) { break; }             // 手札を交換せずにテイク終了
    field[cg] = ope[cg];                  // 捨札を場札に追加
    used[(*us)++] = ope[cg];              // 捨札を捨札配列に追加
    hand[the] = stock[HNUM-1+(*us)];      // 手札を交換
    arr_copy(state[cg+1], hand, HNUM);    // 局面の記録
  }

  //----  テイクの後処理
  take_p = poker_point(hand);                 // テイク得点

  for ( k = 0; k < HNUM; k++ ) {
    used[*us] = hand[k];                      // 手札を捨札配列に追加
    (*us)++;
  }

  //----  テイクの経過表示
  if ( Disp_Mode ) { take_show(state, ope, field, cg, take_p); }

  return take_p;
}
Exemple #14
0
//=========================================================
//    フラッシュ ( P5  24点 )                              
//=========================================================
int Flush( const int hd[], int cg, int us ){
  int target;                 // 対象とするマーク(SHDC)
  struct card  deck[13] = {0};// 山札の構造体
  double Mark[4] = {0};       // 各マークの出る確率(0=S 1=H 2=D 3=C)
  double hand_pro[5] = {0};   // 各手札のマークの出る確率(1枚目,2枚目,...)
  double min = 1;             // 最小値を格納
  int chng_mark = 0;          // 捨てるマーク
  int sut_max = 0;            // 手持ちカードの最大組のマークを示す
  int ret=0;                  // 交換するカード
  int i, j;                   // 反復変数
  int a, b;                   // 一時変数
  
  if( poker_point(hd) >= P5 ){ return -1; }
  
  for( i=0; i< 4; i++ ){ deck[i].mark = 13-(sut[i] + udsut[i]); }  // (手札と捨て札から)山札のマーク残り数を求める
  
  for( i=0; i<HNUM; i++ ){
    if( CHNG-cg < HNUM-sut[i] || deck[hand[i].mark].mark == 0 ){ // 残りチェンジ数が必要枚数よりも多い場合 か 山札に対象マークカードがない
      hand_pro[i] = 0;
    }else{
      a = Combi( deck[hand[i].mark].mark, HNUM - sut[hand[i].mark] );  // 13C4 など 13枚のうち、5枚に足りない4枚が出る確率を求める
      b = Combi( (52-us-HNUM), HNUM - sut[hand[i].mark] );             // 山札の中から 5枚に足りない4枚が出る確率を求める
      hand_pro[i] = (double)a/b;
    }
  }
  
  for( i=0; i<4; i++ ){       // 手札の中からマークの数が最大の物を探す
    if( sut_max < sut[i] ){
      sut_max = sut[i];
      target = i;
    }
  }

  if( sut[target] == 2 || sut[target] == 3 || sut[target] == 4 ){  // 既に出来ているペアは(確率を最大にして)崩さない
    for( j=0; j<HNUM; j++ ){
      if( hand[j].mark == target ){
        hand_pro[j] = 1.0;
      }
    }
  }

  for( i=0; i<HNUM; i++ ){  // 出る確率の低いマークを探す
    if( hand_pro[i] < min ){ min = hand_pro[i]; chng_mark = i; }
  }
  ret = chng_mark;

  return ret;
}
Exemple #15
0
int select_card_last( int hd[], int cg, int tk, int ud[], int us, int deck[], int decknum ) {
  int hightexp = poker_point(hd);
  int exp;
  int select = -1;
  int recursioncount = 1;
  int i;

  for ( i = 0; i < HNUM; i++ ) {
    MAX_EXP = 0;
    seek_hightest( hd, cg, tk, i, deck, recursioncount);
    if ( hightexp < MAX_EXP ) {
      hightexp = MAX_EXP;
      select = i;
    }
  }
  MAX_EXP = hightexp;

  return select;
}
Exemple #16
0
int strategy( const int hd[], const int fd[], int cg, int tk, const int ud[], int us) {
  int myhd[HNUM];
  int select = -1;
  int hdcopy[CNUM];
  int udcopy[us];
  int currentpoint = 0;
  int deck[CNUM] = { 0 };
  int decknum = CNUM;
  int k;

  // 最初から高い点なら手札を変えずに終了
  arr_copy( hdcopy, hd, HNUM);
  currentpoint = poker_point(hdcopy);
  if ( currentpoint >= P6 ) { return -1; }

  arr_copy( udcopy, ud, us );
  decknum = makedeck( hdcopy, udcopy, us, deck );
  select = selectcard(hdcopy, cg, tk, udcopy, us, deck, decknum );
  return select;
}
Exemple #17
0
void seek_hightest( int hd[], int cg, int tk, int changecard, int deck[], int recursioncount ) {
  int nexthd[HNUM];
  int nextdeck[CNUM];
  int currentpoint;
  int i, k;

  for ( i = 0; i < CNUM; i++) {
    if ( deck[i] == 0 ) {
      arr_copy( nexthd, hd, HNUM );
      nexthd[changecard] = i;
      arr_copy( nextdeck, deck, CNUM );
      nextdeck[i] = -1;
      currentpoint = poker_point(nexthd);
      if ( currentpoint > MAX_EXP ) { MAX_EXP = currentpoint; }

      if ( cg > 7 - LAST_RECURSION_LIMIT ) { continue; }
      if ( recursioncount >= LAST_RECURSION_LIMIT ) { continue; }
      for ( k = 0; k < HNUM; k++ ) {
          seek_hightest( nexthd, cg+1, tk, k, nextdeck, recursioncount+1 );
      }
    }
  }
}
Exemple #18
0
int strategy(const int hd[], const int fd[], int cg, int tk, const int ud[], int us)
{
  int disc_num;  // 捨てるカードの番号(-1:捨てない)
  int t;
  int k, k1, k2; // 反復変数
  Handcard hands[5]; // 手札を保管
  Cards hand_card, deck_card, remain_card;

  // 手札の情報を格納
  for (k1 = 0; k1 < HNUM; k1++ ) {
    hands[k1].num_val = hd[k1];
    hands[k1].num     = hd[k1] % 13;
    hands[k1].sut     = hd[k1] / 13;
    hands[k1].pos     = k1;
    for ( k2 = 0; k2 < 11; k2++ ) { hands[k1].exp[k2] = 0; }
  }
  calc_card(hands, &remain_card, &deck_card, &hand_card, ud, us);
  //フルハウス以上は確定
  if ( tk != 5 && poker_point(hd) >= P6 ) { return -1; }

  disc_num = limit_take(cg, tk, hands, remain_card, hand_card, deck_card, hd);  if ( disc_num != DEFAULT_NUM ) { return disc_num; }
  // ストレートリーチならストレートを狙う
  if ( check_straight(remain_card, hand_card) >= 1 ) {
    return straight(hands, remain_card, hand_card, deck_card, cg);
  }
  // フラッシュリーチならフラッシュを狙う
  for (k1 = 0; k1 < HNUM; k1++ ) {
    if ( hand_card.sut[k1] >= 4 && deck_card.sut[k1] >= 2 ) {
      return flush(hands, hand_card, deck_card, cg);
    }
  }
  /* // 3カード以上ならペア系を狙う */
  if ( poker_point_pair(hand_card.num) == P3 ) {
    return pair(hands, hand_card, deck_card, remain_card);
  }
  return decide_discard(hands, remain_card, hand_card, deck_card, cg, tk);
}
Exemple #19
0
//=========================================================
//    ファイナル                                           
//=========================================================
int Final( const int hd[], int cg, int us  ){
  struct card  deck[13] = {0};       // 山札の構造体
  int i, j, k, l, m, n;              // 反復変数
  int flag[5] = {0};                 // 返却カード管理フラグ
  int max_point = 0;
  struct card  mer_deck[13] = {0};   // 山札と手札を合わせた構造体
  struct card  ideal_hand[5]= {0};   // 理想手札の構造体
  int  vir_hand[5]  = {0};           // 仮想手札の構造体
  int  vir_deck[52] = {0};           // 仮想山札
  int deck_max = 0;                  // 仮想山札の最大数    
  
  for( i=0; i< 4; i++ ){ deck[i].mark = 13-(sut[i] + udsut[i]); }  // (手札と捨て札から)山札のマーク残り数を求める
  for( i=0; i<13; i++ ){ deck[i].num = 4-(Num[i] + udNum[i]); }    // (手札と捨て札から)山札の数字の残り数を求める

  for( i=0; i< 4; i++ ){ mer_deck[i].mark = deck[i].mark + sut[i] ; } // 山札と手札を合わせる(マーク)
  for( i=0; i<13; i++ ){ mer_deck[i].num  = deck[i].num  + Num[i] ; } // 山札と手札を合わせる(数字)
  
  for( j=0, i=0; i<52; i++ ){       // 仮想山札に捨て札から計算したカード追加
    if( deck_flg[i] == 0 ){
      vir_deck[j] = i;
      j++;
    }
  }
  
  for( i=0; i<HNUM; i++ ){     // 仮想山札に手札から計算したカード追加
      vir_deck[j] = hand[i].orig;
      j++;
  }
  
//  for( i=0; i<HNUM; i++ ){ printf("hand[%d].orig = %d\n",i ,hand[i].orig ); }
//  for( i=0; i<j; i++ ){ printf("●vir_deck[%d]  = %d\n", i, vir_deck[i] );}
  
  deck_max = j;
  max_point = 0;
  for( i=0; i<deck_max-4; i++ ){
    for( j=i+1; j<deck_max-3; j++ ){
      for( k=j+1; k<deck_max-2; k++ ){
        for( l=k+1; l<deck_max-1; l++ ){
          for( m=l+1; m<deck_max; m++ ){
            vir_hand[0] = vir_deck[i];
            vir_hand[1] = vir_deck[j];
            vir_hand[2] = vir_deck[k];
            vir_hand[3] = vir_deck[l];
            vir_hand[4] = vir_deck[m];
            if( max_point < poker_point(vir_hand) ){
              max_point = poker_point(vir_hand);
              ideal_hand[0].orig = vir_hand[0]; // printf("i=%d  ",i );
              ideal_hand[1].orig = vir_hand[1]; // printf("j=%d  ",j );
              ideal_hand[2].orig = vir_hand[2]; // printf("k=%d  ",k );
              ideal_hand[3].orig = vir_hand[3]; // printf("l=%d  ",l );
              ideal_hand[4].orig = vir_hand[4]; // printf("m=%d  \n",m );
            }
          }
        }
      }
    }
  }

  for( i=0; i<HNUM; i++ ){
    ideal_hand[i].mark = ideal_hand[i].orig/13;
    ideal_hand[i].num  = ideal_hand[i].orig%13;
  }

  /* 仮想手札に近づくように切る(仮想手札以外のものを切る) */
  
  for( i=0; i<HNUM; i++ ){
    for( j=0; j<HNUM; j++ ){
      if( hand[i].orig == ideal_hand[j].orig ){  // 理想手札のi番目と同じものがある = flag = 1
        flag[i] = 1;
      }
    }
  }

  for( i=0; i<HNUM; i++ ){
    if( flag[i] == 0 ){ return i; }
  }
  
  return -1;
}
Exemple #20
0
/*
    i|0 1 2 3 4 5 6 7 8 9 10 11 12  13
    -----------------------------------
     |A 2 3 4 5 6 7 8 9 T  J  Q  K  A
*/     
int Straight( const int hd[], int cg, int us ){
  int i, j,k;                  // 反復変数
  int a,b,c;                   // 計算に使う一時変数
  int chng=-1;                 // 交換するnum
  int ret = -1;
  struct card  deck[14] = {0}; // 山札の構造体
  double deck_pro[14] = {0};   // デッキからストレートのできる各々のnumの確率 deck_pro[0] = A = deck_pro[13]
  double hand_pro[13] = {0};   // 手札のカードの確率
  double min =100;
  int count = 0;
  int tmp1, tmp2;
  
  if( poker_point(hd) >= P4 ){ return -1; }
/*----- 事前処理--------------------- -------------------- */
  for( i=0; i< 4; i++ ){ deck[i].mark = 13-(sut[i] + udsut[i]); }  // (手札と捨て札から)山札のマーク残り数を求める
  for( i=0; i<13; i++ ){ deck[i].num = 4-(Num[i] + udNum[i]); }    // (手札と捨て札から)山札の数字の残り数を求める
  deck[13].num = deck[0].num;
  
  //------------------------ 手札に同じ数字がある場合、山札に多い方を残す
  for( i=0; i<4; i++ ){
    if( 1 < Num[i] ){           // 同じ数字が2枚ある場合
      for( j=0; j<HNUM; j++){
        if( hand[j].num == i ){  tmp1 = j; break;}         // 数字からマークを調べる
      }
      for( k=0; k<HNUM; k++){
        if( hand[k].num == i && tmp1 != k ){ tmp2 = k; }   // 数字からマークを調べる
      }
      if( deck[tmp1].num < deck[tmp2].num ){               // 手札の tmp1 番目 と tmp2 番目が同じ数字 残りマークの少ない方を捨てる
        return tmp1;
      }else{
        return tmp2;
      }
    }
  }

  //------------------------
  for( i=0; i<HNUM; i++ ){
    for( j=0; j<14; j++ ){
      if( hand[i].num != j && flg[j] != -1 ){    // 手札にあるものは -1 とする
        flg[j] = deck[j].num;
      }else{
        flg[j] = -1;
      }
    }
  }
  flg[13] = flg[0];


  for( i=0; i<14-4; i++ ){          // 5つの塊で見ていく
    a = 1;
    count = 0;
    for( j=i; j<i+HNUM; j++ ){
      if( flg[j] != -1 && flg[j] != 0 ){  // 手札にない かつ 山札の枚数が 0でない
        a *= flg[j];          // 手札にないカードについて確率の一部分を求める
        count++;
      }
    }
    b = Permu( (52-HNUM-us)-count, count);
    c = Permu( 52-HNUM-us, CHNG-cg );
    
    for( k=i; k<i+HNUM; k++ ){
      deck_pro[k]   += (double)(a*b)/c;
    }  
  }    
  deck_pro[0] += deck_pro[13];  // AとKの後のAは同じため
    

  // 捨てる捜索範囲は i=0 i<13 まで 仮想Aは 含めない
  // 手札の番号について確率を格納し、その5つの中から比較する。
  for( i=0; i<13; i++ ){
    for( j=0; j<HNUM; j++ ){
      if( i == hand[j].num ){
        hand_pro[i] = deck_pro[i];
      }
    }
  }

  
  // 確率が最小のものを探す。
  for( i=0; i<13; i++ ){
    if( hand_pro[i] < min && hand_pro[i] != 0 ){
      min = hand_pro[i];
      chng = i;
    }
  }

  // 手札から交換対象 chng を探す
  for( i=0; i<HNUM; i++ ){
    if( hand[i].num == chng ){
      ret = i;
    }
  }
  
  return ret;
}
Exemple #21
0
//====================================================================
//  補助関数
//====================================================================
//=========================================================
//    フォーカード ( P7  64点 )                            
//=========================================================
int Four_of_a_kind( const int hd[], int cg, int us ){
  int i, j;                     // 反復変数
  int num_min;                  // とりあえず宣言しただけなので使うときに確認を!
  int target;                   // 対象とする数字
  struct card  deck[13] = {0};  // 山札の構造体
  int ret  = -1;
  int ret2 = -1;
  int tmp1 = -1, tmp2 = -1;
  
  if( poker_point(hd) > P7 ){ return -1; }  
  
  for( i=0; i< 4; i++ ){ deck[i].mark = 13-(sut[i] + udsut[i]); }  // (手札と捨て札から)山札のマーク残り数を求める
  for( i=0; i<13; i++ ){ deck[i].num = 4-(Num[i] + udNum[i]); }    // (手札と捨て札から)山札の数字の残り数を求める

  // ここに来たときは既に3枚1組がある状態 で進めていく
  
  // 対象となる数字を見つける
  for( i=0; i<13; i++ ){
    if( Num[i] == 3 ){
      target = i;
    }
  }
   
  // 山札に必要な残りの数字が有るか確認 なければフルハウスへ変更
  if(  deck[target].num < 1 ){ return Full_house(hd,cg,us); }
  
  
  for( i=0; i<13; i++ ){                  // フォーカードができると仮定して 捨てる 1組 or 2組 の数字を探す
    if( Num[i] == 1 || Num[i] == 2 ){
      tmp1 = i;
      for( j=i+1; j<13; j++){
        if( Num[j] == 1 || Num[j] == 2 ){
          tmp2 = j;
          break;
        }
      }
    }
  }
  
  if( tmp2 != -1 ){
    if( deck[tmp1].num < deck[tmp2].num ){                       // 山札に残っている数字の枚数が少ない方を捨てる
      ret =tmp1;
    }else if( deck[tmp2].num < deck[tmp2].num ){
      ret = tmp2;
    }else if( deck[tmp1].num == deck[tmp2].num ){
      if( deck[hand[tmp1].mark].mark < deck[hand[tmp2].mark].mark ){  // 山札に少ないマークを捨てる
        ret = tmp1;
      }else{
        ret = tmp2;
      }
    }
    for( i=0; i<HNUM; i++ ){
      if( hand[i].num == ret ){ return i; }
    }
  }else { // tmp2 = -1 のとき すなわち 2枚1組だった場合 (AAA55)など
    for( i=0; i<HNUM; i++ ){
      if( hand[i].num =! target ){
        for( j=i+1; j<HNUM; j++ ){
          if( hand[i].num != target ){
            if( deck[hand[i].mark].mark < deck[hand[j].mark].mark ){  // 山札に少ないマークを捨てる
              return i;
            }else{
              return j;
            }
          }
        }
      }
    }
  }
  /* 手札から数字を探す */
  
  return ret2;
}