Reputation:
I'm making a poker game, and I was trying to test and see if any player had a royal flush in their hand. Before I could test this, however, I came into a roadblock: I don't have a fast and simple way of testing each players' hands for the Ace, King, Queen, Jack, and ten in a suit.
This is my code so far:
private void findWinner() {
// p1 hand
List<String> p1hand = cards.subList(10, 15);
p1hand.addAll(cards.subList(0, 2));
System.out.println("Player 1's total hand is " + p1hand);
// p1 hand
List<String> p2hand = cards.subList(10, 15);
p2hand.addAll(cards.subList(2, 4));
System.out.println("Player 2's total hand is " + p2hand);
// testing for royal flush
String[] spadeRoyalFlush = {"Ace of spades", "King of spades", "Queen of spades", "Jack of spades", "10 of spades"};
String[] heartRoyalFlush = {"Ace of hearts", "King of hearts", "Queen of hearts", "Jack of hearts", "10 of hearts"};
String[] dimRoyalFlush = {"Ace of diamonds", "King of diamonds", "Queen of diamonds", "Jack of diamonds", "10 of diamonds"};
String[] clubRoyalFlush = {"Ace of clubs", "King of clubs", "Queen of clubs", "Jack of clubs", "10 of clubs"};
// p1
boolean p1royalFlush = false;
if(p1hand.contains(spadeRoyalFlush)) { // line 104
p1royalFlush = true;
}
if(p1hand.contains(heartRoyalFlush)) {
p1royalFlush = true;
}
if(p1hand.contains(dimRoyalFlush)) {
p1royalFlush = true;
}
if(p1hand.contains(clubRoyalFlush)) {
p1royalFlush = true;
}
if(p1royalFlush) {
System.out.println("Player 1 got a royal flush with " + p1hand);
}
// p2
boolean p2royalFlush = false;
for(int i=0; i<p2hand.size(); i++) {
if(p2hand.contains(spadeRoyalFlush)) {
p2royalFlush = true;
}
if(p2hand.contains(heartRoyalFlush)) {
p2royalFlush = true;
}
if(p2hand.contains(dimRoyalFlush)) {
p2royalFlush = true;
}
if(p2hand.contains(clubRoyalFlush)) {
p2royalFlush = true;
}
}
if(p2royalFlush) {
System.out.println("Player 2 got a royal flush with " + p2hand);
}
} // line 165 is where I call this method
cards
is an ArrayList of Strings that contains every name of each card (e.g. "Ace of spades", "3 of hearts", etc.)
When I run this code, I get the error:
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$SubList.checkForComodification(Unknown Source)
at java.base/java.util.ArrayList$SubList.listIterator(Unknown Source)
at java.base/java.util.AbstractList.listIterator(Unknown Source)
at java.base/java.util.ArrayList$SubList.iterator(Unknown Source)
at java.base/java.util.AbstractCollection.contains(Unknown Source)
at poker.PlayGame.findWinner(PlayGame.java:104)
at poker.PlayGame.doEverything(PlayGame.java:165)
at poker.MainPoker.main(MainPoker.java:7)
I researched what that meant and I was astounded because as far as I could tell, I wasn't iterating over anything in my code.
This is the DoEverything method:
public void doEverything() {
dealHands();
throwCards();
findWinner(); // line 165
}
This is the main method:
public static void main(String[] args) {
PlayGame game = new PlayGame();
game.doEverything(); // line 7
}
Upvotes: 0
Views: 107
Reputation: 18313
I would use List.containsAll()
as documented here.
Returns true if this list contains all of the elements of the specified collection.
String[] array = ...;
List<String> list = ....;
list.containsAll(Arrays.asList(array));
Reagrding the ConcurrentModificationException
at line 104, you are calling contains()
on p1hand
, but p1hand
is from cards.subList(10, 15)
.
We can't see where cards
comes from. You have not posted the necessary code to debug that point. But see the answer from @devpuh for more detail on calling contains()
on a sub-list.
Upvotes: 5
Reputation:
Be careful with List.subList(int fromIndex, int toIndex)
!
Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.
(...)
The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)
All changes on this create List will affect the original list!
And you get a ConcurrentModificationException
as soon as you try to access a sublist when the original list was structural changed. (In your case you added a new element to the list cards
)
Change
List<String> p1hand = cards.subList(10, 15);
p1hand.addAll(cards.subList(0, 2));
to
List<String> p1hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
p1hand.addAll(cards.subList(0, 2));
And to check if the list contains all specific cards use
p1hand.containsAll(Arrays.asList(spadeRoyalFlush));
Upvotes: 1