0

Javaでカードゲーム「UNO」を作ってみました。プレーヤーがカードをプレイするとき、他の要素を左にシフトして手札から取り除く必要があります。パラメータとして int n を取り、破棄されるカードを参照します。メソッドは、クラスのフィールドとして指定したカード配列を変更する必要があります。これは、カードまたはプレイヤーの手であるオブジェクトの配列です。実行すると、nullPointerException が生成されます。エラーが発生する理由はわかっていますが、修正方法がわかりません。また、配列リストの使用を避けようとしています。また、破棄されたカードを印刷できるように戻します。ありがとう。

public Card removeCardFromHand(int n)
{
    Card c = cards[n];
    Card[] tempCards = new Card[cards.length - 1];
    for(int i = 0; i < n; i++)
    {
        tempCards[i] = cards[i];
    }
    for(int i = n; i < cards.length; i--)
    {
        tempCards[n] = cards[n + 1];
    }
    cards = tempCards;
    return c;
} 

エラーコード:

java.lang.ArrayIndexOutOfBoundsException: 7

at Player.removeCardFromHand(Player.java:86)
at BUno.executeOnePlay(BUno.java:112)
at BUno.play(BUno.java:70)
at BUno.main(BUno.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)

この場合、プレイヤーが 7 枚のカードを持っていたために発生しています。7 番目のインデックスが削除されると、その 7 番目のインデックスは空になりました。プレイヤーがカードを引かなければならないときにカードを追加する同様の方法を書きましたが、問題なく動作しました。配列リストやベクトルを扱っていない次の試験の練習をしているので、それらを使用しても意味がありません。

4

3 に答える 3

2
for(int i = n; i < cards.length; i--)
{
    tempCards[n] = cards[n + 1];
}

それは何ですか?:-)

差し迫った3つの問題。n1 つ目は、正しい ではなく、ループ内の配列インデックスで使用していることですi

2 つ目は、それを修正しても、配列の末尾を超えてしまうことです。

i3 つ目は、デクリメントするのではなく、インクリメントする必要があるということです。iそれを減分すると、常に 未満になるため、ループが永久に実行されることを意味しますcards.length。そして、永遠に、私はあなたが何かをしようとし始める時点までを意味しますcards[-1]:-)

代わりに、次のことを試してください。

for (int i = n; i < cards.length - 1; i++)
    tempCards[i] = cards[i + 1];
于 2012-04-30T02:37:09.660 に答える
1

2 番目のforループは、期待どおりの動作をしていません。継続的tempCards[n] = cards[n+1]に減分している間、何度も再割り当てしています。i

for(int i = n; i < cards.length; i--) 
    { 
        tempCards[n] = cards[n + 1]; 
    } 

i例では、cards.length よりも小さい 3 のような値で始まるように見えます。その後、2、1、0 i、-1、-2 などに減少します。

于 2012-04-30T02:37:33.653 に答える
0

配列に依存する代わりに、 LinkedListを使用できます。Cardプレイヤーの手札へのアイテム (a) の削除と追加がより高速になります。

あなたが投稿したコードには 2 つの問題があります。最初のものは潜在的な同時アクセスです (ただし、より高いレベルで処理する可能性があります): 一方、1 つのカードの削除が完全に完了していないときにカードを追加することは可能ですか?

2番目のものはここにあります:

for(int i = n; i < cards.length; i--) 
{ 
   tempCards[n] = cards[n + 1]; 
}

逆方向にコピーする必要があります ( i++)。そうしないと、tempCard に {Card1, Card2, ..., Card n-1, Card n+1, Card n, Card n -1 ... Card 2, Card 1} または index > card.lengh / 2 のカードを削除しようとすると、ArrayIndexOutOfBound でクラッシュします

于 2012-04-30T02:46:41.583 に答える