Game of Set program, need help with for loop nesting and more

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • falconsx23
    New Member
    • Nov 2008
    • 55

    Game of Set program, need help with for loop nesting and more

    I am making a game called Set, it is a card game: here is a brief description of the rules:

    The game of Set is played with 81 cards, each of which has 4 properties (number, pattern,
    color and shape). The number of objects is 1, 2, or 3. The 3 possible patterns are solid,
    striped, and open. The 3 possible colors are red, green, and purple. The 3 possible
    shapes are diamond, squiggle, and oval. The 81 cards comprise all possible combinations
    of patterns, colors and shapes. Some example cards are:
    • 1 Striped red oval
    • 2 Solid green squiggle
    • 3 Open purple diamond

    Ok now what I am having trouble with is creating my deck of 81 cards. The way I am trying to do it is by creating a buch of nested for loops (should only be 4) that goes through each array and gets a number, color, shape and pattern. If nested right I should be able to create a deck of cards that has 81 possible combination's of numbers, colors, shapes and patterns.

    Code:
    import java.util.Scanner;
    import java.util.*;
    /**
     * Write a description of class GameOfSet here.
     * @author (Michael Brown) 
     * @version (a version number or a date)
     */
    public class GameOfSet
    {
        
        ArrayList<Card> cards;   //An array list of card objects
         
        
        /**
         * Constructor for objects of class GameOfSet
         * @param String to determine Shape and String to determine color
         * @param number can be 1-3
         * @param color can be red, green, purple
         * @param pattern can be solid, stripped, open
         * @param shape can be diamond, squiggle, oval
         * 
         */
        public GameOfSet()
        {
           
             cards = new ArrayList<Card>();
            
            Card cards = new Card ("1", "solid", "purple", "oval" );              //One card from the Cards ArraysList that has 4 perameters 
           
           
            
            
        }
        
        /**
         * Deck of 81 cards
         * nested for loop will create 81 possible 
         * combinations of number, color, pattern, and shape
         * each card will have one number, pattern, color and shape
         */
        
        public void getDeckOfCards()
        {      
          ArrayList<String> number = new ArrayList<String>(3);                     //ArrayList of numbers
          number.add("1");
          number.add("2");
          number.add("3");
          
          ArrayList<String>  color = new ArrayList<String>(3);                     //ArrayList of colors
          color.add("red");
          color.add("green");
          color.add("purple ");
          
          ArrayList<String> pattern = new ArrayList<String>(3);                 //ArrayList of patterns
          pattern.add("solid");
          pattern.add("striped");
          pattern.add("open");
          
          ArrayList<String> shape = new ArrayList<String>(3);                   //ArrayList of Shapes
           shape.add("diamond");
           shape.add("squiggle");
           shape.add("oval");
          
          
             for(int i = 0; i < number.size(); i++)
             {
            
                 for(int j = 0; j < color.size(); j++)
                 {
                      Card deck = cards.get(i);
                 
                      for(int k = 0; k < pattern.size(); k++)
                      {
    
                        
                            for(int m = 0; m < shape.size(); m++)
                            {
    
                            }
                        }
                    }
                }                     
            
        }
        
        
    }

    As you can see I have Card deck = cards.get(i);, well I should also be able to get j, k, and m. But I have no idea where I should put that. And after I get that settled, I should be able to put what ever is at i, k, k, and m, and add that to the deck.
  • r035198x
    MVP
    • Sep 2006
    • 13225

    #2
    A method called getDeckOfCards should not be void. It must be returning a List<Card> instead.
    Enums will help to clean up the code and logic

    Comment

    • falconsx23
      New Member
      • Nov 2008
      • 55

      #3
      Right now I want to just create a deck of 81 cards for that method. Im not sure If i should be returning anything yet. Also I am confused on the Enums link to help clean up the code. I will continue looking at it though.

      Comment

      • r035198x
        MVP
        • Sep 2006
        • 13225

        #4
        Suppose you have an enum called Color.
        The Color.values() method gives you an array of all the colors.

        Comment

        • Frinavale
          Recognized Expert Expert
          • Oct 2006
          • 9749

          #5
          Originally posted by falconsx23
          Ok now what I am having trouble with is creating my deck of 81 cards. The way I am trying to do it is by creating a buch of nested for loops (should only be 4) that goes through each array and gets a number, color, shape and pattern. If nested right I should be able to create a deck of cards that has 81 possible combination's of numbers, colors, shapes and patterns.
          Who told you that there should only be 4 nested loops...or even that you need use for-loops to solve this problem? Seems a bit weird...you could use something like recursion to solve the problem and then there wouldn't be 4 nested loops...

          I think that the point that r035198x was getting at is that it would probably be a lot easier if you were to use enums because you have a constant list of values for your numbers, patterns, colours, and shapes.

          Anyways, I'm not sure why you're having a problem with solving the problem.

          If you write it out as psudo code it's pretty obvious how the loop structure should look and what you should be doing:
          Code:
          For each number from 1 - 3 
            For each colour in my list/enum of shapes
              For each shape in my list/enum of shapes
                For each pattern in my list/enum of patterns
                  Add a new card(number, colour, shape, pattern) to my deck of cards
                Get the next pattern
              Get the next shape
            Get the next colour
          Get the next number
          How much more simple can it get?
          It really helps if you give your variables meaningful names...instead of using a,b, c or i,j,k,l,m use things like "number", "colour", "shape" and "pattern".

          Originally posted by falconsx23
          Right now I want to just create a deck of 81 cards for that method. Im not sure If i should be returning anything yet. Also I am confused on the Enums link to help clean up the code. I will continue looking at it though.
          What do you mean you're not sure if you should be returning anything....
          The name of the method is getDeckOfCards...n ot "setDeckOfCards "...not "populateDeckOf Cards"....it's getDeckOfCards.

          It seems very obvious that when someone calls the getDeckOfCards method the are expecting to get a deck of cards....how are they supposed to get anything if you don't give them something (return something to them) when they call the method? Again, pay attention to names :)

          -Frinny

          Comment

          • falconsx23
            New Member
            • Nov 2008
            • 55

            #6
            ok you are right that is bad programming on my part... sorry

            Comment

            • JosAH
              Recognized Expert MVP
              • Mar 2007
              • 11453

              #7
              For any number n in the range [0,81) you can do the following:

              Code:
              int number= n/27;
              int pattern= n/9%3;
              int color= n/3%3;
              int shape= n%3;
              So a single loop will generate all your different cards; no recursion nor nested loops are needed.

              kind regards,

              Jos

              Comment

              • Frinavale
                Recognized Expert Expert
                • Oct 2006
                • 9749

                #8
                Originally posted by JosAH
                For any number n in the range [0,81) you can do the following:

                Code:
                int number= n/27;
                int pattern= n/9%3;
                int color= n/3%3;
                int shape= n%3;
                So a single loop will generate all your different cards; no recursion nor nested loops are needed.

                kind regards,

                Jos
                Show off!

                : )

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Originally posted by Frinavale
                  Show off!

                  : )
                  Not at all; write down all numbers in the range 0 ... 80 in ternary (base 3) notation and you'll see: 0000 ... 2222. There are much trickier things one can do with this notion in any base.

                  kind regards,

                  Jos (ex-moderator)

                  Comment

                  • falconsx23
                    New Member
                    • Nov 2008
                    • 55

                    #10
                    Ok Frinavale, while I was working on this program my Lab Teacher Assistant suggested that using nested for loops will help me out, and what I have up there he said I was on the right track. Also keep in mind that I am still a beginner at Java and no expert. So what may be obvious to you is not to me and I apologize for that.

                    JosAH thanks alot for the response and I will try out the way you did as soon as I can get my program up.

                    Comment

                    • Frinavale
                      Recognized Expert Expert
                      • Oct 2006
                      • 9749

                      #11
                      Well the first thing you need to do is create/declare something that will represent the Deck Of Cards. An ArrayList<Cards > will work fine.

                      Have you learned about variable scope yet?

                      You could declare the deck of cards at the Class Level or at Method Level (let's just stick with these 2 scopes for now)...

                      If you declare the card deck in the getDeckOfCards method then the deck of cards is destroyed once the method is finished executing. If you need to use this deck of cards anywhere else then you either have to return the deck of cards to the calling code, or you need to declare the deck of cards at the class level.

                      If you declare the deck of cards as a member of the GameOfSet class then it will exist for as long as the GameOfSet exists. In this case I would rename the method from getDeckOfCards to "populateDeckOf Cards" because "get" implies that whatever is calling the method will be getting something back from the method. If another class needs to use the same deck of cards then I would implement the getDeckOfCards( ) to return the deck of cards you declared as a member of the GameOfSet class.

                      Anyways, the important point to take away from this is that you need to declare some sort of container that will represent the deck of cards....otherw ise you won't have anywhere to put the cards.

                      Once you've declared the DeckOfCards container you need to loop through all of the card possibilities in order to create a card for each possibility.

                      You already have a good idea of how to do this. How you do the loop doesn't really matter. The easiest way to for a beginner to understand would be to use For Loops....so keep on track with what you were doing.

                      So, for each possibility create 1 card and add it to the ArrayList<Card> that represents the deck of cards.

                      Once you are finished adding all of the cards to the deck return the deck (or not if it's a class member)

                      If you are going to return the deck then you need to change your getDeckOfCards method so that it returns the deck of cards. So you'll need to change the method's signature to:

                      public ArrayList<Card> getDeckOfCards( )

                      Give this a try.
                      If you're still stuck, post your updated code and we can discuss it :)

                      -Frinny

                      Comment

                      • falconsx23
                        New Member
                        • Nov 2008
                        • 55

                        #12
                        No we have not learned about scopes yet nor recursion. And yes what you are saying about for each possibility create 1 card and add it to the ArrayList<Card> that represents the deck of cards is what I was trying to do.

                        That was what I am stuck on. I wasn't sure how to set up the for loops and also where to place the add method to add the card that is created to the deck.

                        I am thinking that I should only have to call the add method once, but I am not sure where to place that add method. What I mean by add method is something like this

                        cards.add(Card) .
                        "Card" is the card being created from the nested for loops. So card should be like Card ("1", "solid", "purple", "oval" ).

                        What you are saying here "So, for each possibility create 1 card and add it to the ArrayList<Card> that represents the deck of cards." Would I place the add method after all of the for loops? Anyways here is what I have so far:

                        Code:
                        public class GameOfSet
                        {
                            
                            ArrayList<Card> cards;   //An array list of card objects
                             
                            
                            
                            public GameOfSet()
                            {
                               
                                 cards = new ArrayList<Card>(); 
                                Card cards = new Card ("1", "solid", "purple", "oval" );              //One card from the Cards ArraysList that has 4 perameters 
                               
                            }
                            
                            public ArrayList<Card> populateDeckOfCards()
                            {      
                             ArrayList<Cards>();                                                                         //An ArrayList that will represent DeckOfCards like a container  
                              ArrayList<String> number = new ArrayList<String>(3);                     //ArrayList of numbers
                              number.add("1");
                              number.add("2");
                              number.add("3");
                              
                              ArrayList<String>  color = new ArrayList<String>(3);                     //ArrayList of colors
                              color.add("red");
                              color.add("green");
                              color.add("purple ");
                              
                              ArrayList<String> pattern = new ArrayList<String>(3);                 //ArrayList of patterns
                              pattern.add("solid");
                              pattern.add("striped");
                              pattern.add("open");
                              
                              ArrayList<String> shape = new ArrayList<String>(3);                   //ArrayList of Shapes
                               shape.add("diamond");
                               shape.add("squiggle");
                               shape.add("oval");
                              
                              
                                 for(int i = 0; i < number.size(); i++)
                                 {
                                
                                     for(int j = 0; j < color.size(); j++)
                                     {
                                          Card deck = cards.get(i);
                                     
                                          for(int k = 0; k < pattern.size(); k++)
                                          {
                        
                                            
                                                for(int m = 0; m < shape.size(); m++)
                                                {
                        
                                                }
                                            }
                                        }
                                    }                     
                                
                            }   
                        }
                        As you can see I changed the signature of the method so that it could return something, but at the same time I am having trouble creating the container for the populateDeckOfC ards. (Line 18)

                        Comment

                        • Frinavale
                          Recognized Expert Expert
                          • Oct 2006
                          • 9749

                          #13
                          The add method that I'm talking about is part of the ArrayList class.
                          Sun (the makers of Java) has a website that lists all of the classes along with the class's methods etc (the API). This documentation can be found here. Bookmark this resource because every time you need help using a Java class you can refer to it for help before asking us.

                          Anyways, like I was saying, the add method is a member of the ArrayList class.

                          First you need to instantiate the ArrayList class before you can use it...I'm not sure if you know what instantiate means...it means to "create an instance of".

                          There are classes (they are like blue prints...for a house) and then there are instances of classes (the actual house).

                          Before you can use any variable you have to instantiate it (create an instance of it) or else it doesn't exist and you will get Null Reference errors if you try to use it.

                          Ok so create a new instance of the ArrayList class to use as your deckOfCards:

                          Code:
                           ArrayList<Cards> deckOfCards = new ArrayList<Cards>(81);
                          Now if you want to add a card to the deck you call the ArrayList's add method, providing it a card:
                          Code:
                          Card theCard = new Card(.......);
                          deckOfCards.add(theCard);
                          Make sense?

                          Comment

                          • Frinavale
                            Recognized Expert Expert
                            • Oct 2006
                            • 9749

                            #14
                            I was just reviewing your code and I don't have a clue what you're trying to do at line 18.

                            What you did is create a class member variable "cards"...I 've been referring to this as the deckOfCards.

                            So you already have a container (an ArrayList) to put the cards into when you create them.

                            You have already correctly instantiated this container in the constructor. (It might be a good idea to rename your "cards" variable to deckOfCards since it is representing a "deck of cards")


                            Great!

                            Don't know what you're doing at line 18.....just delete that.

                            Also remove line 12....there's no need to have that there. You should be creating new cards (not at line 12) in the inner most for loop instead (line 53)...and then adding it to the deck of cards (blah that name...adding it to your "cards" variable).

                            You need to call the "populateDeckOf Cards" method in the constructor.

                            Since you are going to be populating a class variable, you don't need to return anything. So, (sorry) change your populateDeckOfC ards method signature back to returning void:

                            public void populateDeckOfC ards()

                            Now in the populateDeckOfC ards you want to add to the card to the deck of cards (the "cards" variable) by using the ArrayList.add() method (**hint: line 53**)......

                            Comment

                            • falconsx23
                              New Member
                              • Nov 2008
                              • 55

                              #15
                              Yes I am following you so far. I did create a seperate class called Card like you said here is the code for it just in case you need to see it:

                              Code:
                              public class Card
                              {
                                  public String number;        
                                  public String color;   
                                  public String pattern;
                                  public String shape;
                                  
                                  public Card(String number, String color, String pattern, String shape)
                                  {
                                      this.number = number;
                                      this.color = color;
                                      this. pattern = pattern;
                                      this.shape = shape;   
                                  }
                                  
                                  public String getNumber()
                                  {
                                      
                                      return number;
                                  }
                                  
                                  /**
                                   * returns color
                                   */
                                   
                                  public String getColor()
                                 {
                                      return color;
                                  }
                                  
                                  /**
                                   * returns pattern
                                   */
                                  public String pattern()
                                  {
                                      
                                      return pattern;
                                  }
                                  
                                  /**
                                   * returns shape
                                   */
                                  public String shape()
                                  {  
                                      return shape;
                                  }   
                              }
                              Yea I tried using the add method from the JAVA API earlier, I was typing it wrong. OK So here is my code again:

                              Code:
                              public class GameOfSet
                              {
                                  
                                  ArrayList<Card> cards;   //An array list of card objects
                                  
                                  public GameOfSet()
                                  {
                                     
                                       cards = new ArrayList<Card>();  
                                        ArrayList<Card> populateDeckOfCards = new ArrayList<Card>(81); 
                                  }
                                
                                  
                                  public  void populateDeckOfCards()
                                  {      
                                   ArrayList<String>deckOfCards = new ArrayList<String>(81);   
                                    
                                    ArrayList<String> number = new ArrayList<String>(3);                     //ArrayList of numbers
                                    number.add("1");
                                    number.add("2");
                                    number.add("3");
                                    
                                    ArrayList<String>  color = new ArrayList<String>(3);                     //ArrayList of colors
                                    color.add("red");
                                    color.add("green");
                                    color.add("purple ");
                                    
                                    ArrayList<String> pattern = new ArrayList<String>(3);                 //ArrayList of patterns
                                    pattern.add("solid");
                                    pattern.add("striped");
                                    pattern.add("open");
                                    
                                    ArrayList<String> shape = new ArrayList<String>(3);                   //ArrayList of Shapes
                                     shape.add("diamond");
                                     shape.add("squiggle");
                                     shape.add("oval");
                                    
                                    
                                       for(int i = 0; i < number.size(); i++)
                                       {
                                      
                                           for(int j = 0; j < color.size(); j++)
                                           {
                                                Card deck = cards.get(i);
                                           
                                                for(int k = 0; k < pattern.size(); k++)
                                                {
                              
                                                     Card theCard = new Card("","","","");
                                                     populateDeckOfCards().add(theCard);
                              
                              
                                                      for(int m = 0; m < shape.size(); m++)
                                                      {
                              
                                                      }
                                                
                                              }
                                          }                     
                                      
                                  }   
                              }
                              }
                              Im getting an error message at line 50 stating void cannot be dereferenced. I tried calling the populateDeckOfC ards method in the constructor and one thing I changed from what you originally stated was

                              Code:
                               ArrayList<[B]Cards[/B]> populateDeckOfCards = new ArrayList<[B]Cards[/B]>(81);
                              to
                              Code:
                              ArrayList<Card> populateDeckOfCards = new ArrayList<Card>(81);
                              I was getting an error stating cannot find symbol Cards.

                              Comment

                              Working...