[swustoj 1088] 德州扑克

德州扑克(1088)

问题描述

德州扑克是一款风靡全球的扑克游戏。德州扑克一共有52张牌,没有王牌。每个玩家分两张牌作为“底牌”,五张由荷官陆续朝上发出的作为公共牌。开始的时候,每个玩家会有两张面朝下的底牌。经过所有押注圈后,若仍不能分出胜负,游戏会进入“摊牌”阶段,也就是让所剩的玩家亮出各自的底牌以较高下,持大牌者获胜。因技巧性强,易学难精又被称为“扑克游戏中的凯迪拉克”。

现在有N个玩家进入摊牌阶段(编号为1到N),摊牌阶段比大小的规则是,用自己的2张底牌和5张公共牌结合在一起,选出5张牌,不论手中的牌使用几张(甚至可以不用手中的底牌),凑成最大的成牌,跟其他玩家比大小。比牌先比牌型,大的牌型大于小的牌型,牌型一般分为10种,从大到小为:

1.皇家同花顺:最高为Ace(一点)的同花顺。

如A K Q J 10 的同花顺

2.同花顺:同一花色,顺序的牌。

如:K Q J 10 9 的同花顺

3.四条:有四张同一点数的牌。

如:4 4 4 4 9

4.葫芦:三张同一点数的牌,加一对其他点数的牌。

如:3 3 3 10 10

5.同花:五张同一花色的牌。

如:J 10 8 7 5 的全是红桃的牌

6.顺子:五张顺连的牌。

如:5 4 3 2 A 的非同花牌(此牌型为最小的顺子)

7.三条:仅有三张同一点数的牌,其余两张点数不同。

如: 9 9 9 5 3

8:两对:两张相同点数的牌,加另外两张相同点数的牌。

如:K K 5 5 2

9.一对:仅有两张相同点数的牌。

如:10 10 9 4 2

10.高牌:不符合上面任何一种牌型的牌型,由单牌且不连续不同花的组成,以点数决定大小。

如:A 10 9 5 3 的非同花的牌

点数大小为A>K>Q>J>10>9>8>7>6>5>4>3>2,

若两个牌牌型相同,则比较点数,点数比较为从两副牌最大的牌到最小的牌依次开始比较大小,若出现某张牌大于对手的牌,则获胜。如A 8 7 4 2和A 6 5 3 1,先比较最大的,两幅都是A,继续比较次大的,8>7,则第一副牌获胜。(顺子5 4 3 2 A特判)

若两副牌大小相同,则他们同时获胜。

现在问这N个玩家哪些玩家获胜。(牌最大)

输入

多组测试数据,每组先输入N(2<=N<=10),代表玩家个数,接下来N行,每行4个数据X1i C1i X2i C2i,X1i,C1i表示第i个玩家的第一张牌,X1i表示牌的点数(A,2,3到K),C1i表示花色(S表示黑桃,H表示红心,C表示草花,D表示方片),同理X2i C2i表示第二张牌。然后是10个数据X1C,C1C......X10C,C10C。表示5张公共牌。

输出

第一行输出获胜玩家的个数,第二行输出获胜玩家的编号(由小到大)。

样例输入

3
A H A S
2 H 3 H
4 C 5 D
A D A C 4 H 5 H 6 H
2
A H A S
A C A D
5 D 6 C 7 D 8 H 10 C

样例输出

1
2
2
1 2

疯狂地模拟、不要问为什么、不会、贴个代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define N 15

struct Card
{
    int point;//点数,颜色
    char color;
};

struct Maxcard
{
    int point[5];//点数
    int flag;//牌型
}maxcard[N];

Card card[5];
Card Pcard[N][2];
Card Ccard[5];
int n;

bool cmp(Card a,Card b)
{
    return a.point>b.point;
}

void init()//把每个选手的最大牌先初始化为最小
{
    for(int i=0;i<n;i++)
    {
        maxcard[i].flag=10;
        maxcard[i].point[0]=7;
        maxcard[i].point[1]=5;
        maxcard[i].point[2]=4;
        maxcard[i].point[3]=3;
        maxcard[i].point[4]=2;
    }
}

int getp(char p[])
{
    int pp;
    if(strcmp(p,"10")==0)pp=10;
    else if(p[0]>=‘2‘&&p[0]<=‘9‘)pp=p[0]-‘0‘;
    else if(p[0]==‘J‘)pp=11;
    else if(p[0]==‘Q‘)pp=12;
    else if(p[0]==‘K‘)pp=13;
    else pp=14;
    return pp;
}

Maxcard gettype(Card select[5])
{
    sort(select,select+5,cmp);
    bool samec=true;
    bool isstr=true;
    int i;
    for(i=1;i<5;i++)//判断同花和顺子
    {
        if(select[i].color!=select[i-1].color)samec=false;
        if(select[i].point!=select[i-1].point-1)isstr=false;
    }
    if(select[0].point==14&&select[1].point==5&&select[2].point==4&&select[3].point==3&&select[4].point==2)//A2345的情况
    {
        isstr=true;
        for(i=0;i<4;i++)select[i].point=select[i+1].point;
        select[4].point=1;
    }
    Maxcard ret;
    for(i=0;i<5;i++)ret.point[i]=select[i].point;
    int vis[15]={0};
    int maxsame=0,secsame=0,maxi;
    for(i=0;i<5;i++)
    {
        vis[ret.point[i]]++;
        if(vis[ret.point[i]]>maxsame)maxsame=vis[ret.point[i]],maxi=ret.point[i];
    }
    for(i=1;i<=14;i++)
    {
        if(maxi!=i&&vis[i]>secsame)secsame=vis[i];
    }
    if(samec&&isstr)ret.flag=2;//同花顺
    else if(maxsame==4)ret.flag=3;//四条
    else if(maxsame==3&&secsame==2)ret.flag=4;//葫芦
    else if(samec)ret.flag=5;//同花
    else if(isstr)ret.flag=6;//顺子
    else if(maxsame==3)ret.flag=7;//三条
    else if(maxsame==2&&secsame==2)ret.flag=8;//两对
    else if(maxsame==2)ret.flag=9;//一对
    else ret.flag=10;//高牌
    return ret;
}

int biger(Maxcard a,Maxcard b)
{
    if(a.flag<b.flag)return 1;
    else if(a.flag>b.flag)return -1;
    else
    {
        for(int i=0;i<5;i++)
        {
            if(a.point[i]>b.point[i])return 1;
            else if(a.point[i]<b.point[i])return -1;
        }
        return 0;
    }
}

void solve()
{
    Card temp[7];
    Card select[5];
    int i,j,k,l,cnt;
    for(i=2;i<7;i++)temp[i]=Ccard[i-2];
    for(i=0;i<n;i++)//计算每位玩家最大的牌
    {
        temp[0]=Pcard[i][0];
        temp[1]=Pcard[i][1];
        for(j=0;j<6;j++)//枚举第一张不要的牌
        {
            for(k=j+1;k<7;k++)//枚举第二张不要的牌
            {
                cnt=0;
                for(l=0;l<7;l++)
                {
                    if(l!=j&&l!=k)select[cnt++]=temp[l];
                }
                Maxcard tt=gettype(select);
                if(biger(tt,maxcard[i])==1)maxcard[i]=tt;
            }
        }
    }
    cnt=1;
    int ansi[N];
    Maxcard ans=maxcard[0];
    ansi[0]=0;
    for(i=1;i<n;i++)
    {
        if(biger(maxcard[i],ans)==1)
        {
            cnt=0;
            ans=maxcard[i];
            ansi[cnt++]=i;
        }
        else if(biger(maxcard[i],ans)==0)
        {
            ansi[cnt++]=i;
        }
    }
    printf("%d\n",cnt);
    printf("%d",ansi[0]+1);
    for(i=1;i<cnt;i++)printf(" %d",ansi[i]+1);
    printf("\n");
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        init();
        int i;
        char p[2],c[2];
        for(i=0;i<n;i++)
        {
            scanf("%s%s",p,c);
            Pcard[i][0].point=getp(p);
            Pcard[i][0].color=c[0];
            scanf("%s%s",p,c);
            Pcard[i][1].point=getp(p);
            Pcard[i][1].color=c[0];
        }
        for(i=0;i<5;i++)
        {
            scanf("%s%s",p,c);
            Ccard[i].point=getp(p);
            Ccard[i].color=c[0];
        }
        solve();
    }
    return 0;
}
时间: 2024-11-16 07:34:52

[swustoj 1088] 德州扑克的相关文章

分享一个德州扑克的算法

德州扑克想必很多人都玩过,当然对于新手需要说明的是,德州指的是德克萨斯州,而不是山东德州. 这几个月一直在做一个德州扑克的服务器,分享下在计算最大牌型,比牌逻辑的算法和洗牌的方法,希望对大家有帮助. 首先我们定义一下Poker类 public class Poker { private String tag; // 图片扑克花色的表示(代表的是红桃.黑桃,梅花.方块 private int num; // 表示扑克牌面的大 public Poker(String tag, int num) {

模拟德州扑克对战游戏

================================================================ 注意:本文参考"巧妙的Python数据结构玩法|实战德州扑克"的相关内容,并在此基础之上完成模拟扑克对战游戏. 原文网址:http://mp.weixin.qq.com/s/JQ0zJGf7Tz49Xn78x7Z40g ================================================================ 我们写了两

德州扑克 2015 华为软件精英挑战赛

概述 华为2015软件挑战赛比赛总结,跟队友当时奋斗了15天吧,最后差点进32强了,第三轮遇到的对手太厉害,止步64强了.这次官方提供 Ubuntu 纯命令行镜像和庄家 Server,选手编写德州扑克选手机器人程序互相 PK(8人一组)500轮后钱多者胜出.运行只要运行华为提供的ne">dist_check_and_run.sh 脚本 即可,里面会给自动运行每个game程序.最近快要找工作了一些项目还是要总结一下的,感觉欠缺的地方还是有很多的,下面进入正题. 梳理一下主干主要这次比赛项目主

德州扑克输赢判断-C#

首先讲一下思路吧. 德州扑克一把有7张牌,可能组成10种牌型,所以,在网络游戏中,不可能是两两比较,然后排序,最简单的做法就是对每个玩家的手牌计算一个权值,然后对最终玩家的权值进行排序即可得到最终的输赢顺序. 其实这个是我的毕业设计,在大三的时候,我曾在一位学长王总的带领下做过一个德州扑克的记录软件,那个软件比较简单,只是有记录员记录现实世界中正在进行的游戏,然后把玩家的牌,叫牌操作和游戏结果记录下来,以供将来重放时做教学使用.当时的项目并没有输赢判断的功能,而是由记录员自己输入输赢的玩家顺序.

一场改变你投资生涯的讨论:职业德州扑克手看交易

各位投友大家好. 校长今天花时间仔细读了一篇长文,叫做<职业德州扑克手看交易:没犯任何错误照样输个精光>,非常棒的文章. 可惜不知道作者是谁,但看得出来,文中讲到的他自己在德州扑克上的经验是真实的. 这篇文章提出了两个非常有价值的概念. 第一个叫盈亏同源.有一些亏损是你在追求盈利道路上必须要支付的成本,这是不可避免也是不应该避免的.因为你一旦避免了这些亏损,你同时也就失去了盈利的机会. 而另外一些亏损择时可以避免也是应该避免的.所谓高手就是在这个部分发挥功力. 第二个概念是把风险分成了三层:系

德州扑克AI WEB版

继续之前的德州扑克话题,上次的DOS界面确实没法看,我女朋友说这是什么鬼.哈哈,估计只有自己能玩了 这两天重构了一下界面,基于web服务器和浏览器来交互. 服务器和客户端之间用websocket通信,这种全双工长连接更方便服务器及时的将整个游戏数据向客户端推送. 这篇随笔主要记录一下做前端界面的时候遇到的一些坑,至于德州扑克游戏的具体逻辑以及AI的逻辑可以查看我前两篇随笔 说道web服务器,go语言对这方面封装的非常好,用起来太爽了.而使用websocket,我们需要用到google提供的一个w

华为软件精英挑战赛【德州扑克】心得体会

这是华为举办的一个软件竞赛,华为提供一个德州扑克台桌的server,我们要根据牌型等因素,给出出牌的策略,类似模拟牌手的程序.从知道挑战的题目到提交最终版本的程序中间只有一个月的时间,刚看到这个题目一点头绪没有,看了论文有用蒙特卡洛模拟,决策树等,各种没听过的词汇,感觉写出这个程序会很难,和我一个教研室的小伙伴们看到这个题目的时候陆续都放弃了. 思考了半天我也放弃了,因为接下来几个星期还有实习的面试和小论文等着我完成,就这样过了2个星期,期间我把小论文与实习面试都完成了,在一天早晨无意中又点开了

java和h5 canvas德州扑克开发中(二)

德州扑克网页源码在github上分享 https://github.com/lxr1907/pokers 感兴趣的可以上去看下. 1.通讯使用websocket,主要在message.js中. 2.用canvas画界面的代码主要在view.js中. 3.游戏逻辑控制代码在controll.js中. 4.poker.min.js是github上的一个开源画扑克牌的js,在drawCards.js中进行了简单的封装. 5.music.js主要负责音效播放. 6.texasIndex.html是游戏的

2015华为德州扑克入境摘要——软体project

直到6一个月2号下午12时00,华为长达一个月的德州扑克锦标赛落下帷幕也被认为是. 我们的团队一直共同拥有3民,间.一个同学(吴)负责算法设计,一个同学(宋)负责分析消息,而我负责的实现框架设计和详细的决策算法.离5报名早年1月开始,要设置环境,设计框架,任务分工,以及各个模块代码的编写.从我个人的感觉来看,整个过程能够说是一个比較艰辛的历程. 德州扑克是一种棋牌类游戏.属于一种博弈过程,起先我对这个游戏没有不论什么的了解,最多的也仅仅是在影视题材里面见过,可是详细的游戏规则并不懂.而正是在这种