从卡座底部更换卡片

时间:2014-12-08 02:14:32

标签: java arrays for-loop arraylist collections

我是java的初学者并创建了一个2类程序“VideoPoker”,它基本上模仿了一人5画的游戏。在这个游戏中,一副纸牌被洗牌,前5张牌(现在洗牌的牌)被用来进行5次抽牌。当发牌时,用户可以移除他/她给出的5张牌中的一些,全部或全部。如果用户删除了卡,则会将其删除并替换为 next 顶部卡。我被困在用户决定取出卡的位置。在我的程序中,当有人删除所有卡或有时甚至只有一些卡时,卡#2(索引1)和卡#4(索引3)始终保留在下一手牌(5张卡)中。我的尝试是在代码 PICTURE BELOW

Deck.java:

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

public class Deck {
    // Constructing a deck from two arrays
    String[] suit = { "C", "D", "H", "S" };
    String[] rank = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
    ArrayList<String> deck = new ArrayList<String>(suit.length * rank.length);
    int currentCard = 0;

    // Storing public variables
    int suits = suit.length;
    int ranks = rank.length;
    int deckSize = deck.size();

    // Constructs a deck with 52 cards
    public Deck(){
        for(int i = 0; i < suits; i ++){
            for(int j = 0; j < ranks; j++){
                String temp = rank[j] + suit[i];
                deck.add(temp);
            }
        }
    }

    public String toString(){
        return Arrays.deepToString(deck.toArray());    
    }

    // Fisher-Yates Shuffle 
    public ArrayList<String> shuffle(){
        Collections.shuffle(deck);
        return deck;
    }

    public String deal(){
        return deck.get(currentCard++);
    }

    public String remove(int i){
        return deck.remove(i);
    }

    public String get(int i){
        return deck.get(i);
    }

    public ArrayList<String> getList(){
        return deck;
    }
}

Dealer.java(测试人员程序):

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Dealer {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        Deck testDeck = new Deck();

        System.out.println(testDeck);

        testDeck.shuffle();

        System.out.println(testDeck);

        for (int i = 0; i < 5; i ++){
            System.out.print(testDeck.deal() + " "); 
        }

        String choice;

        for (int i = 0; i < 5; i++){
            System.out.print("\nWould you like to remove card " + (i + 1) + "? ");
            choice = in.next();
            if (choice.equals("Y")){
                testDeck.remove(i);
            }
        }

        for (int i = 0; i < 5; i++){
           System.out.print(testDeck.get(i) + " ");  
        }
    }
}

输出:

output

2 个答案:

答案 0 :(得分:2)

你的问题在这里:

for (int i = 0; i < 5; i++){
    System.out.print("\nWould you like to remove card " + (i + 1) + "? ");
    choice = in.next();
    if (choice.equals("Y")){
        testDeck.remove(i); // <-- removing the 'i'th element is the problem
    }
}

在此块中,您询问用户是否要在特定位置移除卡,但请考虑这一点。如果用户说,&#34;是的!我想删除第一张卡!&#34;,你删除索引0处的顶牌,这很好。但它也是问题出现的地方,因为现在你有一个全新的套牌!之前在索引1的卡片(在你的例子中它是10个心脏)现在实际上在索引0处。所以从本质上讲,你正在对待甲板,就像它永远不会改变,而实际上它有可能动态改变和你在代码中没有考虑到这一点。

一种可能的(尽管是粗略的)解决方案

// a list used to store the index of cards to be removed    
ArrayList<Integer> indexesToRemove = new ArrayList();

for (int i = 0; i < 5; i++) {
    System.out.print("\nWould you like to remove card " + (i + 1) + "? ");
    choice = in.next();
    if (choice.equals("Y")) {
        indexesToRemove.add(i); // record index of card to be removed
    }
}

// here we remove the cards all at once    
for(int i = 0; i < indexesToRemove.size(); i++) {
    // each iteration is a guaranteed removal so
    // we subtract by i to counteract for each subsequent removal
    testDeck.remove(indexesToRemove.get(i) - i);
}

答案 1 :(得分:1)

问题归结于您实现卡座逻辑的方式。您应该使用ArrayDeque(发音为“array deck”)来处理存储和删除逻辑,而不是使用ArrayList存储卡,然后通过它进行索引。

你应该与牌组分开追踪牌手的内容;主要的探测器就是你将甲板和玩家的手耦合在一起。通过使您的程序更加通用,您可以消除大部分复杂性。

在使程序更通用的同一方面,你还应该使用一个单独的类来处理卡片。不过不需要花哨:只有两个公共final字段,一个构造函数和一个toString方法。