问题(简短版):如何比较 ArrayList 中的元素?
我已经掌握了 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());
}
}
}
还有一个检查每手牌的类(这是我无法弄清楚的类)。我目前已经添加了代码来添加一个 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);
}
以及一种测试过牌手牌的方法,该方法可创建获胜手牌(顺子、同花、同种三手牌)。我不知道如何在我的“检查手牌”类(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());
}
}
最佳答案
要评估扑克牌,您要做的最常见的事情可能是循环遍历数据结构(可以是数组、列表等)并将牌相互比较。例如这里有一些伪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.Collections 和 java.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 */
}
但是使用辅助方法有助于组织您的代码。
我希望这会有所帮助。如果您还需要对牌进行评分来决定是否有获胜者,只需向返回分数的枚举添加另一个方法即可。然后看看哪一个最大。
关于java - Java 中 ArrayList 扑克游戏的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20578235/