#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2010
    Posts
    5
    Rep Power
    0

    [Homework] Creating Game Program


    This program is supposed to function as a "guessing game". A user guesses a number between 1000 and 9999 and the program guesses a number, the user then tells how many digits in the program's "guess" match the number of digits the user was thinking of. Then it guesses again with a modified result, until it guesses the correct answer or determines the number can't exist. My program is built to have all possible numbers (1000 through 9999) in an arraylist and, upon getting the number of matches, to delete any numbers that don't match it. I go about this by putting the number that the computer guessed along with the first possible number into two arrays of length four (so each digit has its own index), then counting the number of matches and deleting the current number if the matches aren't the same as what the user input. However, it simply doesn't go about the process like I believe it should. I would appreciate any help you could give in hinting to me where the problem is.

    The second half of the program (separated by a line break) was given to us and shouldn't be changed, it is what we work off of to create the methods and functions.

    Thanks for any help!



    Code:
    import java.util.ArrayList;
    import java.util.Random;
    
    import javax.swing.JOptionPane;
    
    public class Assignment2 {
    	public int totalGuesses = 0;
    	public int guess;
    	Random rand = new Random();
    	ArrayList<Integer> numbers = new ArrayList<Integer>();
    
    	public Assignment2 ( ){
    		for(int j = 1000; j<=9999; j++){
    			numbers.add(j);}
    	}
    		
    
    
    	public int myGuessIs() {
    		if(numbers.size() !=0){
    		guess = numbers.get((int) (rand.nextInt(numbers.size()-1))).intValue();
    		totalGuesses++;}
    		else{guess = -1;}
    		return guess;
    		
    
    	}
    	
    	public int totalNumGuesses() {
    		return totalGuesses;
    
    	}
     
    	public void updateMyGuess(int nmatches) {
    		int modnumbers;
    		int modguess = guess;
    		int tempmodnumbers;
    		int tempmodguess;
    		int matches;
    		
    			for(int j = 0; j<numbers.size(); j++){
    				matches = 0;
    				modnumbers = numbers.get(j).intValue();
    				for(int i = 3; i>=0; i--){
    					tempmodnumbers = modnumbers%10;
    					modnumbers = modnumbers/10;
    					tempmodguess = modguess%10;
    					modguess = modguess/10;
    					if(tempmodnumbers == tempmodguess){
    						matches++;}
    				}
    				
    				if(matches != nmatches){
    					numbers.remove(j);
    					j--;
    				}
    				else{System.out.println(numbers.get(j));}
    				
    			}
    			
    	}
    	
    	// fill in code here (optional)
    	// feel free to add more methods as needed
    	
    	
    	
    	// you shouldn't need to change the main function
    	public static void main(String[] args) {
    
    		Assignment2 gamer = new Assignment2( );
      
    		JOptionPane.showMessageDialog(null, "Think of a number between 1000 and 9999.\n Click OK when you are ready...", "Let's play a game", JOptionPane.INFORMATION_MESSAGE);
    		int numMatches = 0;
    		int myguess = 0;
    		
    		do {
    			myguess = gamer.myGuessIs();
    			if (myguess == -1) {
    				JOptionPane.showMessageDialog(null, "I don't think your number exists.\n I could be wrong though...", "Mistake", JOptionPane.INFORMATION_MESSAGE);
    				System.exit(0);
    			}
    			String userInput = JOptionPane.showInputDialog("I guess your number is " + myguess + ". How many digits did I guess correctly?");
    			// quit if the user input nothing (such as pressed ESC)
    			if (userInput == null)
    				System.exit(0);
    			// parse user input, pop up a warning message if the input is invalid
    			try {
    				numMatches = Integer.parseInt(userInput.trim());
    			}
    			catch(Exception exception) {
    				JOptionPane.showMessageDialog(null, "Your input is invalid. Please enter a number between 0 and 4", "Warning", JOptionPane.WARNING_MESSAGE);
    				numMatches = 0;
    			}
    			// the number of matches must be between 0 and 4
    			if (numMatches < 0 || numMatches > 4) {
    				JOptionPane.showMessageDialog(null, "Your input is invalid. Please enter a number between 0 and 4", "Warning", JOptionPane.WARNING_MESSAGE);
    				numMatches = 0;
    			}
    			if (numMatches == 4)
    				break;
    			// update based on user input
    			gamer.updateMyGuess(numMatches);
    			
    		} while (true);
    		
    		// the game ends when the user says all 4 digits are correct
    		System.out.println("Aha, I got it, your number is " + myguess + ".");
    		System.out.println("I did it in " + gamer.totalNumGuesses() + " turns.");
    	}
    }
  2. #2
  3. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2007
    Posts
    1,939
    Rep Power
    3120
    1. Please use code tags when posting code.
    2. What is your specific question?
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2010
    Posts
    5
    Rep Power
    0
    Originally Posted by jzd
    1. Please use code tags when posting code.
    2. What is your specific question?
    Sorry about that. I've fixed it.

    My question is why my program isn't running as intended. I've gone through it multiple times on paper and cannot find what the problem is, however I think I've found where it is.

    In the updateMyGuess method, the program looks at a possible number (the first available in the arrayList of possible numbers) and compares it with the number it "guessed". It's supposed to look at each individual digit, and if they match increment the variable "matches". updateMyGuess was passed a variable nmatches, which the user provided (telling how many digits matched, both in number and position), and at the end it checks if nmatches and matches are the same. If they are not, that means the number couldn't be one that the user guessed so it deletes it from the array. Then it continues with the next possible number.

    However, I've found that it deletes all but the thousands (2000, 3000, 4000, etc), note that this doesn't include 1000. For example:

    I'm thinking of the number 9876
    The computer "guesses" 8888.
    I tell it there's one match.
    It should delete all numbers that don't have exactly one match, meaning it will not delete 7841 (one match) but will delete 7848 (two matches).
    However, as I said it deletes all but the thousands, not including 1000.

    Any help you could give would be greatly appreciated. Thanks.
  6. #4
  7. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2007
    Posts
    1,939
    Rep Power
    3120
    You have a lot of moding going on that probably is excluding these numbers.

    I would add println statements throughout the method to get your head around what is really happening.

    But looking closer, you have a lot of complex logic of comparisons and code that extracts the digits. I would pull the digit extraction out into a separate method that you can verify that that piece operations correctly. Doing this will also make the code more readable and reduce the complexity.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2009
    Posts
    245
    Rep Power
    243
    Since you are not doing any math with the numbers except to find the digits, why don't you just keep the input as a string and compare it character by character? This eliminates the most confusing and error-prone section of the code, as well as improving readability.

    Comments on this post

    • jzd agrees : I almost mentioned that as well, but I didn't want to bring up to many points at once and loose the OP.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2010
    Posts
    5
    Rep Power
    0
    Thanks for your suggestions, guys. I actually followed Spyder's advice and it works almost perfectly. The one strange thing is, though, that at 10 guesses (I've checked multiple times), it gives me an IllegalArgumentException as follows:

    Exception in thread "main" java.lang.IllegalArgumentException: n must be positive
    at java.util.Random.nextInt(Unknown Source)
    at Assignment2.myGuessIs(Assignment2.java:25)
    at Assignment2.main(Assignment2.java:70)

    I'm currently checking, but from what I'm reading in the exception it seems like it might be a problem in my understanding of how the Random method I'm using works, and not just what I typed in. So if you could offer any information while I'm looking my program over I would appreciate it. Here is my updated and almost working code.

    Code:
    import java.util.ArrayList;
    import java.util.Random;
    
    import javax.swing.JOptionPane;
    
    public class Assignment2 {
    	public int totalGuesses = 0;
    	public String guess;
    	Random rand = new Random();
    	ArrayList<String> numbers = new ArrayList<String>();
    
    	public Assignment2 ( ){
    		for(int j = 1000; j<=9999; j++){
    			numbers.add(Integer.toString(j));}
    	}
    		
    
    
    	public int myGuessIs() {
    		if(numbers.size() !=0){
    		guess = numbers.get((rand.nextInt(numbers.size()-1)));
    		totalGuesses++;}
    		else{guess = "-1";}
    		return Integer.parseInt(guess);
    		
    
    	}
    	
    	public int totalNumGuesses() {
    		return totalGuesses;
    
    	}
     
    	public void updateMyGuess(int nmatches) {
    		int matches;
    		
    			for(int j = 0; j<numbers.size(); j++){
    				matches = 0;
    				for(int i = 3; i>=0; i--){
    					if(guess.charAt(i) == numbers.get(j).charAt(i)){
    						matches++;}
    				}
    				
    				if(matches != nmatches){
    					numbers.remove(j);
    					j--;
    				}
    				else{System.out.println(numbers.get(j));}
    				
    			}
    			
    	}
    	
    	
    	
    	// you shouldn't need to change the main function
    	public static void main(String[] args) {
    
    		Assignment2 gamer = new Assignment2( );
      
    		JOptionPane.showMessageDialog(null, "Think of a number between 1000 and 9999.\n Click OK when you are ready...", "Let's play a game", JOptionPane.INFORMATION_MESSAGE);
    		int numMatches = 0;
    		int myguess = 0;
    		
    		do {
    			myguess = gamer.myGuessIs();
    			if (myguess == -1) {
    				JOptionPane.showMessageDialog(null, "I don't think your number exists.\n I could be wrong though...", "Mistake", JOptionPane.INFORMATION_MESSAGE);
    				System.exit(0);
    			}
    			String userInput = JOptionPane.showInputDialog("I guess your number is " + myguess + ". How many digits did I guess correctly?");
    			// quit if the user input nothing (such as pressed ESC)
    			if (userInput == null)
    				System.exit(0);
    			// parse user input, pop up a warning message if the input is invalid
    			try {
    				numMatches = Integer.parseInt(userInput.trim());
    			}
    			catch(Exception exception) {
    				JOptionPane.showMessageDialog(null, "Your input is invalid. Please enter a number between 0 and 4", "Warning", JOptionPane.WARNING_MESSAGE);
    				numMatches = 0;
    			}
    			// the number of matches must be between 0 and 4
    			if (numMatches < 0 || numMatches > 4) {
    				JOptionPane.showMessageDialog(null, "Your input is invalid. Please enter a number between 0 and 4", "Warning", JOptionPane.WARNING_MESSAGE);
    				numMatches = 0;
    			}
    			if (numMatches == 4)
    				break;
    			// update based on user input
    			gamer.updateMyGuess(numMatches);
    			
    		} while (true);
    		
    		// the game ends when the user says all 4 digits are correct
    		System.out.println("Aha, I got it, your number is " + myguess + ".");
    		System.out.println("I did it in " + gamer.totalNumGuesses() + " turns.");
    	}
    }
    EDIT: Soon after posting this, I found what I think to be the problem. In the myGuessIs method, at the point where there was only one possible number left, it was choosing a random number with zero as the parameter for rand.NextInt. I changed it to the following and so far everything is working. I'll keep checking it but I believe it should be all set. Thanks so much! I can't believe I spent hours trying to make it work the way with the mod when I could have just changed it to a string. Any other suggestions for simply making my code "cleaner"?

    Code:
    public int myGuessIs() {
    		if(numbers.size() >1){
    		guess = numbers.get((rand.nextInt(numbers.size()-1)));
    		totalGuesses++;}
    		else if(numbers.size() == 1){
    			guess = numbers.get(0);
    		}
    		else{guess = "-1";}
    		return Integer.parseInt(guess);

    Comments on this post

    • harshcsr agrees
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2017
    Posts
    1
    Rep Power
    0
    can you please share how you solved this illegal argument exception problem?

IMN logo majestic logo threadwatch logo seochat tools logo