2

私はソリティアカウントプログラムに取り組んでいます。私はすでにメインプログラムを動作させていますが、自分のクラスを実装しようとすると、19行目でNullPointerExceptionエラーが発生します(到達するたびにc.getRank)。

最初にメインプログラムを作成し、CardDeckそれが機能するために必要なすべての関数を含むというクラスをインポートしましたが、今はまったく同じことを行う独自のクラスを作成することになっています。CardDeck(インポートされたクラスにアクセスできないことに注意してください)。

メインコードは次のとおりです。

import se.lth.cs.ptdc.cardGames.Card;

public class Patiens {
public static void main(String[] args) {
    double good = 0;
    double bad = 0;
    double result = 0;

    for (int a = 0; a < 1000000; a++) {
        CardDeck deck = new CardDeck();
        deck.shuffle();
        double fail = 0;
        while (deck.moreCards()) {

            for (int i = 1; i <= 3 && deck.moreCards(); i++) {

                Card c = deck.getCard();

                if (i == 1 && c.getRank() == 1) {
                    fail++;
                }

                if (i == 2 && c.getRank() == 2) {
                    fail++;
                }

                if (i == 3 && c.getRank() == 3) {
                    fail++;
                }
            }
        }
        if (fail >= 1) {
            bad++;      
        }
        else{
            good++;
        }
    }
    System.out.println("Good: " + good + " Bad: " + bad);
    result = good / bad;
    System.out.println("Result= " + result);
}

}

それがすることは、私のデッキが正常に終了する確率を数えることです:

カードを引くと同時に1-2-3、1-2-3を数えます。これで、カードが「1」を数えたときにたまたまACEである場合、現在のデッキは失敗します。プログラムが「2」などを数えている間、ランク2のカードについても同じことが言えます。一度失敗することなく終了する確率は0.8%です。

これが私が作成しているCardDeckクラスです:

import se.lth.cs.ptdc.cardGames.Card;

import java.util.Random;

public class CardDeck {
    private Card[] cards;
    private int current;
    private static Random rand = new Random();

    public CardDeck() {
        cards = new Card[52];
        for(int suit = Card.SPADES; suit <= Card.CLUBS; suit++) {
            for (int i = 0; i < 13; i++) {
                cards[i * suit] = new Card(suit, i);
            }
        }
        current = 0;
    }

    public void shuffle() {
        Card k;
        for(int i = 1000; i > 0; i--) {
            int nbr = rand.nextInt(52);
            int nbr2 = rand.nextInt(52);
            k = cards[nbr2];
            cards[nbr2] = cards[nbr];
            cards[nbr] = k;
        }
    }

    /**
     *Checks for more cards
     */
    public boolean moreCards() {
        if(current > 51) {
            return false;
        } else {
            return true;
        }
    }

    /**
     *Draws the card lying on top.
     */
    public Card getCard() {
        return cards[current++];

    }
}

これがimport se.lth.cs.ptdc.cardGames.Card;必要に応じて、カードを作成するクラスです。

package se.lth.cs.ptdc.cardGames;

public class Card {
    public static final int SPADES = 1;
    public static final int HEARTS = SPADES + 1;
    public static final int DIAMONDS = SPADES + 2;
    public static final int CLUBS = SPADES + 3;

    private int suit;
    private int rank;

    public Card(int suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public int getSuit() {
        return suit;
    }

    public int getRank() {
        return rank;
    }
}

(上記のクラスを変更することは想定されていないことに注意してください)

4

3 に答える 3

4

あなたの問題はここにあります:

cards[i * suit] = new Card(suit, i);

これを次のように変更した場合:

cards[i + ((suit - 1) * 13)] = new Card(suit, i);

それはあなたが期待することをします。

考慮すべき2つのこと:最初に、配列はゼロベースであるため、最初のカードはインデックス0にある必要があります。次に、スーツを掛けると、その数の倍数が得られます。例:

  • スペード:1、2、3、4、5、6、7、8、9、10、11、12、13
  • ハーツ:2、4、6、8、10..。
  • ダイヤモンド:3、6、9、12..。
  • クラブ:4、8、12、16..。

したがって、一部の要素は複数回入力され(12は4回入力されます)、一部の要素(特定の素数> 13)の要素(23など)はnullになります。一般に、次のように、インデックスを別の変数で表すだけでおそらく十分です。

int cardIndex = 0;
for (int suit = Card.SPADES; suit <= Card.CLUBS; suit++) {
    for (int i = 0; i < 13; i++) {
        cards[cardIndex++] = new Card(suit, i);
    }
}
于 2012-11-15T09:52:19.730 に答える
1

1ベースのインデックス(で行う)を使用すると期待どおりに機能しないため、配列には要素CardDeck.cardsが含まれますnulli * suitCard.SPADES

于 2012-11-15T09:49:55.937 に答える
0

Cardオブジェクトを返す代わりに、クラスのgetCard()メソッドが戻るようです。メソッドを確認し、戻る前にCardobjを出力してください。CardDecknullgetCard()

于 2012-11-15T09:49:29.347 に答える