【问题标题】:JAVA changing from an array to a list and using the shuffle methodJAVA从数组变为列表并使用shuffle方法
【发布时间】:2014-09-25 20:48:20
【问题描述】:

我的任务是创建一副牌并随机发五张牌。我终于让它“工作”了,但我需要一些帮助。我刚刚读到,java 现在有一个 shuffle 方法来打乱列表。我们现在正在使用数组,所以我认为需要数组有没有办法将 shuffle 方法与数组一起使用?如果没有,有人可以指导我切换到列表吗?我认为这将有助于回答我的下一个问题。我唯一要做的就是以某种方式说明在随机发出 5 张牌后牌组中还剩下多少张牌。但是,看到我如何使用数组并且您无法从数组中删除项目,因为它是固定的(对吗?)我想看看是否有一种方法可以模拟从数组中删除卡片以便不处理它们再次?或者将数组转换为列表/集合会更容易吗?

这是我的代码。任何帮助是极大的赞赏。另外,我也会接受有关清理代码的任何建议...

public class CardGame {
    public static void main (String [] args) { 

    DeckOfCards deck = new DeckOfCards();
    //call shuffle
    deck.shuffle(1000);

   Card b;
   for (int i = 0; i < 5; i++) {
       b = deck.deal();
       System.out.println("Deal a card: " + b);  
    }
  }  
}


class Card {

   public static final int SPADE   = 4;
   public static final int HEART   = 3;
   public static final int CLUB    = 2;
   public static final int DIAMOND = 1;

   private static final String[] Suit = {"*", "Hearts", "Clubs", "Spades", "Diamonds"};
   private static final String[] Rank = {"*", "*", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};    

   private int cardSuit;
   private int cardRank;

   public Card( int suit, int rank ) {
      if ( rank == 1 )
         cardRank = 14;     // Give Ace the rank 14
      else
         cardRank = (int) rank;

      cardSuit = (int) suit;
   }

   public int suit() {
      return ( this.cardSuit );     
   }

   public String suitStr() {
      return( this.Suit[ this.cardSuit ] );  
   }

   public int rank() {
      return ( this.cardRank );
   }

   public String rankStr() {
      return ( Rank[ this.cardRank ] );
   }

   public String toString() {
      return ( Rank[ this.cardRank ] + " of "+ Suit[ this.cardSuit ] );
   }
}

class DeckOfCards {
   public static final int NEWCARDS = 52;
   private Card[] deckOfCards;         // Contains all 52 cards
   private int currentCard;            // deal THIS card in deck

   public DeckOfCards( ) {
      deckOfCards = new Card[ NEWCARDS ];
      int i = 0;

      for (int suit = Card.DIAMOND; suit <= Card.SPADE; suit++)
         for ( int rank = 1; rank <= 13; rank++ )
             deckOfCards[i++] = new Card(suit, rank);
             currentCard = 0;
   }
  //shuffle(n): shuffle the deck
   public void shuffle(int n) {
      int i, j, k;

      for ( k = 0; k < n; k++ ){ 
      i = (int) ( NEWCARDS * Math.random() );  // Pick 2 random cards
      j = (int) ( NEWCARDS * Math.random() );  // in the deck

      //swap these randomly picked cards
      Card temp = deckOfCards[i];
      deckOfCards[i] = deckOfCards[j];
      deckOfCards[j] = temp;
      }
      currentCard = 0;   // Reset current card to deal
   }

   //deal(): deal deckOfCards[currentCard] out
   public Card deal() {

      if (currentCard < NEWCARDS) {
         return ( deckOfCards[currentCard++] );
      }
      else{
         System.out.println("Out of cards error");
         return ( null );  // Error;
      }
   }

   public String toString() {
      String s = "";
      int k;
      k = 0;

      for ( int i = 0; i < 4; i++ ) {        
          for ( int j = 1; j <= 13; j++ )
             s += (deckOfCards[k++] + " ");
             s += "\n";
     }
      return (s);
   }
}

在得到所有帮助后,我决定重写我的代码,这就是我得到的结果,但我在将它们整合在一起并使其正常工作时遇到了一些麻烦!

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

public class CardGame {
    public static void main (String [] args) { 

    DeckOfCards deck = new DeckOfCards();
    //call shuffle
    deck.shuffle();

   Card b;
   for (int i = 0; i < 5; i++) {
       b = deck.deal();
       System.out.println("Deal a card: " + b);  
   }
 }  
}



class Card {

enum Suit {
   HEARTS(1), 
   CLUBS(2), 
   DIAMONDS(3), 
   SPADES(4);

  private int suitValue;

  private Suit (int suitValue)
  {
    this.suitValue = suitValue;
  }

  public int getSuitValue()
  {
    return suitValue;
  }  
}

private Suit suit;
private Value value;

 public Card (Suit suit, Value value)
{
this.suit = suit;
this.value = value;
}

public Suit getSuit() {
    return suit;
}
public Value getValue() {
    return value;
}

/*
public int compareTo(Card o) {

  return 0;
  }
 } */

class DeckOfCards 
{
 private List<Card> cards = new ArrayList<Card>();

 public DeckOfCards () {

 for (Suit suit : Suit.values()) {
     for (Value value : Value.values()) {
        Card card = new Card(suit, value);
        cards.add(card);
  }
 }
}

  public List<Card> getCards() {
      return cards;
  }

  public void shuffleDeckOfCards() {
       Collections.shuffle(cards);
  }


 public String toString() {
     return this.Value + " of "+ this.Suit;
  }
 }

【问题讨论】:

  • 从数组中移除卡片 - 设置引用 = null。将数组转换为列表,随机播放,然后重新转换为数组。
  • 我实际上刚刚收到我教授的回复,他希望我们只使用数组。 “对于作业,我希望你使用数组,因为我们还没有介绍列表。由于牌是按顺序从牌堆中发牌的,你可以计算从数组中发了多少张牌,然后使用这个计数从数组中检索下一张卡片。"

标签: java arrays list methods collections


【解决方案1】:

这是一个完整的示例程序,它演示了您需要的所有东西 - 从数组中洗牌和移除卡片。

示例卡类:

public class Card {
    private String value = "";

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Card(String value) {
        super();
        this.value = value;
    }

}

示例程序:

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

public class CardGame {

    public static void main(String[] args) {

        List<Card> pack = new ArrayList<Card>();
        Card c1 = new Card("c1");
        Card c2 = new Card("c2");
        Card c3 = new Card("c3");
        pack.add(c1);
        pack.add(c2);
        pack.add(c3);

        System.out.print("List : ");
        CardGame.displayCardList(pack);

        Card[] packArr = cardListToArray(pack);

        System.out.print("Array : ");
        CardGame.displayCardArray(packArr);

        // http://stackoverflow.com/questions/4228975/how-to-randomize-arraylist
        long seed = System.nanoTime();
        Collections.shuffle(pack, new Random(seed));

        System.out.print("Shuffle List : ");
        CardGame.displayCardList(pack);

        packArr = cardListToArray(pack);

        System.out.print("Shuffle Array : ");
        CardGame.displayCardArray(packArr);

        System.out.print("Remove Card from Array : ");
        CardGame.removeCardFromArray(packArr, new Card("c1"));
        CardGame.displayCardArray(packArr);

    }

    public static boolean removeCardFromArray(Card[] packArr, Card card) {

        boolean cardFound = false;

        for (int i = 0; i < packArr.length; i++) {

            if (packArr[i].getValue().equalsIgnoreCase(card.getValue())) {
                packArr[i] = null;
                cardFound = true;
                break;
            }

        }

        return cardFound;

    }

    public static Card[] cardListToArray(List<Card> pack) {

        Card[] packArr = new Card[pack.size()];

        for (int i = 0; i < pack.size(); i++) {
            packArr[i] = pack.get(i);
        }

        return packArr;

    }

    public static void displayCardList(List<Card> pack) {

        for (Card c : pack) {
            System.out.print(c.getValue() + ", ");
        }
        System.out.println();
    }

    public static void displayCardArray(Card[] packArr) {

        for (Card c : packArr) {

            if (c == null) {
                System.out.print("REMOVED, ");
            } else {
                System.out.print(c.getValue() + ", ");

            }

        }
        System.out.println();
    }

}

【讨论】:

  • 谢谢波拉特!我正在尝试重写我的代码,所以这肯定会有所帮助!您将如何处理此处样本中的五张随机牌并显示牌组中还剩多少张牌?
【解决方案2】:

卡片

在 Card 类中,花色应该是一个枚举。你可以像这样创建枚举。

enum Suit {

    SPADE,
    HEART,
    CLUB,
    DIAMOND
};

那么这个类应该包含它当前西装的一个变量,比如

Suit suit;

你可以很容易地改变它的值。

suit = Suit.HEART;

如果你必须使用索引来访问你可以使用的西装

suit = Suit.values()[index];

当得到你可以使用的卡片的等级时

return Rank[suit.ordinal()];

Card 类中的函数名称不是您应该使用的典型名称。其中一些应该是吸气剂。我会推荐像 getSuit() 和 getSuitName() 这样的名字,你想要的名字只是通过阅读它们就可以理解它们的作用。像 suit() 这样的名字有点令人困惑,他们不会告诉你他们用 suit 做了什么。

DeckOfCards

在 DeckOfCards 类中,初始化卡组时,为花色使用 for each 循环。

for (Suit suit : Suits.values()) {

    ...
}

这将遍历所有西装。

如果你想切换到一个列表,你应该将你的私有变量 deckOfCards 声明为一个 ArrayList。

private List<Card> deckOfCards = new ArrayList<>();

如果您以前没有使用过列表,这是创建卡片对象的列表。菱形运算符 () 假定对象类型来自您之前指定的类型 (Card) 这是 java 7 的功能,如果您使用的是旧版本,您将使用

new ArrayList<Card>();

您可以使用 add() 函数添加一张卡片,而不是跟踪您在牌组中的位置

deckOfCards.add(card);

这将允许您使用 Collections.shuffle(deckOfCards) 随机洗牌。

要访问卡片,请使用 get(int i) 函数

deckOfCards.get(index);

如果您仍在使用数组,则在洗牌时使用 Random 对象。扔一个

Random random = new Random();

在你们班的乞求中。 for 循环的内部可能是这样的

int i = random.nextInt(NEWCARDS);
int j = random.nextInt(NEWCARDS);

Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;

在 shuffle 函数中,我会更改 i、j 和 k 的名称。变量 K 应该被称为 i 因为它是迭代器。变量 j 和 k 应该重命名为更有意义的名称。

如果您想将数组转换为可以使用的列表

Arrays.asList(new ArrayList<Card>());

与此相反,转换回数组。

list.toArray();//This will return an array of Objects[]

Card[] cards = new Card[NEWCARDS];

list.toArray(cards)//This will store the list into the array cards.
//Note if the lists is bigger than the array it is storing it in, the function will return a new array that can hold all of the elemnents in the list.

注意:在这些示例中,我一直在使用 ArrayList,您可能需要研究 List 类的其他实现。

个人喜好

除了 Card 类的 toString() 之外,我会删除 return 语句中的括号。

在代码中使用括号(例如 DeckOfCards 构造函数)时,会有一些额外的空格。我会这样的

public DeckOfCards() {

括号内的内容周围也不应该有空格,例如

i = (int) ( NEWCARDS * Math.random() );

//should be

i = (int) (NEWCARDS * Math.random());

【讨论】:

  • 太棒了,谢谢gyroninja!我正在尝试重写整个内容,但事实证明这很困难!不过我来得很慢,谢谢你的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多