Tic-A-Tac

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);
}

输出结果

下节预告

麻将有关

时间: 2024-10-13 22:43:38

Tic-A-Tac的相关文章

python中遍历的技巧

遍历的技巧 遍历一个序列时,使用enumerate()函数可以同时得到索引和对应的值. >>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i, v ... 0 tic 1 tac 2 toe 同时遍历两个或更多的序列,使用zip()函数可以成对读取元素. >>> questions = ['name', 'quest', 'favorite color'] >>> answers =

Python数据结构(二)

5.2. The del statement There is a way to remove an item from a list given its index instead of its value: the del statement. This differs from the pop() method which returns a value. The del statement can also be used to remove slices from a list or

从代码中学Python语法三(持续更新)

# -*- coding:utf-8 -*- from collections import deque __author__ = 'hunterhug' mylist = [2, 3, 4, 5] print(mylist) mylist.append(3) # 添加元素到链尾 print(mylist) mylist[mylist.__len__():]=[5] print(mylist) mylist.extend(mylist) # 链表叠加 print(mylist) mylist.i

【Python】Python数据结构

列表(list) list是可以修改的(字符串和Tuple则不能修改) 列表中的常用方法 list.append(x) #把x加入表尾 list.insert(i,x) #在第i个元素之前插入x list.remove(x) #删除列表中值为x的第一个元素 list.count(x) #返回x在列表中出现的次数 list.sort() #排序 list.reverse() #倒排 list.index(x) #返回列表中第一个x的索引 list.pop() #弹出最后一个元素(也可以传入参数使删

Python Tutorial 学习(五)--Data Structures

5. Data Structures 这一章来说说Python的数据结构 5.1. More on Lists 之前的文字里面简单的介绍了一些基本的东西,其中就涉及到了list的一点点的使用.当然,它可不仅仅只有那么一点点,这里给出一个更详细一点的说明.来吧骚连,打开你的命令行窗口 >>>help(list) 看看会出来一些什么~~` list.append(x) 向一个序列里面追加元素 x a = [] a.append(x) # 假设x已经定义了 a[len(a):] = [x] l

Python -- 循环技巧(Looping Techniques)

1.当想同时得到索引和对应的值时,可以用enumerate()函数 for i, v in enumerate(['tic', 'tac', 'toe']): print i, v 0 tic 1 tac 2 toe 2.要同时循环两个或多个序列,可以与zip()函数配对. questions = ['name', 'quest', 'favorite color'] answers = ['lancelot', 'the holy grail', 'blue'] for q, a in zip

python----数据结构

数据结构 列表 Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能. 以下是 Python 中列表的方法: 方法 描述 list.append(x) 把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]. list.extend(L) 通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L. list.insert(i, x) 在指定位置插入一个元素.第一个参数是准备插入到其前面的那个元素的索引,

python中常用的函数与库一

1, collections.deque 在python里如果我们用列表作为队列使用也是可以的,只是当从队尾删除或者增加元素的时候是很快的,但是从队首删除或者增加元素则要慢得多,这是因为在队首进行操作其他的元素都要逐一改变. collections.deque就是为队列设计的,它能迅速得删除或者增加元素,无论是队首还是队尾 >>> from collections import deque >>> queue = deque(["Eric", &qu

python016 Python3 数据结构

Python3 数据结构本章节我们主要结合前面所学的知识点来介绍Python数据结构. 列表Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能.以下是 Python 中列表的方法: 方法 描述 list.append(x) 把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]. list.extend(L) 通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L. list.insert(i, x