首页 > 代码库 > Tic-A-Tac

Tic-A-Tac

image

Tic A Tac Poker是泰坦尼克号赌船里的一个游戏,给定9张牌,按照上图的形式排列,牌的位置可以随意调整,要求组合出给定的几手牌。怎么样算一手牌呢,规则如下

    三张牌组合符合以下任意情形的,可以作为一手

    顺子,同花,两对或者三条,上图中,绿色的线条可以表示可以作为一手的牌,可以看到,总共8组牌中,总共有5手牌

    怎么计算呢?直观的思维就是先列出每一种排列,然后对每一种排列进行计算,输出手数最多的那个组合。想法粗糙了一些,有没有更简单的办法呢,应该有,但是我还没有想到,所以,只能用傻一些的办法。

    在24点中,用过一种全排列的算法,那种效率相对要低下一些,这里用另外一种全排列算法。它也采用递归,但并不像前面算法需要记录那些数字可选,哪些不可选。它的基本思想是对于一个需要全排列的数组q[],从q[0]开始,按顺序选择一个数字和q[0]交换,然后以q[1]作为数组开头,按照上述的逻辑进行递归,直到程序结束。

  得到排列后,将8组牌型进行计算,得出几手,统计出最大的手数和对应的排列,最后输出取得的结果

 

程序清单

 

#include <stdio.h>
#include <string.h>

#define END_DATA     10

struct poker
{
    int cards_type;//0-3 黑桃,红心,草,方片
    int cards_num; //1-13 A-K
};
struct poker input[9] = {
    {0,6},
    {3,4},
    {1,5},
    {0,9},
    {2,12},
    {1,9},
    {0,8},
    {3,7},
    {1,8}
};
int array[10] = {0,1,2,3,4,5,6,7,8,END_DATA};
char card_type[4] = {6,3,5,4};//
char *card_num[] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
int max_hands_array[9];
int max_hands_count = 0;
//  0 -- 1 -- 2
//  | \  |  / |
//  3 -- 4 -- 5
//  |  / | \  |
//  6 -- 7 -- 8  
//将8组牌对应的牌以其序号标出
int  hand[8][3] = {
    {0,1,2},
    {3,4,5},
    {6,7,8},
    {0,3,6},
    {1,4,7},
    {2,5,8},
    {0,4,8},
    {2,4,6}
};

void print_poker(struct poker p)
{
     printf("%c",card_type[p.cards_type]);
     printf("%s",card_num[p.cards_num-1]);
}
void print_card_array(int *array)
{
    int i;
    for(i=0;i<9;i++)
    {
       if(i%3==0)  printf("\n");
       print_poker(input[array[i]]);
    }
    printf("\n");
}
int ishands(struct poker  a,struct poker b,struct poker c)
{
    int n;
    if(a.cards_num==b.cards_num||b.cards_num==c.cards_num||a.cards_num==c.cards_num) return 0; //pair
    if(a.cards_type==b.cards_type&&a.cards_type==c.cards_type) return 0;//flush
    n = (a.cards_num-c.cards_num)*(b.cards_num-c.cards_num);
    if(n==2||n==-1) //顺子
    {
        return 0;
    }
    return -1;
}
void process_hands(int *q)
{
     int i,hands=0;
     int a,b,c;
     for(i=0;i<8;i++)
     {   
         a = q[hand[i][0]];
         b = q[hand[i][1]];
         c = q[hand[i][2]];
         if(ishands(input[a],input[b],input[c])==0) hands++;
     }
     if(max_hands_count<hands)
     {
        memcpy(max_hands_array,array,sizeof(max_hands_array));
        max_hands_count = hands;
     }
}
void get_one_permutation(int *q)
{
      int i,j; //i,j是代码界的小明
      if(q[0]==END_DATA)
      {     
          process_hands(array);     
          return;
      }
      for(i=0;q[i]!=END_DATA;i++)
      {
          j = q[0];
          q[0] = q[i];
          q[i] = j;
          get_one_permutation(q+1);
          q[i] = q[0];
          q[0] = j;
      }
}
void main()
{
     get_one_permutation(array);    
     print_card_array(max_hands_array);
     printf("最大手数%d  \n",max_hands_count);
}

输出结果

image 

 

下节预告

麻将有关

Tic-A-Tac