我正在制作一个纸牌游戏,它运行良好,除非我无法进入卡座的底部而不会在某些时候遇到IndexOutOfBoundsException错误。我有一个1到52之间的数字随机数组,我用它来选择从我所拥有的数组列表中调用的索引。由于套牌是一个ArrayList,我可以轻松地在每个循环后删除每张卡。但是我无法从随机数字数组中删除该数字,因此随着卡列表变小,调用索引的可能性就越大。无法找到解决方法。我已经尝试使用if语句将随机数的值更改为小于arrayList的最大长度但仍然得到错误。
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to War! Press enter to begin."); //User prompt
Scanner scanner = new Scanner(System.in); //Scanner init
String[] suit = {" of Diamonds", " of Spades", " of Hearts", " of Clubs"};//Array for suits
String[] faces = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};//Array for faces
String[] deck = new String[52]; //Deck size setup
boolean deckComplete = false;//Boolean for deck being finished
int[] random = new int[52];//Array for all numbers between 0 and the number of cards in the deck multiplied by number of decks
ArrayList<Integer> random1 = new ArrayList<Integer>();
int playerOneTotal = 0;
int playerTwoTotal = 0;
for (int x = 0; x<random.length; x++) {
random[x] = x;
}//Content setup for random array
Random rndNum = new Random();//Random init
int i = 0;
for (i = 0; i < deck.length; i++) {
deck[i] = faces[i % 13] + suit[i % 4];
}//Deck of cards setup
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(deck));//Changing Array with card contents into an ArrayList
while (deckComplete == false) { //While loop for dealing cards
for (int j = deck.length; j >= 1; j--) {
// System.out.println("Hit enter to be dealt a card!");
String readString = scanner.nextLine(); //Set variable "readString" to user input
int randomNumber = rndNum.nextInt(j);
int randomNumberTwo = rndNum.nextInt(j);
if (readString.equals("")) { //If user input equals "enter"...
if (randomNumber >= arrayList.size()) {
randomNumber = arrayList.size() - 1;
}
if (randomNumberTwo == arrayList.size()) {
randomNumberTwo = arrayList.size() - 1;
}
int playerOne = random[randomNumber];
int playerTwo = random[randomNumberTwo];
int playerOneScore = 0;
int playerTwoScore = 0;
System.out.println("Player One Draws a: " + arrayList.get(random[randomNumber])); //Print out card
arrayList.remove(random[randomNumber]); //Remove card from deck
System.out.println("Player Two Draws a: " + arrayList.get(random[randomNumberTwo])); //Print out card
arrayList.remove(random[randomNumberTwo]); //Remove card from deck
playerOneTotal = playerOneTotal + playerOneScore;
playerTwoTotal = playerTwoTotal + playerTwoScore;
if (playerOneTotal > playerTwoTotal) {
System.out.println("Player One Wins this round! Current Score - Player One: " + playerOneTotal + " Player Two: " + playerTwoTotal);
}else if (playerOneTotal < playerTwoTotal) {
System.out.println("Player Two Wins this round! Current Score - Player One: " + playerOneTotal + " Player Two: " + playerTwoTotal);
}else if (playerOneTotal == playerTwoTotal) {
}
if (j == 1) { //If program gets to last card...
deckComplete = true; //Set desk complete to true
System.out.println(arrayList.get(random[randomNumber])); //Print last card
arrayList.remove(random[randomNumber]); //Remove last card
System.out.println("You are out of cards!"); //Print "You are out of cards"
break; //Stop loop
}
}
}
除了尝试(下面)之外还有什么方法可以让我得到正确的结果吗?
if (randomNumber >= arrayList.size()) {
randomNumber = arrayList.size() - 1;
}
if (randomNumberTwo == arrayList.size()) {
randomNumberTwo = arrayList.size() - 1;
}
编辑:这是确切的错误消息。
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 33, Size: 23
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at Game.main(Game.java:72)
答案 0 :(得分:1)
如果我读得正确,您每回合就会从ArrayList
选择一张随机卡片。你可以通过在游戏开始时整个ArrayList
来改变你的生活(类似于你在现实生活中如何改变牌组)。然后,您只需删除列表的第一个(或最后一个)元素,而不必担心IndexOutOfBoundsException
。
要对整个套牌进行随机播放,请使用Collections.shuffle
:
Collections.shuffle(fileList, new Random());
从牌组中取出顶牌:
arrayList.remove(0);
答案 1 :(得分:1)
你有deck
这是52张牌的完整列表,按顺序排列。
您创建arrayList
副本,就像您一样,除非您重命名stack
(或cardStack
),然后:
Collections.shuffle()
stack
stack
(或remove(stack.size()-1)
从remove(0)
取卡,但速度较慢。更好的是,使用ArrayDeque
而不是ArrayList
,因为它可以用作LIFO(后进先出)堆栈。在您的情况下,您可以使用stack.pop()
来获取卡片。
<强>跟进强>
为了让游戏发挥作用,一张牌必须不仅仅是文字“Ace of Spade”。你需要知道它是一个Ace,它是一个Spade,所以你需要一个类,例如名为Card
,包含两个字段:suit
和face
。然后该类的toString()
方法将返回“Ace of Spade”。
另请注意,除非您想作弊,否则永远不会使用索引访问cardStack
。在堆栈被洗牌后允许的唯一操作是pop()
,以将卡片放在堆栈的顶部。
你的整体循环看起来像这样:
// Build deck
...
// Create shuffled stack
Deque<Card> cardStack = new ArrayDeque<>(Arrays.asList(deck));
Collections.shuffle(cardStack, rndNum);
// Play game
while (! cardStack.isEmpty()) {
Card player1card = cardStack.pop();
Card player2card = cardStack.pop();
// do you stuff here
}