Deleting Strings from ArrayList

312
February 22, 2017, at 7:57 PM

I am trying to code the Mastermind game, but instead of the user cracking the computer's code, the computer must crack the user's code. I am having trouble in the response method, where I attempt to remove possible codes that cannot be correct. The example I was testing was that the secret code is 223, with the tokens being 1,2, and 3, and the position being 3. The computer first guesses 1 1 1, which I say is incorrect. Then, the computer should remove all strings containing "1" from the ArrayList, but it doesn't remove anything at all. What have I done wrong?

import java.util.Scanner;
import java.util.ArrayList;
public class MMplayer {
    static Scanner scan = new Scanner (System.in);
    String[] tokencolors; //the tokens the user enters
    ArrayList <String> possibleGuesses = new ArrayList <String>();
    String [] remainingGuess; //the number of remaining possible guesses
    String lastGuess; //the last guess that was made
    int guessNum = 0; //guess count
    int positions = 0;
    int ccpw; //"color correct, position wrong"
    int ccpc; //"color correct, position correct"
public static void main (String[] args){
    //This sets up the introduction so the player knows how to play
    System.out.println("Hello, and welcome to Mastermind!");
    System.out.println("");
    System.out.println("You will choose a certain number of tokens to play with (these can be anything, like colors, names, or fruit).\n"
            + "Then you will choose the number of those tokens that you'd like to use in the game (called the position)."
            + "\nThe computer will then try to guess the correct name and location of your tokens. ");
    System.out.println("\nPlease enter the number of tokens and their names (up to six tokens), and the number of positions (up to four)."
            + "\nJust remember that to make it harder for the computer, pick more tokens than you actually want to use. ");
    System.out.println("");
    System.out.println("Enter number of tokens now: ");
    //number of tokens, makes sure it is at most 6 
    int aryLength = scan.nextInt();
    if (aryLength > 6){
        System.out.println("Please enter at most six tokens.");
        System.exit(0);
    }
    System.out.println("Enter token names now, pressing enter after each: ");
    String [] tokencolors = new String[aryLength];
    for (int i = 0; i < aryLength; i++){
        tokencolors[i] = scan.next();
    }
    System.out.println("Enter number of positions now: ");
    int position = scan.nextInt();
    if (position > 4){
        System.out.println("Please enter at most 4 positions.");
        System.exit(0);
    }

    MMplayer player = new MMplayer(tokencolors, position);
}
public MMplayer(String[] cTokencolors, int cPositions) {
    tokencolors = cTokencolors;
    positions = cPositions;
    holder();
}
public void holder (){
    if (guessNum == 0){ //if this is the very first guess
        if (positions == 1){ //if there is one position
            for (int i = 0; i < tokencolors.length; i++){
                possibleGuesses.add(tokencolors[i]);
            }
        }
        else if (positions == 2){ //if there are two positions
            for (int i = 0; i < tokencolors.length; i++){
                for (int j = 0; j < tokencolors.length; j++){
                    possibleGuesses.add(tokencolors[i] + " " + tokencolors[j]);
                }
            }
        }
        else if (positions == 3){ //if there are three positions
            for (int i = 0; i < tokencolors.length; i++){
                for (int j = 0; j < tokencolors.length; j++){
                    for (int k = 0; k < tokencolors.length; k++){
                        possibleGuesses.add(tokencolors[i] + " " + tokencolors[j] + " " + tokencolors[k]);
                    }
                }
            }
        }
        else if (positions == 4){ //if there are four positions
            for (int i = 0; i < tokencolors.length; i++){
                for (int j = 0; j < tokencolors.length; j++){
                    for (int k = 0; k < tokencolors.length; k++){
                        for (int l = 0; l < tokencolors.length; l++){
                            possibleGuesses.add(tokencolors[i] + " " + tokencolors[j] + " " + tokencolors[k] + " " + tokencolors[l]);
                        }
                    }
                }
            }
        }
        else {
            System.out.println("Number of positions is invalid.");
            newGame();
        }
        System.out.println("Guess: " + possibleGuesses.get(0));
        lastGuess = possibleGuesses.get(0);
        guessNum++;
        System.out.println("First enter how many tokens were right, but had the wrong position: ");
        ccpw = scan.nextInt();
        System.out.println("Next, enter how many tokens were right and had the right position: ");
        ccpc = scan.nextInt();
        response(ccpw, ccpc);
    }

}
//  public String[] nextMove() {// return the next guess
//
//  } 

public void response(int colorsRightPositionWrong, int positionsAndColorRight) {
    ccpw = colorsRightPositionWrong;
    ccpc = positionsAndColorRight;


    if (ccpc == positions){
        System.out.println("The computer has won!");
    }
    else {
        if (guessNum == 1){
            String guess = tokencolors[0];
            for (int i = 0; i < possibleGuesses.size(); i++){
                if (possibleGuesses.get(i).equals(guess)){
                    possibleGuesses.remove(i);
                }
            }
        }
        System.out.println("Remaining guesses: " + possibleGuesses);
    }

}
}
Answer 1
Based on my understanding of your description it appears that you have issue on the line shown below where you should check for contains instead instead of equals:
if (guessNum == 1){
            String guess = tokencolors[0];
            for (int i = 0; i < possibleGuesses.size(); i++){
                //check for contains below?
                if (possibleGuesses.get(i).equals(guess)){
                    possibleGuesses.remove(i);
                }
            }
        }
..
}
Answer 2

You're using tokencolors[0] as your first guess, which would be "1", in this case. That causes nothing to be removed if you use equals (because all the possibilities have the format "1 1 1"), as you're describing.

If using contains, what happens is that you're modifying the list while iterating, which is a bad idea. Analysing each value of i:

i = 0

guesses.get(0) == "1 1"

"1 1" contains "1", so removes. Guesses are now [1 2, 2 1, 2 2]

i = 1

guesses.get(1) == "2 1"

"2 1" contains "1", so removes. Guesses are now [1 2, 2 2]

i = 2

At this point the i >= guesses.size(), so the loops ends.

Using iterators

You should use an iterator for removing things in a list:

for (Iterator<String> it = guesses.iterator(); it.hasNext(); ) {
    String item = it.next();
    if (item.contains(guess)) {
        iterator.remove();
    }
}
Rent Charter Buses Company
READ ALSO
Loading big files in java as HashMaps

Loading big files in java as HashMaps

I'm developing as part of my PhD a big system in Java that works with data that is contained huge text files

479
how to use update and join query together in codeigniter?

how to use update and join query together in codeigniter?

Updating data while join two tables but it gives an error in where condition can i use join and update together in a query ?

521
How to write a RewriteRule to pass only the last portion of a path

How to write a RewriteRule to pass only the last portion of a path

I have a PHP file that receives a parameter to print a page, like this:

296