2013-12-14 241 views
0

问题(简短版本):如何比较ArrayList中的元素彼此?比较ArrayList扑克游戏Java

我已经掌握了ArrayList的大部分基础知识(包括添加,获取,设置,大小...)。我无法进入ArrayList来比较对象(扑克牌的价值和套装),以确定最佳的扑克牌。我有一个课程来存储关于卡片的信息。

卡类:

/** class Card : for creating playing card objects 
    * it is an immutable class. 
    * Rank - valid values are 1 to 13 
    * Suit - valid values are 0 to 3 
    * Do not modify this class! 
    */ 
    class Card { 

     /* constant suits and ranks */ 
     static final String[] Suit = {"Clubs", "Diamonds", "Hearts", "Spades" }; 
     static final String[] Rank = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"}; 

     /* Data field of a card: rank and suit */ 
     private int cardRank; /* values: 1-13 (see Rank[] above) */ 
     private int cardSuit; /* values: 0-3 (see Suit[] above) */ 

     /* Constructor to create a card */ 
     /* throw PlayingCardException if rank or suit is invalid */ 
     public Card(int rank, int suit) throws PlayingCardException { 
     if ((rank < 1) || (rank > 13)) 
      throw new PlayingCardException("Invalid rank:"+rank); 
     else 
       cardRank = rank; 
     if ((suit < 0) || (suit > 3)) 
      throw new PlayingCardException("Invalid suit:"+suit); 
     else 
       cardSuit = suit; 
     } 

     /* Accessor and toString */ 
     /* You may impelemnt equals(), but it will not be used */ 
     public int getRank() { return cardRank; } 
     public int getSuit() { return cardSuit; } 
     public String toString() { return Rank[cardRank] + " " + Suit[cardSuit]; } 


     /* Few quick tests here */ 
     public static void main(String args[]) 
     { 
     try { 
      Card c1 = new Card(1,3); // A Spades 
      System.out.println(c1); 
      c1 = new Card(10,0); // 10 Clubs 
      System.out.println(c1); 
      //c1 = new Card(10,5);  // generate exception here 
     } 
     catch (PlayingCardException e) 
     { 
      System.out.println("PlayingCardException: "+e.getMessage()); 
     } 
     } 
    } 

和A类检查卡每手(这是我在遇到麻烦搞清楚类)。我目前添加了代码,以使其添加一个ArrayList并再次打印每一个(只是为了确保我可以创建一个单独的ArrayList,因为我对自己的能力不太满意),但我无法弄清楚如何比较每张卡的要素(等级和套装)。

检查手类:

/** Check current currentHand using multipliers and goodHandTypes arrays 
* Must print yourHandType (default is "Sorry, you lost") at the end o function. 
* This can be checked by testCheckHands() and main() method. 
*/ 
    private void checkHands() 
    { 
     // implement this method! 
     ArrayList<Card> multiplierCheck = new ArrayList<Card>(); 
     String yourhandtype = "Sorry, you lost"; 

     for (int toList = 0; toList<5; toList++) { 
       multiplierCheck.add(currentHand.get(toList)); 
      } 
     System.out.println(multiplierCheck); 

     System.out.println(yourhandtype); 
    } 

,并测试检查创建的手被获胜的手(直,同花顺,三张相同的牌)之手的方法。我无法弄清楚如何比较我的Check Hands Class中的各张牌。

testCheckHands()方法

public void testCheckHands() 
    { 
     try { 
      currentHand = new ArrayList<Card>(); 

     // set Royal Flush 
     currentHand.add(new Card(1,3)); 
     currentHand.add(new Card(10,3)); 
     currentHand.add(new Card(12,3)); 
     currentHand.add(new Card(11,3)); 
     currentHand.add(new Card(13,3)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Straight Flush 
     currentHand.set(0,new Card(9,3)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Straight 
     currentHand.set(4, new Card(8,1)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Flush 
     currentHand.set(4, new Card(5,3)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // "Royal Pair" , "Two Pairs" , "Three of a Kind", "Straight", "Flush ", 
     // "Full House", "Four of a Kind", "Straight Flush", "Royal Flush" }; 

     // set Four of a Kind 
     currentHand.clear(); 
     currentHand.add(new Card(8,3)); 
     currentHand.add(new Card(8,0)); 
     currentHand.add(new Card(12,3)); 
     currentHand.add(new Card(8,1)); 
     currentHand.add(new Card(8,2)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Three of a Kind 
     currentHand.set(4, new Card(11,3)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Full House 
     currentHand.set(2, new Card(11,1)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Two Pairs 
     currentHand.set(1, new Card(9,1)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // set Royal Pair 
     currentHand.set(0, new Card(3,1)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 

     // non Royal Pair 
     currentHand.set(2, new Card(3,3)); 
     System.out.println(currentHand); 
      checkHands(); 
     System.out.println("-----------------------------------"); 
     } 
     catch (Exception e) 
     { 
     System.out.println(e.getMessage()); 
     } 
    } 
+0

checkHnads究竟做了些什么以及它不起作用? –

+1

@peeskillet我认为它还没有做任何事情。我认为这就是OP所要求的。 Mikael究竟是什么问题?我假设你拥有的是每个玩家手中的ArrayList,这样你就可以获得纸牌并与扑克规则进行比较。这个问题实际上是否与ArrayList或比较扑克牌值有关? – Radiodef

+0

@Radiodef我只是不确定如何访问里面的arraylist卡内的信息。我已经想出了如何使用[arraylist name] .get(0).getRank()来访问这些套装,但是我很难找出比较的结果,找到直线(来自队伍)以及如何让一个“价值”超过另一个皇家同花顺>三类>同花>直(或者其他顺序)。 – MikaelCMiller

回答

1

为了评估扑克牌手,你可能要做的最常见的事情是循环遍历数据结构(可以是数组,列表,w憎恨者)并且将这些卡片相互比较。例如,以下是一些伪Java来比较直:

for (int i = 1; i < /* length of hand */; i++) { 

    if (/* rank for card i is not 1 greater 
      than rank for card i - 1 */) { 

     /* not a straight */ 
    } 
} 

注意的是,上述假设的结构进行排序,我会得到。此外,由于扑克牌手如此不同,所以全部都不是真正的“最佳方式”。你将不得不为每一个例程写一个例程。所以我建议你拿出一些可以帮助你的抽象。我会做的是使用枚举。这里有一个基本的例子:

enum PokerHand { 
    STRAIGHT { 
     @Override 
     boolean matches(List<Card> hand) { 

      for (int i = 1; i < hand.size(); i++) { 
       if (
        card.get(i).getRank() != 
        card.get(i - 1).getRank() + 1 
       ) { 
        return false; 
       } 
      } 

      return true; 
     } 
    }, 
    FOUR_OF_A_KIND { 
     @Override 
     boolean matches(List<Card> hand) { 

      int[] rankCount = new int[14]; 

      /* count up the ranks in the hand */ 
      for (Card card : hand) { 
       rankCount[card.getRank()]++; 
      } 

      boolean foundHasOne = false; 
      boolean foundHasFour = false; 

      /* now evaluate exclusively 
      * there must be only a 1 count and a 4 count 
      */ 
      for (int i = 1; i < rankCount.length; i++) { 

       if (rankCount[i] == 1) { 
        if (!foundHasOne) { 
         foundHasOne = true; 
        } else { 
         return false; 
        } 

       } else if (rankCount[i] == 4) { 
        if (!foundHasFour) { 
         foundHasFour = true; 
        } else { 
         return false; 
        } 

       } else if (rankCount[i] != 0) { 
        return false; 
       } 
      } 

      return true; 
     } 
    }, 
    ROYAL_FLUSH { 
     final int[] rfRanks = { 
      1, 10, 11, 12, 13 
     }; 

     @Override 
     boolean matches(List<Card> hand) { 

      for (int i = 0; i < rfRanks.length; i++) { 
       if (rfRanks[i] != hand.get(i).getRank()) 
        return false; 
      } 

      return true; 
     } 
    }; 

    abstract boolean matches(List<Card> hand); 
} 

当然,上面并没有涵盖所有的扑克牌手,只是几个例子。我也不玩扑克,所以这些可能会有点不对,但重点是要展示一些评估示例。

正如我之前所说,如果您提前对列表进行排序,这变得更加简单。 java.util.Collectionsjava.util.Arrays有这方面的实用方法,所以它是相当微不足道的。如果在检查完手后不希望排序继续存在,请确保在排序前进行复制。

/* make a shallow copy */ 
List<Card> sortedHand = new ArrayList<Card>(playerHand); 

/* sort based on rank */ 
Collections.sort(sortedHand, new Comparator<Card>() { 
    @Override 
    public int compare(Card card1, Card card2) { 
     int rank1 = card1.getRank(); 
     int rank2 = card2.getRank(); 

     if (rank1 > rank2) { 
      return 1; 

     if (rank1 < rank2) 
      return -1; 

     return 0; 
    } 
}); 

请参阅Comparator#compare了解如何工作的说明,但这基本上是它的排序。

使用枚举或类似的东西,然后使评估逻辑上相当平凡。

现在我推荐的是做一个评估的方法,因为那样你可以方便地返回手的常数。

static PokerHand evaluateHand(List<Card> hand) { 
    for (PokerHand potential : PokerHand.values()) { 
     if (potential.matches(hand)) 
      return potential; 
    } 

    /* imply there is not a matching hand */ 
    return null; 
} 

所以以后你让你的手的副本,并整理它,你可以打电话来评价它:

PokerHand evaluated = evaluateHand(sortedHand); 

if (evaluated != null) { 
    /* it's a recognized hand */ 
} 

你不必做的方法,你可以做类似的如下:

PokerHand evaluated = null; 
for (PokerHand potential : PokerHand.values()) { 
    if (potential.matches(sortedHand)) { 
     evaluated = potential; 
     break; 
    } 
} 

if (evaluated != null) { 
    /* it's a recognized hand */ 
} 

但使用帮助器方法可以帮助组织您的代码。

我希望有帮助。如果您还需要对手进行评分以决定是否有赢家,则只需向枚举中添加另一种方法即可返回得分。然后看哪一个是最大的。

+0

我在手中迭代时遇到了很多麻烦,但是这清除了它向上。此外,我现在看到,访问每张牌的等级和花色必须通过循环完成。我试图弄清楚这一点,但你已经清除了它。 – MikaelCMiller

1

,如果你说这是怎么不工作,而是通过一个ArrayList迭代不知道..

for (String s : arrayList) 
    if (s.equals(value)) 
     // ... 

字符串可以被替换为INT ,等等。

+0

这有助于迭代,谢谢。我需要弄清楚如何比较特定的值(卡牌和套装的行列)来找出直线,同花,三种等等。 – MikaelCMiller