我正在努力学习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次。这样,我的套牌对象的最后五张牌都是随机选择的,并且它们不可能被选中两次。我认为最简单的方法(我还没有尝试)将创建一个变量,它保存我的一个牌组索引的值,以便我可以交换它们。你们有人同意吗?
非常感谢任何帮助!
答案 0 :(得分: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]
)会起作用。
答案 1 :(得分: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)
答案 2 :(得分: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
游戏。
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();
}
}
答案 3 :(得分: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;
}
错误1:不要用常数来初始化Random
。这将使您的伪随机序列始终完全相同。
错误2:您的声明Deck deck
错误,或您尝试访问deck[index]
的方式,因为deck
未声明为数组。由于Deck
是一个代表卡片集合的类,因此更合乎逻辑的罪魁祸首是后一行。更改为适当Deck
方法的调用。
在不知道Deck
的实现的情况下,无法知道正确的代码。如果Deck
本质上是随机牌组,那么你应该选择前5名。如果它是完全排序的(这不是一个真实的牌组,我应该添加),那么你需要随机选择卡掉了。 Deck
类至少应该有一个remove
方法,可以立即解决重复问题。
答案 4 :(得分:1)
对卡片进行随机播放并选择,这比使用随机选择更好,因为有可能重复但是如果你使用随机播放则不会。您可以使用Collections#shuffle
。