Replace cards at the bottom of the deck

I am a beginner with java and created a 2-cool VideoPoker program that basically simulates the 5-draw of the same name. In this game, the deck of cards is shuffled and the top 5 cards (now the shuffled deck) are used to play 5 draws. The user can remove one, all or none of the 5 cards that are given to him when the cards are dealt. If the user removes the card, it will be removed and replaced with the next top card. I am stuck at the point where the user decides to delete the card. In my program, when someone removes all the cards, or sometimes even some, card # 2 (index 1) and card # 4 (index 3) always remain in the next hand (5 cards), My attempt is in the PICTURE BELOW code:

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 (tester program):

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:

output

+3


source to share


2 answers


Your problem is here:

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
    }
}

      

In this block, you are asking the user if they want to remove the card at a specific location, but think about it. If the user says, "Yes, I want to delete the first card!", You delete the top card at index 0, which is good. But this is also where the problem comes in, because you now have a whole new deck! A card that was previously at index 1 (in your example it is 10 from Hearts) is now actually at index 0. So essentially you treat the deck as if it never changes when in fact it has the ability to dynamically change and you don't take that into account in your code.



Possible (albeit crude) solution :

// 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);
}

      

+2


source


The problem comes down to how you implement the logic of the deck. Instead of using an ArrayList to store your cards and then indexing through it, you should use an ArrayDeque (pronounced "array deck") to handle the storage and disposal logic.

You must track the contents of the player's hand separately from the deck; the main issue is how you use the player's deck and hand. By making your program more general, you can remove most of the complexity.



In the same vein, which makes the program more general, you should also use a separate class for handling maps. No need to be fancy: just two public final fields, a constructor and a toString method.

+1


source







All Articles