diff --git a/MasterMindGame.java b/MasterMindGame.java index 00e9754..a6edd97 100644 --- a/MasterMindGame.java +++ b/MasterMindGame.java @@ -1,4 +1,5 @@ import java.util.Optional; +import java.util.Random; /** * A code-breaking game where the app selects a sequence of symbols, and @@ -11,9 +12,23 @@ * @version 1 */ class MasterMindGame implements Game { + + private static final char[] VALID_CHARACTER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + private static final int CODE_LENGTH = 4; + public String getName() { return "MasterMind"; } public Optional play() { System.out.println("[Playing MasterMind - Placeholder]"); return Optional.empty(); } + + public String generateCode() { + Random r = new Random(System.nanoTime()); + StringBuilder out = new StringBuilder(); + for (int i = 0; i < CODE_LENGTH; i++) { + out.append(VALID_CHARACTER[r.nextInt(10)]); + } + return out.toString(); + } } diff --git a/MasterMindGameTest.java b/MasterMindGameTest.java new file mode 100644 index 0000000..5855398 --- /dev/null +++ b/MasterMindGameTest.java @@ -0,0 +1,82 @@ +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashSet; + +public class MasterMindGameTest { + + private MasterMindGame mm; + private static final char[] VALID_CHARACTER = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + + @BeforeEach + public void setUp() { + mm = new MasterMindGame(); + } + + @Test + public void testCodeLengthCorrectness() { + assertEquals(4, mm.generateCode().length()); + } + + @Test + public void testCodeContentCorrectness() { + int count = 100; + String[] codes = new String[count]; + for (int i = 0; i < count; i++) { + codes[i] = mm.generateCode(); + } + + assertEquals(0, checkIncorrectCharacters(codes)); + } + + private static int checkIncorrectCharacters(final String[] in) { + int out = 0; + for (int i = 0; i < in.length; i++) { + for (int j = 0; j < in[i].length(); j++) { + if (!contains(VALID_CHARACTER, in[i].charAt(j))) { + out++; + } + } + } + return out; + } + + private static boolean contains(final char[] bank, final char key) { + for (char b: bank) { + if (b == key) { + return true; + } + } + return false; + } + + @Test + public void testCodeRepetition() { + /* + * I was curious as to the odds of an overlap, and before spending ages + * rerunning "ant test" to no avail, I checked via Wolfram Alpha. + * It appears that 10,000 choose 100 (100 codes being checked, and + * values from 0000 to 9999) is on the order of 6 * 10^241. Code + * collisions are very unlikely given that many possible unique + * combinations. + */ + int count = 100; + HashSet codes = new HashSet<>(count); + for (int i = 0; i < count; i++) { + codes.add(mm.generateCode()); + } + + // Commented below after ensuring code equality check is correct + // printCodes(codes); + assertEquals(count, codes.size()); + } + + private static void printCodes(final HashSet in) { + for (String i: in) { + System.out.println(i); + } + } +}