[英]Creating a card shuffling program Java
我正在嘗試在 java 中創建一個洗牌器,通過執行進出洗牌來執行“完美洗牌”(將牌組分成兩等分並交錯每張牌,然后再重復一次)。 我有以下代碼來執行隨機播放。
public class Shuffle {
private static final int shuffleCount = 2;
private static final int valueCount = 52;
public static void main(String[] args){
System.out.println("Result of " + shuffleCount + "perfect shuffles" );
int[] value1 = new int[valueCount];
for (int i = 0; i < value1.length; i++){
value1[i] = i;
}//ends valueCount for loop
for (int j = 1; j <= shuffleCount; j++){
riffleShuffle(value1);
System.out.println(" " + j +":\n");
for(int k = 0; k < value1.length; k++){
System.out.println(" " + value1[k]);
}
System.out.println();
}//ends shuffleCount for loop
System.out.println();
}
public static void riffleShuffle(int[] value){
int[] temp = new int[value.length];
int startFirst = 0;
int startSecond = value.length / 2;
for (int i = 0; i < value.length; i+=2){
temp[i] = value[startFirst];
temp[i+1] =value[startSecond] ;
startFirst ++;
startSecond ++;
}
for (int i =0; i< value.length; i++)
value[i] = temp[i];
}
}
我正在嘗試將它實現到我的甲板類中,而不是將數字 0-52 洗牌,而是將一副牌洗牌。 我的甲板課程如下所示;
public class Deck {
private List<Card> cards;
private int size;//number of cards in deck
public Deck(String[] faces, String[] suits, int[] values){
cards = new ArrayList<Card>();
for(String suit: suits)
for(int value = 0; value < values.length && value < faces.length; value++){
Card a = new Card(faces[value], suit, values[value]);
cards.add(a);
}
size = cards.size();
shuffle();
}//ends deck
public boolean isEmpty(){
return cards.isEmpty() && size == 0;
}//ends isEmpty
public int size(){
return cards.size();
}//ends size
public void shuffle(){
for (int i = cards.size() - 1; i > 0; i--){
int pos = 0;
Card a = cards.remove(pos);
cards.add(i, a);
}
}//ends shuffle
public Card deal(){
size --;
Card a = cards.get(size);
return a;
}//ends Card deal
@Override
public String toString(){
String deck_rtn = "\nsize = " + size + "\n\nUndealt cards: \n\n";
for(int k = size -1; k >= 0; k--){
deck_rtn = deck_rtn + cards.get(k);
if (k != 0){
deck_rtn = deck_rtn + ", ";
}//ends first if
if ((size - k) % 2 == 0) {
deck_rtn = deck_rtn + "\n";
}//ends second if
}
deck_rtn = deck_rtn + "\nDealt cards: \n";
for (int k = cards.size() - 1; k >= size; k--){
deck_rtn = deck_rtn + cards.get(k);
if (k != size){
deck_rtn = deck_rtn + ", ";
}
if ((k - cards.size()) % 2 ==0){
deck_rtn = deck_rtn + ", ";
}
}
deck_rtn = deck_rtn + "\n";
return deck_rtn;
我發現我的問題源於試圖在我的套牌類中將它實現到我的 shuffle 方法中。
public void shuffle(){
for (int i = cards.size() - 1; i > 0; i--){
int pos = 0;
Card a = cards.remove(pos);
cards.add(i, a);
}
}//ends shuffle
有人有什么想法嗎? 非常感謝所有幫助,謝謝。 附注。 我盡量避免在任何可能的地方使用快速集合類方法,我是 Java 新手,想在使用集合類之前首先完全理解事物。
我不確定你所說的完美洗牌是什么意思。 java 的 Collections.shuffle 方法有什么問題嗎?
List<Card> cards = new ArrayList<>(52);
Collections.shuffle(cards);
所以,你希望你的牌組(一張桌子)一分為二,然后從每張牌中合並一張牌。
您可以這樣做:
public static Object[] riffleShuffle(Object[] deck){
if (deck.length < 2) return deck; // nothing to shuffle
Object[][] split = split(deck);
return merge(split[0], split[1]);
}
private static Object[][] split(Object[] deck) {
Object[][] split = new Object[2][];
int pivot = (deck.length + 1) / 2; //rounded up
split[0] = copy(deck, 0, pivot);
split[1] = copy(deck, pivot, deck.length);
return split;
}
private static Object[] merge(final Object[] o1, final Object[] o2) {
Object[] merged = new Object[o1.length + o2.length];
for (int i=0; i<merged.length; i++){
if (i%2==0) merged[i] = o1[i/2];
else merged[i] = o2[i/2];
}
return merged;
}
private static Object[] copy(Object[] source, int start, int end){
Object[] copy = new Object[end - start];
for (int i=start; i < end; i++){
copy[i-start] = source[i];
}
return copy;
}
riffleShuffle(Object[] deck)
將接受任何對象。 你可以這樣稱呼它:
Integer[] values = {1,2,3,4,5,6,7,8,9,10,11,12,13};
Object[] result = riffleShuffle(values);
if (result instanceof Integer[]) {
values = (Integer[]) result;
System.out.println(Arrays.toString(values));//[1, 8, 2, 9, 3, 10, 4, 11, 5, 12, 6, 13, 7]
}
如果需要,您可以按Card
更改Integer
。
我不太明白你在 shuffle 方法中想要做什么,但我的建議是:
首先,你不需要private int size;//number of cards in deck
你private int size;//number of cards in deck
因為你可以調用cards.size()
。 也不推薦,因為您的甲板尺寸和您的列表尺寸可能不同。 只要堅持你的 size 方法: public int size(){return cards.size();}
或者在你的情況下,因為你總是把它當作一副普通的紙牌,你可以只使用 52 的常數。
但是我真的不喜歡固定的東西,那么以下方法將洗牌任何大小的牌組:
public void suffle(){
//let's first split the deck in two
List<Card> firstHalf = new ArrayList<>();
List<Card> secondHalf = new ArrayList<>();
int halfSize = cards.size()/2;
if(cards.size()%2 != 0){ //in case the number of cards is odd we have to add one more card to the first half
halfSize += 1;
}
for(int i = 0; i < cards.size(); i++){
if(i < halfSize){
firstHalf.add(cards.get(i));
}else{
secondHalf.add(cards.get(i));
}
} //now we have a split deck, the firstHalf contains the top of the deck and the second half contains the bottom
cards = new ArrayList<>();//empty the main deck to remake it
while(firstHalf.size > 0){ //the first half will always be bigger or have the same size
cards.add(firstHalf.get(0)); //always get the first card, since we will remove it next
firstHalf.remove(0);
if(secondHalf.size() > 0){ //now we are interleaving the cards
cards.add(secondHalf.get(0));
secondHalf.remove(0);
}
}
//now your deck is shuffled
}
編輯:我想我更了解你想要什么,看看這個:
public static void riffleShuffle(List<Cards> value){
List<Cards> temp = new ArrayList<>();
int startFirst = 0;
int startSecond = value.size() / 2;
for (int i = 0; i < value.size(); i += 2){
temp.add(value.get(startFirst));
temp.add(value.get(startSecond);
startFirst ++;
startSecond ++;
}
value = new ArrayList<>();
for (int i =0; i< value.size(); i++){
value.add(temp.get(i));
}
}
程序中的典型 shuffle 是通過所謂的Fisher-Yates
shuffle 完成的,它隨機化一個元素列表。 我想你想模擬一個完美的洗牌,每張卡片都與其他卡片交錯。 這是這樣做的一種方法。
大部分是樣板來演示方法。 方法mergeShuffle
是您可能感興趣的方法。
public static void main(String[] args) {
String suit = "CDHS";
String rank = "KQJT98765432A";
// create a deck of cards..
String[] deck = IntStream.range(0, 52).mapToObj(
i -> "" + rank.charAt(i % 13) + suit.charAt(i / 13)).toArray(
String[]::new);
// show it
display(deck);
deck = mergeShuffle(deck);
System.out.println();
display(deck);
}
public static void display(String[] deck) {
int i = 0;
for (String card : deck) {
System.out.print(card + " ");
i++;
if (i % 13 == 0) {
System.out.println();
}
}
}
public static String[] mergeShuffle(String[] deck) {
String[] shuffledDeck = new String[52];
if (deck.length != 52) {
System.out.println("You're not playing with a full deck. :)");
return null;
}
int i = 0; // destination index of the shuffled deck
for (int k = 0; k < 26; k++) {
shuffledDeck[i++] = deck[k];
shuffledDeck[i++] = deck[k + 26];
}
return shuffledDeck;
}
}
一種更簡單的方法(在拆分時交錯):
public void suffle(){
//let's first split the deck in two
List<Card> firstHalf = new ArrayList<>();
List<Card> secondHalf = new ArrayList<>();
while(cards.size() > 0){//we will split the cards while interleaving them
firstHalf.add(cards.get(0));
cards.remove(0);
if(cards.size() > 0){
secondHalf.add(cards.get(0));
cards.remove(0);
}
}
//now just put the two parts together
cards = new ArrayList<>();
for(int i = 0; i < firstHalf.size(); i++){
cards.add(firstHalf.get(i));
}
for(int i = 0; i < secondHalf.size(); i++){
cards.add(secondHalf.get(i));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.