65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Java 中制作扑克牌对子评估器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2009年8月8日

CPOL

14分钟阅读

viewsIcon

164294

创建、评估和比较 5 张牌的扑克牌组。

引言

标题说明了一切:制作一个可以创建、评估和比较 5 张牌扑克牌组的程序。

背景

本教程可独立使用,但如果您想了解更多关于在 Java 中创建牌组和牌类的信息,请参阅此处

使用代码

此程序将能够生成、评估和比较扑克牌组。需要对面向对象设计有基本了解(创建类并让它们相互交互)。这里没有继承或接口。;) RandomArrayList 以及静态变量和方法有时会被使用,但如果您还不了解它们,它们也不会成为障碍。我在给初学者的笔记中包含了简短的说明。

那么,在面向对象的扑克牌游戏中我们需要什么?我们有牌(Card)、牌组(Deck)和手牌(Hand)。Card 类将包含rank(点数)和suit(花色)变量,Deck 将是Cards 的容器,而Hand 将是我们评估和比较扑克牌组的地方。

package javapoker;
public class Card{
    private short rank, suit;

    private static String[] suits = { "hearts", "spades", "diamonds", "clubs" };
    private static String[] ranks  = { "Ace", "2", "3", "4", "5", "6", "7", 
                   "8", "9", "10", "Jack", "Queen", "King" };

    public static String rankAsString( int __rank ) {
        return ranks[__rank];
    }

    Card(short suit, short rank)
    {
        this.rank=rank;
        this.suit=suit;
    }

    public @Override String toString()
    {
          return ranks[rank] + " of " + suits[suit];
    }

    public short getRank() {
         return rank;
    }

    public short getSuit() {
        return suit;
    }
}

所以我们有只读的suitrank变量,一个简单的构造函数,一个toString方法和一个rankAsString方法。该类将非常快速,因为它只需访问静态数组的索引就知道要输出哪个字符串。这个数组充当字典,允许我们快速轻松地将一个 int 转换为相应的字符串。我们甚至不必使用String.ParseInt()。我们可以创建一个 switch 语句,根据suitrank变量找到要输出的相应字符串,但它每次都必须对其进行评估。访问数组的特定索引要快得多。rankAsString 方法是一个实用方法,用于接收一个数字并将其转换为相应的点数字符串(我们稍后将使用它)。

给初学者:关于 static 关键字的说明:静态方法和变量适用于整个类,而不是像实例方法和变量那样适用于特定实例。我们通过 new 创建的特定卡片实例调用getRank()。但我们会通过类调用rankAsString,例如“Card.rankAsString( 4 );”。我们有一个静态数组来表示不同的花色名称。这个数组属于整个类,而不仅仅是某个Card,因此每个Card 的实例方法和类的静态方法都可以访问它。

注意:现在,我们可以为ranksuit变量使用 short 甚至 byte,因为只有四种可能的值。但计算机处理 4 字节 int 的速度比处理 2 字节 short 的速度要快得多,所以您在极其微小的内存量上会获得处理速度上的收益。使用 int 而不是 short 是 Java 中的最佳实践。

现在我们需要一个牌组来存放我们的牌。我制作了另一个教程,展示了许多不同的牌组制作方法,但在本教程中,我将只展示最高效的方法。

package javapoker;
import java.util.Random;import java.util.ArrayList;
public class Deck {
    private ArrayList<Card> cards;

    Deck()
    {
        cards = new ArrayList<Card>();
        int index_1, index_2;
        Random generator = new Random();
        Card temp;

        for (int a=1; a<=4; a++)
        {
            for (int b=1; b<=13; b++)
             {
               cards.add( new Card(a,b) );
             }
        }

       int size       

        for (int i=0; i<100; i++)
        {
            index_1 = generator.nextInt( cards.size() - 1 );
            index_2 = generator.nextInt( cards.size() - 1 );

            temp = cards.get( index_2 );
            cards.set( index_2 , cards.get( index_1 ) );
            cards.set( index_1, temp );
        }
    }

    public Card drawFromDeck()
    {       
        return cards.remove( 0 );
    }

    public int getTotalCards()
    {
        return cards.size();
        //we could use this method when making 
        //a complete poker game to see if we needed a new deck
    }
}

我们将牌放入CardArrayList 中,然后随机抽取 100 对牌并交换它们,从而洗牌。要从牌组中抽牌,我们只需返回第一个元素/牌,然后将其从牌组中移除。所有随机化都在构造函数中提前完成(在实际发牌之前),这使得我们的drawFromDeck 方法更简单,处理器占用更少。

给初学者的注意事项:关于ArrayList 的简短教程:ArrayList 是 Java 中“泛型”的一个例子。泛型有点像数组,因为它们存储特定类型的对象(<>之间的类型)。但ArrayList 是一个对象,而不仅仅是数组,因此它具有可以帮助我们的方便方法。我们可以使用size() 自动获取其大小,使用remove()add() 添加或删除对象,像数组一样使用get()set() 获取和设置对象,也许最有用的是,如果我们需要的空间更多,它会自动增长(实际上只是将项目复制到一个更大的数组中,但它会处理所有这些,所以我们不必这样做)。这使得我们常用的数据结构特性,如添加新元素,非常容易使用(使用数组,要在末尾添加新元素,我们必须创建一个从零开始的索引变量;每次在该索引处添加对象时,我们都会将其递增,以便我们能够添加更多对象;当然,我们必须希望数组有足够的空间;稍后您会看到这种技术)。要使用ArrayList,我们必须在源文件顶部导入java.util.ArrayList

给初学者的注意事项:关于Random 的总结:Random 是一个我们可以用来生成随机数的方便小工具类。要使用它,我们导入java.util.Random,然后使用Random generator = new Random() 创建一个随机数生成器。完成此操作后,我们可以使用我们的Random 实例“generator”通过nextInt() 获取随机 int。如果我们将一个整数传递给nextInt(),它将给我们一个小于该 int 且大于零的随机整数。所以当我们调用generator.nextInt( 52 ); 时,它会给我们一个 0 到 51 之间的随机数,我们可以将其用作ArrayList 中的索引来交换两张牌,从而洗牌。

好的,这不算太难,我们已经有了可以自我描述为字符串的牌,以及一个可以存放它们并分发的ArrayList的牌组。但现在,我们实际上需要处理它们以形成一副扑克牌。牌的存储机制将与牌组类似,大部分代码将用于评估牌组的级别。这将非常有趣,请耐心等待。

我们将有一个包含 5 张牌的数组,以及一个包含 6 个 int 的数组来表示牌组的价值。第一个 int 将对应牌组的类型,0 代表最高牌,1 代表对子,值越大代表等级越高的牌组。如果我们平局,第二个值将必须决定胜者。我们如何找到第二个值将取决于每种牌组的类型:在对子中,点数更高的对子获胜;在顺子中,点数更高的顶牌获胜,依此类推。如果这些值相等,我们将继续考虑下一个决定因素,例如除了对子之外的最高牌,或者两对牌中的低对。有些牌组只有两个决定因素,例如顺子。第一个值将是顺子在扑克牌等级中的位置(大于三张相同点数的牌,小于同花),第二个值将是顺子中的顶牌(7、J、K 等)。对于最高牌,我们将得到 0,因为最高牌是等级最低的牌组,接下来的 5 个值将是牌组中牌的点数,按降序排列。

到目前为止我们所拥有的

package javapoker;
public class Hand {
    private Card[] cards;
    private int[] value;

    Hand(Deck d)
    {
        value = new int[6];
        cards = new Card[5];
        for (int x=0; x<5; x++)
        {
            cards[x] = d.drawFromDeck(); //fill up cards[] array.
        }

        //rest of our code to assign values to the value array goes here
    }
   

    void displayAll()
    {
        for (int x=0; x<5; x++)
            System.out.println(cards[x]); //calls cards[x].toString()
    }

    int compareTo(Hand that)
    {
        for (int x=0; x<6; x++) //cycle through values
        {
            if (this.value[x]>that.value[x])
                return 1;
            else if (this.value[x]<that.value[x])
                return -1;
        }
        return 0; //if hands are equal
    }
}

好了,现在进行脏活,计算我们扑克牌组的实际价值。让我们从对子的情况开始。我们如何判断是否存在对子?如果我们有两张点数相同的牌。我们将如何实现?我们可以遍历点数,看看是否有任何点数有两张牌具有其值。但那样的话,对于三张相同点数的牌,我们必须再次执行相同的操作。何不创建一个包含 13 个槽(每个点数一个)的 int 数组,然后遍历这些牌;对于每张牌,我们将递增数组的相应索引。让我们看看代码表示

(从这一点开始的所有代码都放在Hand 构造函数中,在我们之前的注释处。)

int[] ranks = new int[14];

for (int x=0; x<=13; x++)
{
    ranks[x]=0; //zero the contents of the array
}

for (int x=0; x<=4; x++)
{
    ranks[ cards[x].getRank() ]++;
    //increment rank array at the index of each card's rank
}

为了简单起见,我们使用 1 代表 A 而不是 0 代表 A 来表示牌的点数。如果我们使用 0 代表 A,那么我们将使用 9 代表 10,这很令人困惑。由于我们的牌点数范围是 1-13,我们数组的第一个索引(0)将是空的。

好的,现在我们有了点数数组,现在我们需要找到实际上是否有任何对子。我们需要知道是否存在对子,如果存在,那么对子的点数是什么。所以我们创建一个 int sameCards 来记录相同点数的牌的数量,以及一个 int groupRank 来保存对子的点数。我们创建一个 int sameCards 是因为我们可能有不止两张相同点数的牌,甚至可能是 3 张或 4 张(希望不是 5 张,除非我们的处理器是黑庄)。我们可以只创建一个 bool isPair,但我们也想知道是否存在三张或四张相同点数的牌。

int sameCards=1;
//we know there will be at least one card of any rankint groupRank=0;
for (int x=13; x>=1; x--) //loop going from 13 to 1
{
    if ( ranks[x] > sameCards) //If more cards of rank x than sameCards 
    {
        sameCards=ranks[x];    //set sameCards to that number of cards
        groupRank=x;           //and record the rank of the cards 
    }
}

sameCards 从 1 开始,所以如果我们找到一种点数有两张牌,那么我们就记录 2 作为sameCards,并将rank (x) 作为groupRank。这对于对子、三张相同点数的牌或四张相同点数的牌来说都很好。

但等等,假设我们有一手满堂彩。有一对 K,所以我们记录 2 作为sameCards,13 作为groupRank。但我们继续遍历其他点数,如果存在 3 张 5,那么我们将用 3 覆盖sameCards,因为该点数的牌数量大于sameCards 的当前值。类似的情况:我们有两个对子,它记录了第一个对子,但不是另一个。我们可以处理只有一组牌的牌组,但不能处理有 2 组牌的牌组。我们需要一种方法来跟踪至少两个不同的牌组,并跟踪每组牌的数量和点数。在继续之前稍微思考一下。

注意:这绝对是程序中最复杂的逻辑,所以如果你一开始没弄懂,不用担心。剩下的代码都比较容易,你可以稍后再回来处理这部分。 :)

我的解决方案:好了,我们必须跟踪两组牌的点数以及每组牌的数量,所以我们将有两个变量来表示点数(largeGroupRank, smallGroupRank)以及两个变量来表示具有该点数的牌的数量(sameCards, sameCards2)。

int sameCards=1,sameCards2=1;
//initialze to 1int largeGroupRank=0,smallGroupRank=0;

for (int x=13; x>=1; x--)
{
     if (ranks[x] > sameCards) 
     {
         if (sameCards != 1)
         //if sameCards was not the default value
         {
             sameCards2 = sameCards;
             smallGroupRank = largeGroupRank;
         }
         
         sameCards = ranks[x];
         largeGroupRank = x;
         
     } else if (ranks[x] > sameCards2)
     {
         sameCards2 = ranks[x];
         smallGroupRank = x;
     }
}

如果ranks[x] 大于sameCards,我们就将其数据分配在那里;否则,如果它大于sameCards2,我们就将其数据分配在那里。现在,我确定你们都看到了嵌套的 if,所以我不妨告诉你们它是做什么用的。假设没有 if 语句:我们找到一对 8,然后我们找到三张 5。sameCards 包含一对 8,由于三张 5 比两张 8 要多,我们覆盖了sameCards。但之前找到的对子只是被覆盖而没有被记录下来,而它应该被放入sameCards2。所以,if 语句会检查sameCards 在被覆盖之前是否已被分配了某些内容,如果已被分配,我们会进行处理。

示例运行:我们找到 2 张 Q,所以我们将该值记录在sameCards 中,因为 2 比我们初始化sameCards 的 1 要大。然后,我们找到 2 张 7,所以我们将它们记录在sameCards2 中。我们找到 3 张 J,将它们记录在sameCards 中,然后找到 2 张 3,所以我们将它们记录在sameCards2 中。两张 8,然后三张 4。我们将两张 8 的数据写入sameCards2,然后将三张 4 的数据写入sameCards1。一切正常 :)

还有一点要讲,但你已经越过了难关;剩下的代码就全是小菜一碟了。

哇哦!我们已经写了确定对子、两对、三张相同点数的牌、四张相同点数的牌和满堂彩的代码。剩下的要确定的就是我们是否是同花或顺子。

我们先来处理同花。我们如何知道所有牌的花色都相同?好吧,如果两张牌的花色不同,那么就没有同花,所以让我们试试这个。我们搭乘遍历牌并记录其点数的循环的便车

boolean flush=true; //assume there is a flush
for (int x=0; x<4; x++) 
{
    if ( cards[x].getSuit() != cards[x+1].getSuit() ) 
        flush=false;
}

好的,在牌之间遍历,如果其中一张牌的花色与下一张牌的花色不匹配,那么就没有同花。

要确定是否存在顺子,我们需要知道是否有五张连续点数的牌。所以,如果存在一张牌具有五个连续的点数,我们就有一个顺子。

int topStraightValue=0;boolean straight=false;  //assume no straight  
for (int x=1; x<=9; x++) //can't have straight with lowest value of more than 10
{
    if (ranks[x]==1 && ranks[x+1]==1 && ranks[x+2]==1 && 
        ranks[x+3]==1 && ranks[x+4]==1)
    {
        straight=true;
        topStraightValue=x+4; //4 above bottom value
        break;
    }
}

if (ranks[10]==1 && ranks[11]==1 && ranks[12]==1 && 
    ranks[13]==1 && ranks[1]==1) //ace high
{
    straight=true;
    topStraightValue=14; //higher than king
}

我们检查是否存在五张连续点数的牌。有一个循环用于处理最高牌为 K 的顺子,我们添加了一个单独的特殊 if 来处理 A 高顺子,因为 A 的数量包含在 ranks[1] 中。

太棒了,我们已经涵盖了所有不同类型的牌组!现在,我们需要开始比较它们。我们拥有确定牌组类型所需的条件,但仍然需要更多数据来解决牌组之间的平局。假设我们有一个对子,我们知道对子是第二低的牌组。如果我们比较的牌组也是对子,那么我们需要比较对子的点数。如果对子的点数相等,我们需要比较下一张最高的牌,然后是下一张最高的牌,然后是下一张最高的牌。我们现在唯一需要的就是按顺序排列的下一张最高的牌。

int[] orderedRanks = new int[5];
int index=0;


if (ranks[1]==1) //if ace, run this before because ace is highest card
{
    //record an ace as 14 instead of one, as its the highest card
    orderedRanks[index]=14;
    index++; //increment position
}

for (int x=13; x>=2; x--)
{
    if (ranks[x]==1)
    //we have already written code to handle the case
    //of their being two cards of the same rank
    {
        orderedRanks[index]=x; 
        index++;
    }
}

现在我们有了一个数组,它将容纳所有其他无关紧要的杂牌。(万岁!)

在我们的Hand 类中,我们有一个私有数组 value,它包含六个 int。我们将使用它来包含牌组的数值。这个数组将包含比较两个扑克牌组所需的所有数据。我之前提到了我们的比较过程:“假设我们有一个对子,我们知道对子是第二低的牌组。如果我们比较的牌组也是对子,那么我们需要比较对子的点数。如果对子的点数相等,我们需要比较下一张最高的牌,然后是下一张最高的牌,然后是下一张最高的牌。”

这会设置一个需要比较的项目列表。最重要的事情是牌组的类型,所以它将放在第一个位置。其余位置将用于在相同类型的两手牌之间进行平局所需的数据。看一下

//start hand evaluation
if ( sameCards==1 ) {    //if we have no pair...
    value[0]=1;          //this is the lowest type of hand, so it gets the lowest value
    value[1]=orderedRanks[0];  //the first determining factor is the highest card,
    value[2]=orderedRanks[1];  //then the next highest card,
    value[3]=orderedRanks[2];  //and so on
    value[4]=orderedRanks[3];
    value[5]=orderedRanks[4];
}

if (sameCards==2 && sameCards2==1) //if 1 pair
{
    value[0]=2;                //pair ranked higher than high card
    value[1]=largeGroupRank;   //rank of pair
    value[2]=orderedRanks[0];  //next highest cards.
    value[3]=orderedRanks[1];
    value[4]=orderedRanks[2];
}

if (sameCards==2 && sameCards2==2) //two pair
{
    value[0]=3;
    //rank of greater pair
    value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank;
    //rank of smaller pair
    value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank;
    value[3]=orderedRanks[0];  //extra card
}

if (sameCards==3 && sameCards2!=2)
//three of a kind (not full house)
{
    value[0]=4;
    value[1]= largeGroupRank;
    value[2]=orderedRanks[0];
    value[3]=orderedRanks[1];
}

if (straight)
{
    value[0]=5;
    value[1]=;
    //if we have two straights, 
    //the one with the highest top cards wins
}

if (flush)   
{
    value[0]=6;
    value[1]=orderedRanks[0]; //tie determined by ranks of cards
    value[2]=orderedRanks[1];
    value[3]=orderedRanks[2];
    value[4]=orderedRanks[3];
    value[5]=orderedRanks[4];
}

if (sameCards==3 && sameCards2==2)  //full house
{
    value[0]=7;
    value[1]=largeGroupRank;
    value[2]=smallGroupRank;
}

if (sameCards==4)  //four of a kind
{
    value[0]=8;
    value[1]=largeGroupRank;
    value[2]=orderedRanks[0];
}

if (straight && flush)  //straight flush
{
    value[0]=9;
    value[1]=;
}

所以现在我们已经设置好了所有 value 数组(这是Hand 构造函数的结尾),我们可以使用这个方法来比较我们的牌组与任何其他牌组

int compareTo(Hand that)
{
    for (int x=0; x<6; x++)
    {
        if (this.value[x]>that.value[x])
            return 1;
        else if (this.value[x] != that.value[x])
        //if not greater and not equal, must be less
            return -1;
    }
    return 0; //if hands are equal
}

而且,我们可以添加这个方法来显示牌组的摘要(这也是我们使用Card 类中的静态rankAsString 方法将整数转换为关联的牌点数的地方,例如,11 = "Jack")。

void display()
{
    String s;
    switch( value[0] )
    {
        case 1:
            s="high card";
            break;
        case 2:
            s="pair of " + Card.rankAsString(value[1]) + "\'s";
            break;
        case 3:
            s="two pair " + Card.rankAsString(value[1]) + " " + 
              Card.rankAsString(value[2]);
            break;
        case 4:
            s="three of a kind " + Card.rankAsString(value[1]) + "\'s";
            break;
        case 5:
            s=Card.rankAsString(value[1]) + " high straight";
            break;
        case 6:
            s="flush";
            break;
        case 7:
            s="full house " + Card.rankAsString(value[1]) + 
              " over " + Card.rankAsString(value[2]);
            break;
        case 8:
            s="four of a kind " + Card.rankAsString(value[1]);
            break;
        case 9:
            s="straight flush " + Card.rankAsString(value[1]) + " high";
            break;
        default:
            s="error in Hand.display: value[0] contains invalid value";
    }
    s = "                " + s;
    //this just moves the output over a little in the console 
    //so its easier to see when viewing the output
    System.out.println(s);
}

现在这个详尽的类已经完成了,我们可以写一些测试代码来看看它的效果。我们的第一个 main 方法将测试我们制作的牌组的随机性(在之前的教程中有更多讨论)。

package javapoker

public class Main {

    public static void main(String[] args)
    {
        Deck deck= new Deck();
        Card C;

        System.out.println( deck.getTotalCards() );

       while (deck.getTotalCards()!=0 )
       {
           C = deck.drawFromDeck();
           System.out.println( C.toString() );
       }
    } 
}

好的,看起来随机性足够了,那么,现在让我们尝试制作一些牌组,看看程序认为它们的排名如何,并将结果与我们已知的应有排名进行比较。

public static void main(String[] args)  {
     for (int i=0; i<100; i++)
     {
         Deck deck= new Deck();
         Hand hand= new Hand(deck);
         hand.display(); //show the summary of the hand, e.g. "full house"
         hand.displayAll(): //look at all the individual cards in the hand         
     }
}

好了,最后一个要测试的机制是牌组比较,使用一个类似的方法。

 public static void main(String[] args) {
    for (int i=0; i<20000; i++)
    {
        Deck deck= new Deck();
        Hand hand= new Hand(deck);
        Hand hand2= new Hand(deck);
        hand.display();
        hand.displayAll();
        hand2.display();
        hand2.displayAll();
        System.out.println(hand.compareTo(hand2));

    }
}

这样,您就学会了如何在 Java 中制作扑克牌点数评估器!希望您喜欢本教程!请随意发表任何和所有评论、问题和建议!:)

注意:本教程仅涵盖如何制作、评估和比较扑克牌组(我认为这一个教程足够了)。它并没有真正讲述如何制作一个完整的可玩扑克游戏。制作投注功能并不难,但制作逼真对手的 AI 超出了本范围。不过,这是制作扑克游戏的一个很好的基础,如果有人完成了具有良好、逼真 AI 和游戏性的扑克游戏,他们可以将其发布到 CodeProject 上。

代码

以下是教程中每个类的完整代码(用于粘贴到编译器中)

Card.java
package javapoker;
public class Card{
    private short rank, suit;

    private static String[] suits = { "hearts", "spades", "diamonds", "clubs" };
    private static String[] ranks  = { "Ace", "2", "3", "4", "5", "6", "7", 
                                       "8", "9", "10", "Jack", "Queen", "King" };

    public static String rankAsString( int __rank ) {
        return ranks[__rank];
    }

    Card(short suit, short rank)
    {
        this.rank=rank;
        this.suit=suit;
    }

    public @Override String toString()
    {
          return ranks[rank] + " of " + suits[suit];
    }

    public short getRank() {
         return rank;
    }

    public short getSuit() {
        return suit;
    }
}
Deck.java
package javapoker;
import java.util.Random;import java.util.ArrayList;
public class Deck {
    private ArrayList<Card> cards;

     Deck()
    {
        cards = new ArrayList<Card>();
        int index_1, index_2;
        Random generator = new Random();
        Card temp;

        for (short a=0; a<=3; a++)
        {
            for (short b=0; b<=12; b++)
             {
               cards.add( new Card(a,b) );
             }
        }

        int size = cards.size() -1;

        for (short i=0; i<100; i++)
        {
            index_1 = generator.nextInt( size );
            index_2 = generator.nextInt( size );

            temp = (Card) cards.get( index_2 );
            cards.set( index_2 , cards.get( index_1 ) );
            cards.set( index_1, temp );
        }
    }

    public Card drawFromDeck()
    {       
        return cards.remove( cards.size()-1 );
    }

    public int getTotalCards()
    {
        return cards.size();
        //we could use this method when making 
        //a complete poker game to see if we needed a new deck
    }
}
Hand.java
package javapoker;
public class Hand {
    private Card[] cards;
    private int[] value;

    Hand(Deck d)
    {
        value = new int[6];
        cards = new Card[5];
        for (int x=0; x<5; x++)
        {
            cards[x] = d.drawFromDeck();
        }

        int[] ranks = new int[14];
        //miscellaneous cards that are not otherwise significant
        int[] orderedRanks = new int[5];
        boolean flush=true, straight=false;
        int sameCards=1,sameCards2=1;
        int largeGroupRank=0,smallGroupRank=0;
        int index=0;
        int topStraightValue=0;

        for (int x=0; x<=13; x++)
        {
            ranks[x]=0;
        }
        for (int x=0; x<=4; x++)
        {
            ranks[ cards[x].getRank() ]++;
        }
        for (int x=0; x<4; x++) {
            if ( cards[x].getSuit() != cards[x+1].getSuit() )
                flush=false;
        }

        for (int x=13; x>=1; x--)
        {
                 if (ranks[x] > sameCards)
                 {
                     if (sameCards != 1)
                     //if sameCards was not the default value
                     {
                         sameCards2 = sameCards;
                         smallGroupRank = largeGroupRank;
                     }

                     sameCards = ranks[x];
                     largeGroupRank = x;

                 } else if (ranks[x] > sameCards2)
                 {
                     sameCards2 = ranks[x];
                     smallGroupRank = x;
                 }
        }

        if (ranks[1]==1) //if ace, run this before because ace is highest card
        {
            orderedRanks[index]=14;
            index++;
        }

        for (int x=13; x>=2; x--)
        {
            if (ranks[x]==1)
            {
                orderedRanks[index]=x; //if ace
                index++;
            }
        }
        
        for (int x=1; x<=9; x++)
        //can't have straight with lowest value of more than 10
        {
            if (ranks[x]==1 && ranks[x+1]==1 && ranks[x+2]==1 && 
                ranks[x+3]==1 && ranks[x+4]==1)
            {
                straight=true;
                topStraightValue=x+4; //4 above bottom value
                break;
            }
        }

        if (ranks[10]==1 && ranks[11]==1 && ranks[12]==1 && 
            ranks[13]==1 && ranks[1]==1) //ace high
        {
            straight=true;
            topStraightValue=14; //higher than king
        }
        
        for (int x=0; x<=5; x++)
        {
            value[x]=0;
        }


        //start hand evaluation
        if ( sameCards==1 ) {
            value[0]=1;
            value[1]=orderedRanks[0];
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==2 && sameCards2==1)
        {
            value[0]=2;
            value[1]=largeGroupRank; //rank of pair
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
            value[4]=orderedRanks[2];
        }

        if (sameCards==2 && sameCards2==2) //two pair
        {
            value[0]=3;
            //rank of greater pair
            value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank;
            value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank;
            value[3]=orderedRanks[0];  //extra card
        }

        if (sameCards==3 && sameCards2!=2)
        {
            value[0]=4;
            value[1]= largeGroupRank;
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
        }

        if (straight && !flush)
        {
            value[0]=5;
            value[1]=;
        }

        if (flush && !straight)
        {
            value[0]=6;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==3 && sameCards2==2)
        {
            value[0]=7;
            value[1]=largeGroupRank;
            value[2]=smallGroupRank;
        }

        if (sameCards==4)
        {
            value[0]=8;
            value[1]=largeGroupRank;
            value[2]=orderedRanks[0];
        }

        if (straight && flush)
        {
            value[0]=9;
            value[1]=;
        }

    }

    void display()
    {
        String s;
        switch( value[0] )
        {

            case 1:
                s="high card";
                break;
            case 2:
                s="pair of " + Card.rankAsString(value[1]) + "\'s";
                break;
            case 3:
                s="two pair " + Card.rankAsString(value[1]) + " " + 
                                Card.rankAsString(value[2]);
                break;
            case 4:
                s="three of a kind " + Card.rankAsString(value[1]) + "\'s";
                break;
            case 5:
                s=Card.rankAsString(value[1]) + " high straight";
                break;
            case 6:
                s="flush";
                break;
            case 7:
                s="full house " + Card.rankAsString(value[1]) + " over " + 
                                  Card.rankAsString(value[2]);
                break;
            case 8:
                s="four of a kind " + Card.rankAsString(value[1]);
                break;
            case 9:
                s="straight flush " + Card.rankAsString(value[1]) + " high";
                break;
            default:
                s="error in Hand.display: value[0] contains invalid value";
        }
        s = "                " + s;
        System.out.println(s);
    }

    void displayAll()
    {
        for (int x=0; x<5; x++)
            System.out.println(cards[x]);
    }

    int compareTo(Hand that)
    {
        for (int x=0; x<6; x++)
        {
            if (this.value[x]>that.value[x])
                return 1;
            else if (this.value[x]<that.value[x])
                return -1;
        }
        return 0; //if hands are equal
    }
}

关注点

当我观看这个程序评估和比较 200,000 副扑克牌时,我真的觉得自己很强大,好像取得了一些成就。我花了 10 年也做不到的事情,但计算机却在一分多钟内就完成了。

历史

  • 09-08-07:提交文章。
© . All rights reserved.