This is a program with an 'AI' that plays Bulls and cows.
Bulls and cows is a code-breaking game where you think of 4 digit number and the other layer tries to guess it: https://en.wikipedia.org/wiki/Bulls_and_Cows
There are two classes:
BandC
- where all the logic is.BcCount
- which is a pair of bull and cow count.
Any advice is welcome. Especially overall design/making my code more idiomatic and readable/simple.
package BullsAndCows;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
public class BandC {
public static void main(String[] args) {
Set<String> possibleNums = generatePossibleNums();
int steps = 0;
System.out.println("Hello! I am your computer!\nNow think of a number...");
Scanner reader = new Scanner(System.in);
while (true) {
steps++;
Iterator<String> iter = possibleNums.iterator();
String AIguess = iter.next();
System.out.println("My guess is: " + AIguess);
System.out.print("Number of cows:");
int numberOfCows = reader.nextInt();
System.out.print("Number of bulls:");
int numberOfBulls = reader.nextInt();
removeWrongNums(new BcCount(numberOfBulls, numberOfCows), AIguess, possibleNums);
if (numberOfBulls == 4) {
System.out.println("Guessed in " + steps + " steps");
break;
}
}
reader.close();
}
public static BcCount calcBullandCowCount(String guess, String candidate) {
BcCount bcCount = new BcCount(0, 0);
for (int i = 0; i < candidate.length(); i++) {
if (guess.charAt(i) == candidate.charAt(i)) {
bcCount.bullCount++;
} else if (guess.contains(String.valueOf(candidate.charAt(i)))) {
bcCount.cowCount++;
}
}
return bcCount;
}
public static Set<String> generatePossibleNums() {
Set<String> set = new HashSet<String>();
for (int i = 1000; i < 10_000; i++) {
set.add(String.valueOf(i));
}
Iterator<String> iter = set.iterator();
while (iter.hasNext()) {
String str = iter.next();
Set<Character> digits = new HashSet<>();
for (char c : str.toCharArray()) {
if (digits.contains(c)) {
iter.remove();
break;
}
digits.add(c);
}
}
return set;
}
public static void removeWrongNums(BcCount guessBcCount, String guess,
Set<String> possibleNums) {
Iterator<String> iter = possibleNums.iterator();
while (iter.hasNext()) {
String str = iter.next();
if (calcBullandCowCount(guess, str).equals(guessBcCount) == false) {
iter.remove();
}
}
}
}
BcCount.java
package BullsAndCows;
public class BcCount {
public int bullCount = 0;
public int cowCount = 0;
public BcCount(int b, int c) {
bullCount = b;
cowCount = c;
}
public String toString() {
return bullCount + " " + cowCount;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BcCount other = (BcCount) obj;
if (bullCount != other.bullCount)
return false;
if (cowCount != other.cowCount)
return false;
return true;
}
}