Hello,

So I am working on a programming assignment that plays a two player blackjack game. I have pretty much all the functionality of the game worked out. Everything was working correctly when I the cards where drawn by my paintComponent() method. However, as soon as I loaded .jpg card images the cards stopped matching up with values of the players' and dealer's hands. The best I can figure it is that the images are not loading into the array in the order I think they are. I fiddled around with it for awhile now and I could really use a fresh pair of eyes. Below are my methods to load the images, assign the image in the array to a card, and the paintComponent(). Also I uploaded a zip of the entire project. Thanks in advance.

          private void loadImages() throws IOException{
           String prefix = "images/";
           String[] suits = { "b", "c", "d", "h", "s" };
           String[] values = { "-1","-2","-4","-5","-6","-7","-8","-9","-10","-11","-12","-13",};
           String ext = ".jpg";

           int k = 0;
           for(int i = 0;i < 53; i++) {
             if(i == 0){
              String path = prefix + suits[0] + ext;
              URL url = getClass().getResource(path);
              images[i] = ImageIO.read(url);
              }
              else if (i <=13){
               String path = prefix + suits[1] + values[k] + ext;
               URL url = getClass().getResource(path);
               images[i] = ImageIO.read(url);
               k++;
               if(k==12){
                 k = 0;
                }
              }
              else if (i <=26){
               String path = prefix + suits[2] + values[k] + ext;
               URL url = getClass().getResource(path);
               images[i] = ImageIO.read(url);
               k++;
               if(k==12){
                 k = 0;
                }
              }
              else if (i <=39){
               String path = prefix + suits[3] + values[k] + ext;
               URL url = getClass().getResource(path);
               images[i] = ImageIO.read(url);
               k++;
               if(k==12){
                 k = 0;
                }
              }
              else if (i <=52){
               String path = prefix + suits[4] + values[k] + ext;
               URL url = getClass().getResource(path);
               images[i] = ImageIO.read(url);
               k++;
               if(k==12){
                 k = 0;
                }
              }
            }
          }
          public void paintComponent(Graphics g) {
                // The paint method shows the message at the bottom of the of the applet and controls cards drawn


             super.paintComponent(g); // fill with background color.

             g.setFont(bigFont);
             g.setColor(Color.white);
             g.drawString(message, 10, getSize().height - 10);
             g.drawString(message2, 10, getSize().height - 40);

             // Draw labels for the two sets of cards.

             g.drawString("Dealer's Cards:", 400, 13);
             g.drawString("Player 1's Cards:", 80, 510);
             g.drawString("Player 2's Cards:", 580, 510);

              g.setColor(Color.green);
             // Draw dealer's cards.  Draw first card face down if
             // the game is still in progress,  It will be revealed
             // when the game ends.

             g.setFont(smallFont);
             if (gameInProgress)
                g.drawImage(images[0], 400, 30, null);//drawCard(g, null, 400, 30);
             else
                g.drawImage(cardImageSelect(dealerHand.getCard(0)), 400, 30, null);//drawCard(g, dealerHand.getCard(0), 400, 30);
             for (int i = 1; i < dealerHand.getCardCount(); i++)
                g.drawImage(cardImageSelect(dealerHand.getCard(i)), 412 + i * 45, 30, null);

             // Draw the user's cards.

             for (int i = 0; i < player1Hand.getCardCount(); i++)
                g.drawImage(cardImageSelect(player1Hand.getCard(i)), 80 + i * 45, 540, null);

             for (int i = 0; i < player2Hand.getCardCount(); i++)
                g.drawImage(cardImageSelect(player2Hand.getCard(i)), 580 + i * 45, 540, null);


          }  // end paint();

          public Image cardImageSelect(Card c){
            if(c.getSuitAsString() == "Clubs"){
                 switch ( c.getValueAsString() ) {
                 case "Ace":   return images[1];
                 case "2":   return images[2];
                 case "3":   return images[3];
                 case "4":   return images[4];
                 case "5":   return images[5];
                 case "6":   return images[6];
                 case "7":   return images[7];
                 case "8":   return images[8];
                 case "9":   return images[9];
                 case "10":  return images[10];
                 case "Jack":  return images[11];
                 case "Queen":  return images[12];
                 default:  return images[13];
                }
            }
            else if(c.getSuitAsString() == "Diamonds"){
                 switch ( c.getValueAsString() ) {
                 case "Ace":   return images[14];
                 case "2":   return images[15];
                 case "3":   return images[16];
                 case "4":   return images[17];
                 case "5":   return images[18];
                 case "6":   return images[19];
                 case "7":   return images[20];
                 case "8":   return images[21];
                 case "9":   return images[22];
                 case "10":  return images[23];
                 case "Jack":  return images[24];
                 case "Queen":  return images[25];
                 default:  return images[26];
                }
            }
            else if(c.getSuitAsString() == "Hearts"){
                 switch ( c.getValueAsString() ) {
                 case "Ace":   return images[27];
                 case "2":   return images[28];
                 case "3":   return images[29];
                 case "4":   return images[30];
                 case "5":   return images[31];
                 case "6":   return images[32];
                 case "7":   return images[33];
                 case "8":   return images[34];
                 case "9":   return images[35];
                 case "10":  return images[36];
                 case "Jack":  return images[37];
                 case "Queen":  return images[38];
                 default:  return images[39];
                }
            }
            else if(c.getSuitAsString() == "Spades"){
                 switch ( c.getValueAsString() ) {
                 case "Ace":   return images[40];
                 case "2":   return images[41];
                 case "3":   return images[42];
                 case "4":   return images[43];
                 case "5":   return images[44];
                 case "6":   return images[45];
                 case "7":   return images[46];
                 case "8":   return images[47];
                 case "9":   return images[48];
                 case "10":  return images[49];
                 case "Jack":  return images[50];
                 case "Queen":  return images[51];
                 default:  return images[52];
                }
            }
            else
              return null;

          }

c.getSuitAsString() == "Diamonds" etc - doesn't do what you think!

== tests for exactly the same object. To test if two strings have the same text (sequence of letters) use String1.equals(String2)

Thanks for the tip. I updated my code with your suggestion but the result was the same the card images still are not matching up with thier hands.

Any special reason to use convoluted arrays and lookups like that? Why not just have a HashMap<Card, Image> and load that with the 52 cards and their respective images. Then you can just use imageMap.get(card);
(Assumes you hace defined equals method for the Card class)

There is no reason it was just my first instinct. I am new to java and dont know all the tricks yet. Thanks again ill try the hashmap now.

Also if it is not to much trouble what would i do to code the equals method in the card class. It does not have one and im not sure what it needs to do.

It just needs to override the default equals method that it inherited from Object. The inherited method tests for two Card objects being exactly the same object. For two Cards you can say they are equal if they have the same suits and values. (it's just like equals for Strings, which tests for having the same sequence of characters). That's what you need for any (eg) Ace of Clubs to match the Ace of Clubs that you used as a key in the HashMap. The pseudo-code goes like this:

 class Card {
    ...
    public boolean equals(Card other) {
      if this.suit not equal to other.suit return false; // not equal
      if this.value not equal to other.value return false; // not equal
      return true; // sanme suit and value
    }

Thanks James for the support I got the hashmap semi working and then noticed the problem in my original code. It ended up being i forgot to add the string value "-3" in my values array and the value indexer was being reset to 0 to soon. Again thanks and ill keep the hashmap in my mind from now on.

I vote for the enum approach, and in case there's need for a Map, consider using EnumMap.
It has perfect hashing and is extremely compact because internally it represents the elements of the enum using a bit vector.

@JamesCherril:
Your suggestion does not take the equals and hashCode contract into account. Also you don't seem to be overriding anything, the equals method you provided is an overload rather than an override.
Personally if my intent is to override a method, then I always use the @Override annotation. It has great benefits:
It improves readability and documents the intent, moreover if your intent does not conform to what you're doing, the compiler will generate an error message, which is really helpful.

Edited 3 Years Ago by mvmalderen

Hi Tux
All fair points for discussion, but I was trying to present the simplest possible solution and explanation for a beginner.

Oops, I found a mistake in my previous post, when talking about EnumMap I said:
...and is extremely compact because internally it represents the elements of the enum using a bit vector.
That is incorrect, I seem to have mixed up between EnumSet and EnumMap.
For EnumSet the statement about compactness and the bit vector is valid, for EnumMap it isn't.
EnumMap uses an array and the ordinal() method under the hood.

Links: [EnumSet] [EnumMap] [ordinal()]

Edited 3 Years Ago by mvmalderen

This question has already been answered. Start a new discussion instead.