0

我正在尝试学习 Java,我想做一个非常简单的类,它会从随机生成的一副牌中随机选择 5 张牌。我遇到了一些我觉得应该是一个非常简单的问题来解决的问题。此外,这是针对我就读的大学的一个实验室,所以如果你能够在不给我代码块的情况下指导我,那将是更可取的。

这是我收到的错误,我理解我收到它的原因:

表达式的类型必须是数组类型,但它解析为 Deck

这是我的代码:

public static void main(String[] args) {
    System.out.println(select(5));
}

public static Card[] select(int k)
{
    Random rand = new Random(52);
    Deck deck = new Deck(52);
    Card[] hand = new Card[5];
    for (int j = 0; j < 5; j += 1)
    {
        int index = rand.nextInt(52-j);
        hand[j] = deck[index];
    }
    return hand;
}

Deck.java 和 Card.java 类是由我的导师提供的(他在实验期间不可用)。

我最近也意识到这段代码不会为我做我想要它做的事情,但是我仍然需要找出我上面的错误。如果您想帮助解决我遇到的其他问题,请随时在下面回答我的解释,但这不是我来这里的原因。

我想随机选择5张卡片。假设一张随机选择的卡片位于我的牌组对象的索引 27 处。然后我想将该卡移动到索引 51 并重复 4 次。这样我套牌对象的最后五张牌都是随机选择的,不可能被选择两次。我在想最简单的方法(我还没有尝试过)是创建一个变量来保存我的甲板索引之一的值,以便我可以交换它们。你们中有人同意吗?

任何帮助是极大的赞赏!

4

5 回答 5

4

你有你deck作为类的引用Deck指向一个实例: -

Deck deck = new Deck(52);

所以,你不能在像数组这样的索引上访问它: -

deck[index];  // Cannot do this on a reference pointing to object of `Deck`

我认为你可能需要在你的类中提供一些方法,get(index)并像这样访问它: -deck.get(index)

或者您可能想将您的声明deck为:-

Deck[] deck = new Deck[52];

那么 ( deck[index]) 就可以了。

于 2012-10-23T19:48:13.357 回答
4

只是为了补充已经提到的其他建议,

Card[] hand = new Card[5]; 

应该可能读

Card[] hand = new Card[k]; 

你的 for 循环也是如此:

for (int j = 0; j < 5; j += 1) 

应该读

for (int j = 0; j < k; j += 1)
于 2012-10-23T20:00:56.963 回答
2

你应该做

int index = (52 -rand.nextInt(51)+1);

你还需要Deck[]一个52

  Deck[] deck = new Deck[52];
  for(i to 52)
  //Initalize deck[i] here 
  end.
  Now you can access like deck[index]

我认为使用enum你可以Card更好地实现 Game 。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

// This is just sample example  and it is just to show an approach. I had not enough time    to make code perfect but it works fine.
public enum Deck
{
DECK;
enum Rank
{
    DEUCE(2), THREE(3), FOUR(4), FIVE(5), SIX(6),
    SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11);

    Rank(int rank)
    {
        this.rank = rank;
    }

    private final int rank;

}

enum Type
{
    SPADES,
    HEARTS,
    DIAMONDS,
    CLUBS;
}

class Card
{
    private final Rank rank;
    private final Type type;

    Card(Rank rank, Type type)
    {
        this.rank = rank;
        this.type = type;
    }

    @Override
    public String toString()
    {
        return type.name() + rank.name();
    }

}

static List<Deck.Card> cards = new ArrayList<Deck.Card>();
static
{
    for (Rank rank : Deck.Rank.values())
    {
        for (Type type : Deck.Type.values())
        {
            cards.add(DECK.new Card(rank, type));
        }
    }

}

List<Deck.Card> shuffle()
{
    Collections.shuffle(cards);//Once it is shuffled you can use it to draw first five cards same way we play
    System.out.println(cards);
    System.out.println(cards.size());
    return Collections.unmodifiableList(cards);
}

public static void main(String[] args)
{
    DECK.shuffle();
}
}
于 2012-10-23T19:46:59.860 回答
2
public static Card[] select(int k)
{
  Random rand = new Random(52); // mistake 1
  Deck deck = new Deck(52);     // mistake 2
  Card[] hand = new Card[5];
  for (int j = 0; j < 5; j += 1)
  {
    int index = rand.nextInt(52-j);
    hand[j] = deck[index];     // mistake 2
  }
  return hand;
}

错误一:不要Random用常数初始化。这将使您的伪随机序列始终完全相同。

错误 2:要么您的声明Deck deck错误,要么您尝试访问的方式错误deck[index],因为deck未将其声明为数组。由于Deck是一个代表卡片集合的类,因此更合乎逻辑的罪魁祸首是后一行。更改为适当Deck方法的调用。

如果不知道实现,Deck就不可能知道正确的代码。如果Deck本质上是一副随机的牌,那么你应该只取前 5 名。如果它是完全排序的(我应该补充一下,这不是一个现实的牌),那么你需要从中挑选随机牌。该类Deck至少应该有一个remove方法,可以立即解决您的重复问题。

于 2012-10-23T19:50:19.810 回答
1

对卡片进行洗牌和挑选,这比使用随机选择要好,因为会有重复的机会,但如果你使用洗牌,那就不会了。您可以使用Collections#shuffle.

于 2012-10-23T19:50:42.413 回答