0

I'm trying to find a way to delete a specific card or a random card in a deck and return that deleted card. I've created classes for Card and DeckHand. In the DeckHand class, I'm trying to create a delete method that allows the user to pick a card value, delete ONE instance of that card value from the deck, then returns the card that was deleted, and lastly, shorten the array by 1. I'm also trying to make a deleteAny method that deletes a random card from the deck, returns the card that was deleted, and shorten the array by 1.

For the delete method, I'm having trouble finding a way to say:

*if the value input by the user isn't in the deck, print an error message. *if it is, then find the first instance of a card with that value, delete it, and return the card.

I don't understand how to find the first instance of a card with the value and then finding a way to set an available suit to create the instance of the card to then delete it and shift the positions in the array.

I started trying to do an deleteAny method that deletes a random card. I'm able to get the card output to the user that's getting removed, but I'm getting an error with my method. Any ideas?

Card Class:

class Card {
private int _value, _suit;
private String[] _cardValues = {null, "Ace", "2", "3", "4","5", "6", "7", 
    "8", "9", "10", "Jack", "Queen", "King"};
private String[] _cardSuits = {null, "Clubs", "Diamonds", "Hearts", "Spades"};

public Card(int value,int suit) {
    _value = value;
    _suit = suit;
}
public int getCardValue() {
    return _value;
}
public int getCardSuit() {
    return _suit;
}
public String toString() {
    return  _cardValues[_value] + " of " + _cardSuits[_suit];
}

} Deck class:

class DeckHand{
        private Card[] _deckHand;
        private int _deckSize;
        private static final int MAXSIZE = 52;
        private Card[] newDeck;

        public DeckHand() {
           _deckHand = new Card[MAXSIZE];
           _deckSize = 0;
        }
        public DeckHand(int deckSize) {
           _deckHand = new Card[MAXSIZE];
           int index = 0;
           for (int suit = 1; suit <= 4; suit++) {
              for (int rank = 1; rank <= 13; rank++) {
                  _deckHand[index] = new Card(rank, suit);
                  index++;
              }
           }
       _deckSize = deckSize;
       }
 //Here's the delete method, but I have no idea what I'm doing here.
       public void delete(int value) {
          for (int i = 0; i<_deckSize; i++) {
              if(_deckHand[i].getCardValue()==value) {
                  _deckHand[value] = _deckHand[_deckSize-1];
                  newDeck = new Card[_deckHand.length-1];
          } else
            System.out.println("\n--------------------------------------"
                    + "\nThe deck does not contain that value"
                    + "\n--------------------------------------");
          }
       }
 //Here's the deleteAny method, but I'm getting an error
    public void deleteAny(Card newCard) {
    if(_deckSize >= MAXSIZE) {
        newDeck = new Card[_deckHand.length-1];
        for(int i = 0; i<_deckSize; ++i)
            if(_deckHand[i].equals(newCard)) {
                newDeck[i] = _deckHand[i];
            }
        _deckHand = newDeck;
    }
//the error says it has to do with this next line
    _deckHand[_deckSize-1] = newCard;
    _deckSize-=1;
}
}

Main: Here's part of my main method that uses these delete and deleteAny methods:

                    case 3:
                        System.out.println("\nWhich card would you "
                                + "like to remove from the deck?");
                        valueOption();
                        System.out.print("\tOption: ");
                        value = keyboard.nextInt();

                        if(pickDeck == 1) {
                            standard.delete(value);
                        } else {
                            System.out.println("\n-------------------------"
                                    + "-------------------------------\n"
                                    + "The card value \"" + values[value]
                                    + "\" appears "
                                    + empty.count(value)
                                    + " times in the deck."
                                    + "\n---------------------------------"
                                    + "-----------------------");
                        }
                        break;
                    case 4:
                        Random generator = new Random();
                        value = generator.nextInt(13)+1;
                        suit = generator.nextInt(4)+1;
                        newCard = new Card(value,suit);
                        System.out.println("\n--------------------------"
                                + "---------------------"
                                + "\n" + newCard + " was removed from the "
                                + "deck."
                                + "\n--------------------------"
                                + "---------------------");
                        if(pickDeck==1) 
                            standard.deleteAny(newCard);
                        else
                            empty.deleteAny(newCard);

                        break;
Alisa
  • 21
  • 1
  • 5
  • I would use `array.utils.remove` http://stackoverflow.com/questions/642897/removing-an-element-from-an-array-java – kpie Oct 20 '16 at 01:26
  • I was informed not to use that for this assignment. – Alisa Oct 20 '16 at 01:28
  • Tell your professor to stop being a pussy and teach data structures in a language where you actually need data structures by default. (That would be C) Also if you looked at that answer there was another that does it without array.utils. Are you allowed to use `system.arraycopy`? – kpie Oct 20 '16 at 01:38
  • I'll check it out again, thanks. And no, I can't. – Alisa Oct 20 '16 at 01:42

2 Answers2

0

My answer uses most of your method from above. I've tweaked it to incorporate means of checking if we've found the value before.

public Card delete(int value) {
      Card result = new Card(-1,-1);               // Starter card to check if value has been found.
      newDeck = new Card[_deckHand.length-1]
      int location = -1                            // Initial location. This changes once we find the value.
      for (int i = 0; i<_deckHand.length; i++) {
          if(_deckHand[i].getCardValue()==value) { // We've found a match
              if(result.value==-1){                // Check if our starter card still has its original value
                  result = new Card(_deckHand[i].getCardValue(),_deckHand[i].getCardSuit());
                  location = i;                    // Adjust location
              }
      } 
      // make a helper that does the rest. That way you can delete any card from the deck.

      if(location != -1){                          // See if location has been adjusted (i.e. value has been found)
          for(int i = 0; i < location; i++){       // Copy the remnants of _deckHand to newDeck
              newDeck[i]=_deckHand[i];
          }
          for(int j = location+1; j<_deckHand.length-1; j++){
              newDeck[j]=_deckHand[j];
          }
          _deckHand = new Card[newDeck.length]
          _deckHand = newDeck                      // Change _deckHand to newDeck
          return result;                           // Return the card that was removed from _deckHand.
      } else {                                     // `else` indicates that the value has not been found
        System.out.println("\n--------------------------------------"
                + "\nThe deck does not contain that value"
                + "\n--------------------------------------");
      }   
}

Edit: Didn't see the last part about deleteAny(). You could make a helper method called helperDelete(value,location) that takes the value to delete and the position of the card which you want to delete. Using the same strategy as above, once you find the location of the initial value that you want, remove it from the deck, copy the deck into a new, shortened deck, and set your deck instance to be the new deck.

This should allow you to remove the card at a random position value, as needed by deleteAny(), and at a specified location value, as needed by delete().

  • Thank you for the suggestion. It helps a little, but this doesn't seem to work correctly. It's not resizing the array to where it takes that card away. – Alisa Oct 20 '16 at 05:00
  • Interesting. Maybe replace `_deckHand = new Card[newDeck.length]` with `_deckHand = new Card[_deckHand.length-1]`. [This link](http://stackoverflow.com/questions/2777762/shorten-array-length-once-element-is-remove-in-java) will probably help you with the resize. – Sondering Narcissist Oct 20 '16 at 16:46
0

If you need to remove an element from an array without using system.arraycopy or array.utils you might do something like the remove function that follows. (It is only static because I tested this up in one file.)

import java.util.Arrays;

public class HelloWorld{
     public static String[] remove(String[] arr,int index){
         String[] ret = new String[arr.length-1];
         for(int i = 0; i<index; i++){
             ret[i]=arr[i];
         }
         for(int i = index+1; i<arr.length; i++){
             ret[i-1]=arr[i];
         }
         return(ret);
     }
     public static void main(String []args){
        System.out.println("Hello World");
        String[] r = {"This","Is","ATest"};
        System.out.println(Arrays.toString(remove(r,0)));
        System.out.println(Arrays.toString(remove(r,1)));
        System.out.println(Arrays.toString(remove(r,2)));
     }
}
kpie
  • 9,588
  • 5
  • 28
  • 50