我正在写纸牌游戏" war"。 我的课程:
主要DeckOfCards
和Card
:
import java.util.*;
public class DeckOfCards
{
private ArrayList<Card> deck;
private static final Random randomNumbers=new Random();
public DeckOfCards()
{
deck=new ArrayList<Card>();
}
public DeckOfCards(int cardsFaces) //normal deck has 4 faces
{
deck=new ArrayList<Card>();
for (int i=0;i<cardsFaces;i++)
for (int j=2;j<=14;j++)
{
deck.add(new Card(j));
}
}
public void shuffle()
{
for(int first=0;first<deck.size();first++)
{
int second =randomNumbers.nextInt(deck.size()-1);
Card temp=deck.get(first);
deck.set(first, deck.get(second));
deck.set(second, temp);
}
}
public Card dealCard()
{
if (deck.isEmpty())
{
System.out.println("trying to deal from empty deck");
return null;
}
else
return deck.remove(0);
}
public ArrayList<Card> getDeck()
{
return deck;
}
public String toString()
{
String s="";
for (int i=0;i<deck.size();i++)
{
s=s+deck.get(i)+" ";
}
return s;
}
public boolean isEmpty()
{
return (deck.isEmpty());
}
public void addCard(Card c)
{
deck.add(c);
}
public int size()
{
return deck.size();
}
}
public class Card
{
private int value;//2-14 , 14 is ace.
public Card(int value)
{
this.value=value;
}
public int getValue()
{
return value;
}
public String toString()
{
return Integer.toString(value);
}
}
public class Main
{
public static void main(String[] args)
{
DeckOfCards gameDeck =new DeckOfCards(1);
gameDeck.shuffle();
DeckOfCards p1Deck=new DeckOfCards();//player 1 deck
DeckOfCards p2Deck=new DeckOfCards(); //player 2 deck
DeckOfCards sideDeck=new DeckOfCards();
Card p1Card;
Card p2Card;
boolean gameOver=false;
while(!gameDeck.isEmpty()) //dealing cards to players
{
p1Deck.addCard(gameDeck.dealCard());
p2Deck.addCard(gameDeck.dealCard());
}
while(gameOver==false)
{
p1Card=p1Deck.dealCard();
p2Card=p2Deck.dealCard();
System.out.println("p1card="+p1Card.getValue()+" p2card="+p2Card.getValue());
if(p1Card.getValue()>p2Card.getValue()) //player 1 won the cards
{
p1Deck.addCard(p1Card);
p1Deck.addCard(p2Card);
while(!sideDeck.isEmpty())
p1Deck.addCard(sideDeck.dealCard());
System.out.println("player 1 won the cards,deck sizes: p1:"+p1Deck.size()+" p2:"+p2Deck.size());
}
if(p2Card.getValue()>p1Card.getValue()) //player 2 won the cards
{
p2Deck.addCard(p1Card);
p2Deck.addCard(p2Card);
while(!sideDeck.isEmpty())
p2Deck.addCard(sideDeck.dealCard());
System.out.println("player 2 won the cards,deck sizes: p1:"+p1Deck.size()+" p2:"+p2Deck.size());
}
while(p1Card.getValue()==p2Card.getValue()) //war
{
System.out.println("war");
sideDeck.addCard(p1Card);
sideDeck.addCard(p2Card);
if(p1Deck.size()>3 && p2Deck.size()>3)
{
for(int i=0;i<2;i++)
{
sideDeck.addCard(p1Deck.dealCard());
sideDeck.addCard(p2Deck.dealCard());
}
}
else
{
winner(p1Deck,p2Deck,true);
}
}
if(winner(p1Deck,p2Deck,false))
gameOver=true;
}
}
public static boolean winner(DeckOfCards p1Deck,DeckOfCards p2Deck,boolean war)
{
if(p1Deck.isEmpty()|| p1Deck.isEmpty())
{
if(p1Deck.isEmpty())
System.out.println("player 2 is the winner");
else
System.out.println("player 1 is the winner");
return true;
}
if (p1Deck.size()<3 && p2Deck.size()<3 && war==true)
{
System.out.println("it's a tie");
return true;
}
return false;
}
}
我得到NullPointerException
并且不知道为什么。
当我按下异常时它会引导我去行:
System.out.println("p1card="+p1Card.getValue()+" p2card="+p2Card.getValue());
当试图调试时,我理解有时由于某种原因我的dealCard
函数返回null
,尽管我尝试处理的套牌不是空的。
2输出例如:
输出1:
trying to deal from empty deck
p1card=10 p2card=5
player 1 won the cards,deck sizes: p1:8 p2:6
p1card=13 p2card=14
player 2 won the cards,deck sizes: p1:7 p2:7
p1card=11 p2card=2
player 1 won the cards,deck sizes: p1:8 p2:6
p1card=9 p2card=12
player 2 won the cards,deck sizes: p1:7 p2:7
p1card=6 p2card=7
player 2 won the cards,deck sizes: p1:6 p2:8
p1card=4 p2card=8
player 2 won the cards,deck sizes: p1:5 p2:9
Exception in thread "main" java.lang.NullPointerException
at mmn11q2.Main.main(Main.java:25)
输出2:
trying to deal from empty deck
p1card=8 p2card=10
player 2 won the cards,deck sizes: p1:6 p2:8
p1card=7 p2card=13
player 2 won the cards,deck sizes: p1:5 p2:9
p1card=6 p2card=4
player 1 won the cards,deck sizes: p1:6 p2:8
p1card=12 p2card=11
player 1 won the cards,deck sizes: p1:7 p2:7
p1card=5 p2card=3
player 1 won the cards,deck sizes: p1:8 p2:6
p1card=2 p2card=14
player 2 won the cards,deck sizes: p1:7 p2:7
Exception in thread "main" java.lang.NullPointerException
at mmn11q2.Main.main(Main.java:25)
答案 0 :(得分:0)
游戏从套牌中的无效状态开始,如#34所示;试图从空白牌组处理#34;在开始的输出中。
while(!gameDeck.isEmpty()) //dealing cards to players
{
p1Deck.addCard(gameDeck.dealCard());
p2Deck.addCard(gameDeck.dealCard());
}
检查牌组是否有 牌,但尝试交易两张牌 - 因为源牌组有奇数牌,这导致p2Deck有牌入场无。一旦访问此条目(作为该套牌中的最后一项,您将获得例外。
防止此类问题的有用通用解决方案是尝试正确的测试。
例如,测试一下&#39; shuffle&#39;重复洗牌的方法,然后检查牌组是否突然不包含Null值作为其中一项。
此外,防御性编程有帮助 - 每个函数都应该验证输入是否有效,以防止其他地方的错误导致该类中的无效状态。如果你的addCard方法会检查参数是否是有效的卡(而不是None),那么这个bug显然是可见的。
在dealCard函数中进行检查,以验证它是否意外地从数组中处理Null值 - 这是另一个可能的错误来源。
&#34;不要重复自己&#34;是一个有用的口头禅。例如,您的代码有多个地方,如&#34; p1Deck.addCard(gameDeck.dealCard());&#34;,并且每个这样的地方都有一个单独的检查,如果源平台不是空的,否则会是一个错误并返回一个空值。这表明你可能需要一种尝试在两个套牌之间传递卡片的方法,如果一个卡片变空,就不会改变它们。
答案 1 :(得分:0)
您的dealCard
方法会从Deck
public Card dealCard()
{
if (deck.isEmpty())
{
System.out.println("trying to deal from empty deck");
return null;
}
else
return deck.remove(0); // <<<< here
}
所以在一些dealCard
次调用之后,牌组是空的。当dealCard
为空(见上文)时,null
会返回Deck
,因此是NPE。