Nested Loop not working properly in Mastermind game - java

I recently started coding in Java and my coach gave me an exercise where I have to re-create the Mastermind game. To give an overview of this game: the computer creates an array with X random integers, and the user gets to input X integers as well. Location matters. The users scores "Gold" if he guesses an integer that is in the same spot as the computer generated array. If the integer is present in the array, but in the wrong spot, the users gets a "Silver" score. If the integer is not present in the array at all, the user gets a "NotFound" score. The final array should give the user a score for each place in the array, e.g. (Gold, Silver, NotFound)
I have tried to make a nested loop that scores the users guesses. It captures the score in a different array (yourScore[]). User guesses are captured in array "guessednums[]" and the computer generated array is called "nums[]". The size of all arrays has been set with a variable prior to the mentioned code.
What I want the code to do is to first check whether a user's guess matches with the computer choice on the same spot, and if that is the case set the matching space in the yourScore array to "Gold". Then, if the guess does not directly match, I want a loop to check whether the user guess is present in ANY place of the computer generated nums[] array, and to score it as "Silver" if that is the case. Finally, if this is not the case, I want the yourScore[] place to be set as "NotFound".
Matching guesses are properly scored as "Gold". The problem I am encountering is that sometimes the loop will not properly score a guess as "Silver", but instead mark it as "NotFound". I suspect that this has to do with the loop not properly initialising. I have read multiple questions on Stack Overflow and other articles as well, and played around with my code, but I keep running into similar issues.
I would love to get a second opinion on the code and see what I have done wrong.
package Mastermind;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class Mastermind {
static Scanner userInput = new Scanner(System.in);
public static void main(String[] args){
int size = 3; // Allows you to set the size of the arrays in the game
int[] nums = generateNumbers(size); //Stores the computer choice 3-tuple
int[] guessednums; //Stores the guessed 3-tuple
int iteration = 0; //Keeps track of the # of guesses so far
boolean correctAnswer; //true if the guessed tuple matches the computer choice tuple
//Set array size
//The game starts here
while (true){
iteration++;
System.out.println("Iteration #" + iteration);
guessednums = guessTheNumbers(size);
correctAnswer = yourScore(nums, guessednums, size);
if(correctAnswer) break;
}
//Printing the result
printResults(iteration, nums);
}
private static void printResults(int iteration, int[] nums) {
System.out.println("************************************************************"); // Print final result if users has a completely matching guess
System.out.println("************************************************************");
System.out.println("The correct answer was " + Arrays.toString(nums));
System.out.println("It took you " + iteration + " iterations to find the answer!");
}
private static int[] guessTheNumbers(int size) {
System.out.println("Please your ordered guess (press enter after each):");
int[] guessednums = new int[size]; // Initialise array for user choices
for (int i = 0; i < size; i++){ // Loop that creates the array of user input
guessednums[i] = userInput.nextInt();
}
System.out.println(Arrays.toString(guessednums));
return guessednums; // Return array for user guessed numbers array to main method
}
public static int[] generateNumbers(int size){
int[] nums = new int[size]; // Initialise array for computer choices
Random rn = new Random(); // Create new variable for randomised computer choices
for (int i = 0; i < size; i++){ // Loop that creates the array of computer choices
nums[i] = rn.nextInt(9) + 1;
}
System.out.println(Arrays.toString(nums)); // Temporary to print array
return nums; // Return array for computer generated numbers array to main method
}
public static boolean yourScore(int[] nums, int[] guessednums, int size){
String[] yourScore = new String[size]; // Initialise array for user choices
for(int i = 0; i < size; i++){ // Nested loop that scores the user entries as Gold/Silver/NotFound
if (guessednums[i] == nums[i]){
yourScore[i] = "Gold";
} else {
yourScore[i] = "NotFound";// in case is not found it stays that way
for(int j = 0; j < size; j++){
if (guessednums[i] == nums[j]){
yourScore[i] = "Silver"; // found one! break the loop and keep checking numbers
break;
}
}
}
}
if (yourScore[0] == "Gold" && yourScore[1] == "Gold" && yourScore[2] == "Gold"){ // Marks the input as true or false depending on if it matches with the computer choices
boolean correctanswer = true;
return correctanswer;
} else {
System.out.println("Your score is " + Arrays.toString(yourScore) + "!");
System.out.println("************************************************************");
boolean correctanswer = false;
return correctanswer;
}
}
}

The problem comes with the logic. I find useful to put the logic into words:
For each number in the array:
1. Check if the numbers are equal in that position (Gold)
2 else, for each number in the array, check if that number is equal to another in the array
3. If that number is in it, break the loop (Silver)
4. else, mark it as not found (NotFound).
the code would be like this:
for(int i = 0; i < size; i++){ // Nested loop that scores the user entries as Gold/Silver/NotFound
if (guessednums[i] == nums[i]){
yourScore[i] = "Gold";
} else {
yourScore[i] = "NotFound";// in case is not found it stays that way
for(int j=0;j<size<j++){
if (guessednums[i] == nums[j]){
yourScore[i] = "Silver"; // found one! break the loop and keep checking numbers
break;
}
}
}
}

I think you mixed up the outer and inner index meaning. Try this:
for(int i = 0; i < size; i++){ // Nested loop that scores the user entries as Gold/Silver/NotFound
for(int j = 0; j < size; j++){
if(i == j) {
if (guessednums[i] == nums[j]){
yourScore[i] = "Gold";
}
} else {
if (guessednums[i] == nums[j]){
yourScore[i] = "Silver";
} else if (guessednums[i] != nums[j]){
yourScore[i] = "NotFound";
}
}
}
}
Gold is only possible if i == j ...
HTH and always better for readers, if indentation is plausible and thus easy for the eyes ...

Not elegant but simple:
for(int i = 0; i < 5; i++){
yourScore[i] = "NotFound";//most likely
}
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
if(guessednums[i]==nums[j]) {
yourScore[i] = "Silver"; //quite likely
}
}
}
for(int i = 0; i < 5; i++){
if(guessednums[i]==nums[i]) {
yourScore[i] = "Gold"; //very unlikely
}
}

Related

Searching an array with user input and printing all elements that have this value

I'm trying to search an array for a certain value and display all the elements which contain this value in java. For example, the user selects the number 5, there are 3 projects stored in the array with this value so all 3 of those will be printed out. My code is compiling ok, but when I run it, it jumps to the else statement, even if I am inputting a number that is in the array..
Any help would be amazing. Here's my code:
case 3:
//display all elements with the same state
//get number user wishes to search for
boolean found = false;
Scanner input = new Scanner(System.in);
System.out.print("Please enter the number you wish to search for");
//read user input
num = input.nextInt();
//traverse array
int k = 0;
for(k=0; k < myMonths.length; k++){
if(myMonths[index] == num){
found = true;
break;}
if(found){System.out.println(k);}
else{System.out.println("not found");}
}
break;
Here's the array:
//Menu loop
int myMonths[] = new int[5];
int index = 0;
int num;
while(choice !=6){
switch (choice){
case 1:
//int n = number of projects
int n = 1;
Scanner sc = new Scanner(System.in);
System.out.println("How many months was your project?");
for(int i=0; i<1; i++){
int a = sc.nextInt();
//if months is lesser than 2/greater than 12
if((a < 2) || (a > 12)){
System.out.println("Please enter an amount between 2 and 12 months");}
//if months is between 2 and 12 add it to the array
else{myMonths[index++] = a;} }
break;
First, you should be using k instead of index. Second, you shouldn't be printing "not found" (or testing for that) on every iteration. You should limit variable scope as much as practical. And you also mention wanting to find all matching indices so you shouldn't terminate the loop prematurely; I think you wanted something like
//assume the value isn't present.
boolean found = false;
//read user input
int num = input.nextInt();
//traverse array
for(int k = 0; k < myMonths.length; k++) {
if (myMonths[k] == num){
found = true;
System.out.println(k); // don't break or the loop ends early.
}
}
//this test can only be done after you iterate **all** values.
if (!found) {
System.out.println("not found");
}

Java: Print out each number in an array without printing its an repeats of that number?

Im trying to print out an array but only print out the distinct numbers in that array.
For example: if the array has {5,5,3,6,3,5,2,1}
then it would print {5,3,6,2,1}
each time i do it either i only print the non repeating numbers, in this example {6,2,1} or i print them all. then i didnt it the way the assignment suggested
the assignment wants me to check the array before i place a value into it to see if its there first. If not then add it but if so dont.
now i just keep getting out of bounds error or it just prints everything.
any ideas on what i should do
import java.util.Scanner;
public class DistinctNums {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int value;
int count = 0;
int[] distinct = new int[6];
System.out.println("Enter Six Random Numbers: ");
for (int i = 0; i < 6; i++)
{
value = input.nextInt(); //places users input into a variable
for (int j = 0; i < distinct.length; j++) {
if (value != distinct[j]) //check to see if its in the array by making sure its not equal to anything in the array
{
distinct[count] = value; // if its not equal then place it in array
count++; // increase counter for the array
}
}
}
// Displays the number of distinct numbers and the
// distinct numbers separated by exactly one space
System.out.println("The number of distinct numbers is " + count);
System.out.print("The distinct numbers are");
for (int i = 0; i < distinct.length; i++)
{
System.out.println(distinct[i] + " ");
}
System.out.println("\n");
}
}
Always remember - if you want a single copy of elements then you need to use set.
Set is a collection of distinct objects.
In Java, you have something called HashSet. And if you want the order to be maintained then use LinkedHashSet.
int [] intputArray = {5,5,3,6,3,5,2,1};
LinkedHashSet<Integer> set = new LinkedHashSet<Integer>();
//add all the elements into set
for(int number:intputArray) {
set.add(number);
}
for(int element:set) {
System.out.print(element+" ");
}
You can make this using help array with lenght of 10 if the order is not important.
int [] intputArray = {5,5,3,6,3,5,2,1};
int [] helpArray = new int[10];
for(int i = 0; i < intputArray.length ; i++){
helpArray[intputArray[i]]++;
}
for(int i = 0; i < helpArray.length ; i++){
if(helpArray[i] > 0){
System.out.print(i + " ");
}
}

Checking for specific integers in an array

First post here so I'm hoping I don't screw up.
My task is to have a user enter an array of 10 integers and then input another integer separately and have the program either retrieve that number if it's in the array, or give an error if not.
I'm having trouble comparing the inputted integer with those in the array.
Here's part of my code, with the rest found below:
try{
System.out.print("Please enter 10 integers to store in an array and then press enter: ");
for(int index = 0; index < numbers.length; index++)
numbers[index] = input.nextInt();
if(numbers.length==10){ //method doesnt work properly if you input over 10 integers, only if you input less
System.out.print("Thanks for entering 10 integers. Now input an integer to check: ");
int compare = input.nextInt();
if(numbers[index] == compare){ //this is where the error is I believe
System.out.print(compare); //here too
}
http://pastebin.com/U5PdJgr6
Thank you in advance!
If you're using java-8, you can perform that easily using an IntStream
boolean contained = IntStream.of(inputtedNumbers)
.anyMatch(x -> x == numberToSearch);
Turn
if (numbers[index] == compare) {
System.out.print(compare);
}
Into
boolean found;
for (int number : numbers) {
found = number == compare;
if (found) break;
}
if (found) System.out.print(compare);
else throw new Exception("Number Not Found");
P.S. You don't need to check to make sure numbers.length is still 10. The length of an array is always final and can't change.
package integerarrayexceptions;
import java.util.Scanner;
import java.util.InputMismatchException;
public class IntegerArrayExceptions {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numbers[] = new int[10];
try{
System.out.print("Please enter 10 integers to store in an array and then press enter: ");
for(int index = 0; index < numbers.length; index++)
numbers[index] = input.nextInt(); //The loop only applies to this statement.
if(numbers.length==10){
System.out.print("Thanks for entering 10 integers. Now input an integer to check: ");
int compare = input.nextInt();
for (int index2 = 0; index2 < numbers.length; index2++) {
if(numbers[index2] == compare){
System.out.print(compare);
}
}
}
}
catch (InputMismatchException MismatchException)
{
System.out.print("One or more values entered is not an integer.");
}
}
}
There's a loop missing after you entered the compare value:
for (index = 0; index < numbers.length; index++) {
if(numbers[index] == compare){
System.out.print(compare);
}
]
You try to use the variable "index" outside the "for" loop, where it does not exist...

Sorting even numbers from original array

I have to create a program that reads an arbitrary number of positive integers from the user and store them into an array. The number of input data is not more than 100. After the user finishes the program should remove all even integers and place them in another array leaving all odd integers in the original array with no holes. It should display the contents in the original array as the order of input, the contents of the even integer array with a count, and the contents of the original array after taking out all even integers with a count
No third array should be used
Im having trouble displaying the original array and original integer array after taking out the even integers. here is my code so far
import java.util.*;
public class Arrays
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter in any amount of positive numbers, Enter -1 when finished");
int i=0;
int nextElm=0;
int a,b;
int[] origArray = new int[100]; /* Two arrays at length 100*/
int[] evenArray = new int[100];
while((i<origArray.length && i<evenArray.length)&& nextElm!= -1)
{
System.out.println("Enter next number: ");
nextElm = scan.nextInt();
if (nextElm%2 != 0)//Sorts even numbers
{
origArray[i]= nextElm;
}
else
evenArray[i] = nextElm;
i++;
}
System.out.print("\n");
System.out.println("Even Array: ");
for (b=0; b<evenArray.length;b++)
{
if (evenArray[b]== -1)
{
evenArray[b]= 0;
}
if(evenArray[b]!= 0)
{
System.out.print(evenArray[b]+" ");
}
}
System.out.print("\n");
System.out.println("Original Array: ");
for(a=0; a<origArray.length && a<evenArray.length; a++)
{
if (origArray[a]== -1)
{
origArray[a]= 0;
}
if(origArray[a]!= 0)
{
System.out.print(origArray[a]+" " + evenArray[a]);
}
}
System.out.print("\n");
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter in any amount of positive numbers, Enter -1 when finished");
int i = 0;
int nextElm = 0;
int a, b;
int[] origArray = new int[100]; /* Two arrays at length 100 */
int[] evenArray = new int[100];
while (nextElm != -1) {
System.out.println("Enter next number: ");
nextElm = scan.nextInt();
if (nextElm > 0) {
origArray[i] = nextElm;
i++;
}
}
int x = 0;
System.out.println();
// Displays original array and sorts even numbers to even array +
// original count
System.out.printf("\nTotal count of original array is : %d", i);
System.out.println();
for (int orgNumber : origArray) {
if (orgNumber != 0) {
System.out.print(orgNumber + " ");
}
if (orgNumber % 2 == 0) {
if (orgNumber != 0) {
evenArray[x] = orgNumber;
x++;
}
}
}
System.out.println();
// Displays sort even numbers to even array + even count
System.out.printf("\nTotal count of even array is : %d", x);
System.out.println();
for (int evenNumber : evenArray) {
if (evenNumber != 0) {
System.out.print(evenNumber + " ");
}
}
// Displays sort odd numbers from original array + odd count
System.out.printf("\nTotal count of orignal array without even is : %d", i - x);
System.out.println();
for (int oddNumber : origArray) {
if (oddNumber % 2 != 0) {
System.out.print(oddNumber + " ");
}
}
}
This should work perfectly if I understood your question well. Hope you find this helpful.
You want three separate loops. One for inputting the values (I would suggest the while construct as you have done) and one for sorting the values.
Your input loop should read in a new number each time and only quit when the user wants to. For example, if the user inputs a negative number, then your loop will quit. Like this:
System.out.println("Enter any number of numbers; enter a negative when finished.");
int nextElm = 0;
int count = 0;
while (nextElm >= 0) {
nextElm = scan.nextInt();
origArray[count] = nextElm;
count++;
}
// This is where you would put a print statement that prints the original array with a count.
Now after this, use the java.util.Arrays.copyOf() method to trim out the empty elements of the array, like so:
origArray = java.util.Arrays.copyOf(origArray, count+1);
Next, use a for loop to iterate through the array, and move even numbers to the other array. This is the tricky part, because removing items from an array requires iteration to move each value to it's previous index.
int j = 0;
for (int i=0; i<count; i++){
if (origArray[i] % 2 == 0){
evenArray[j] = origArray[i]; //add even number to evenArray
j++; //move to next index of evenArray
for (int k=i; k<(origArray.length-1); k++){
origArray[k] = origArray[k+1]; //store next value in current index
}
}
}
Then finally, use the java.util.Arrays.copyOf() method to trim out the empty elements of the array again, like so:
evenArray = java.util.Arrays.copyOf(evenArray, j+1);
Disclaimer: This was all coded from the hip so let me know if I missed something or did something incorrectly.

finding the number of pairs of numbers in an array that add up to a number

I am trying to come up with a program that will search inside of an array that is given a length by the user that picks out whether there is a pair of numbers that sum to 7. The idea is that if there is k amount of dice being thrown, how many pairs of numbers out of those dice thrown add up to 7. So far this is all that I could come up with but I am very stuck.
This is the driver class for the program. I have to write a class that will make this driver function properly.
import java.util.Scanner;
public class SevenDriver{
public static void main(String[] args){
System.out.println("Enter number of dice to toss");
Scanner s = new Scanner(System.in);
int diceCount = s.nextInt();
SevenTally t = new SevenTally(diceCount);
int experiments = 1000000;
int wins = 0;
for(int j = 0; j < experiments; j++)
if(t.experiment()) wins++;
System.out.println((double)wins/experiments);
}
}
This is what I have so far. It does not currently work or compile. I am just looking for some ideas to get me going. Thanks!
public class SevenTally{
private int diceCount;
public SevenTally(int die){
diceCount = die;
}
public int genDice(){
return 1 + (int)(Math.random()*6);
}
public boolean experiment(){
boolean[] nums = new boolean[diceCount];
int ranNum;
int sum = 7;
for(int i = 0; i < nums.length; i++){
ranNum = genDice();
if (nums[ranNum] == sum){
return true;
}
}
int left = 0;
int right = nums.length - 1;
while(left<right){
int tempSum = nums[left] + nums[right];
if(tempSum == 7){
return true;
}
else if(tempSum>7){
right--;
}
return false;
}
}
First populate your array of length k with random int in [1;6]
The number of possible pairs in an array of length k is the number of 2-combinations in the array, which is (k-1)*k/2 (http://en.wikipedia.org/wiki/Combination)
You can test all the possible pairs (i,j) in your array like so:
int win = 0;
int tally = 7;
for(int i=0; i<k-1; i++){
for(int j=i+1; j<k; j++){
if(array[i]+array[j] == tally){
win++;
}
}
}
What this does is that it sets the first element of the pair to be the first element of the array, and sums it with the other elements one after the other.
It pairs array[0] with array[1] to array[k-1] at the first pass of the i for loop, that's k pairs.
Then k-1 pairs at second pass, and so on.
You end up with (k)+(k-1)+(k-2)+...+1 pairs, and that's exactly (k-1)*k/2 pairs.
done =]
edit: sorry, haven't read the whole thing. the method experiment() is supposed to return a boolean. you can return win>0?true:false; for example...
This Wiki page has some algorithms to do that. Its not a trivial problem...
You're generating a random number in ranNum, and then using it as an index into the array nums. Meanwhile, nums never gets filled, so no matter which box you index into, it never contains a 7.
What you want to do, if I understand your problem correctly, is fill each space in the array with the result of a die roll, then compare every two positions (rolls) to see if they sum to seven. You can do that using a nested for loop.
Essentially, you want to do this: (written in pseudocode as I'm not a java programmer)
int[] results[numrolls]
for (count = 0 to numrolls-1) { results[numrolls]=dieRoller() }
for (outer = 0 to numrolls-2)
for (inner = outer+1 to numrolls-1)
if (results[outer] + results[inner] == 7) return true
return false;
However, in this case there's an even easier way. You know that the only ways to get a sum of 7 on 2d6 are (1,6),(2,5),(3,4),(4,3),(5,2),(6,1). Set up a 6-length boolean array, roll your dice, and after each roll set res[result] to true. Then return (1-based array used for simplicity) ( (res[1] && res[6]) || (res[2] && res[5]) || (res[3] && res[4]) ).
ArrayIndexOutOfBoundsException means you are trying to access an element of the array that hasn't been allocated.
In your code, you create a new array d of length diceCount, but then you genDice() on always 6 elements.

Categories