SHARE
SPREAD
HELP

The Tradition of Sharing

Help your friends and juniors by posting answers to the questions that you know. Also post questions that are not available.


To start with, Sr2Jr’s first step is to reduce the expenses related to education. To achieve this goal Sr2Jr organized the textbook’s question and answers. Sr2Jr is community based and need your support to fill the question and answers. The question and answers posted will be available free of cost to all.

 

#
Authors:
Stuart Reges, Marty Stepp
Chapter:
Arrays
Exercise:
Programming Projects
Question:3 | ISBN:9780136091813 | Edition: 2

Question

Write a program that plays a variation of the game of Mastermind with a user. For example, the program can use pseudorandom numbers to generate a four-digit number. The user should be allowed to make guesses until she gets the number correct. Clues should be given to the user indicating how many digits of the guess are correct and in the correct place and how many digits are correct but in the wrong place.

TextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbookTextbook

Answer

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;

public class MastermindDemo {

	private Scanner keyboard;
	private String input;

	private static int mode;
	private final int STANDARD_MODE = 6;
	private final int CHALLENGE_MODE = 7;

	private char[][] guess;
	private char[][] key;

	private char[] answer;

	private MasterminChoice answerGenerator;

	private boolean winner;

	private GuessMastermind guessEvaluator;
	private int totalHits;
	private int totalGuesses;
	private int guessCount;
	private int hintsUsed = 0;

	public MastermindDemo(int mode) {
		MastermindDemo.mode = mode;
		keyboard = new Scanner(System.in);
		winner = false;
		totalHits = 0;
		answerGenerator = new MasterminChoice(STANDARD_MODE);
		answer = answerGenerator.getAnswer();
		totalGuesses = 0;
		guessCount = 0;
		guess = new char[30][mode - 2];
		key = new char[30][mode - 2];
	}

	public MastermindDemo() {
		keyboard = new Scanner(System.in);
	}

	public static void main(String[] args) throws IOException {

		boolean successfulStart = false;

		MastermindDemo MMGame;
		int mode = 0;
		do {
			successfulStart = false;

			MMGame = new MastermindDemo();

			successfulStart = MMGame.startNewGame();

			if (successfulStart) {

				MMGame.setMode();

				mode = MMGame.getMode();
				MMGame = new MastermindDemo(mode);

				MMGame.answerGenerator = new MasterminChoice(mode);
				MMGame.answer = MMGame.answerGenerator.getAnswer();

				do {

					MMGame.guess[MMGame.totalGuesses] = MMGame.getGuess();

					MMGame.guessEvaluator = new GuessMastermind(MMGame.guess[MMGame.totalGuesses], MMGame.answer);

					MMGame.winner = MMGame.guessEvaluator.evaluateGuess();

					MMGame.key[MMGame.totalGuesses] = MMGame.guessEvaluator.getKey();

					MMGame.totalHits += MMGame.guessEvaluator.getSingleHits();

					MMGame.guessCount++;

					System.out.print("\n Your hits: ");
					for (int i = MMGame.key[MMGame.totalGuesses].length - 1; i >= 0; i--)
						System.out.print(MMGame.key[MMGame.totalGuesses][i] + " ");

				}

				while (!MMGame.winner && MMGame.continueCurrentGame());

				if (MMGame.winner) {

					System.out.println("Congratulations! You win!");
					System.out.println("********************************************************************");
					System.out.println("It took you " + MMGame.guessCount + " guesses.");
					System.out.println(
							"You Averaged " + MMGame.totalHits / ((double) MMGame.guessCount) + " Points Per Guess.");

					MastermindPlans statsController = new MastermindPlans();
					statsController.setMode(mode);
					statsController.saveStats(MMGame.guessCount);

				}
			}

			else {
				break;
			}
		}

		while (successfulStart);
	}

	public boolean startNewGame() throws IOException {

		boolean successfulStart = false;

		do {
			System.out.println("Ready to start a new game? y = yes, n = no, s = show stats");
			input = keyboard.nextLine();

			if (input.equalsIgnoreCase("y") || input.equalsIgnoreCase("yes")) {
				successfulStart = true;
				return true;
			} else if (input.equalsIgnoreCase("n") || input.equalsIgnoreCase("no")) {
				System.out.println("Thank you for playing! Bye!");
				successfulStart = true;
				return false;
			} else if (input.equalsIgnoreCase("s") || input.equalsIgnoreCase("show stats")) {
				System.out.println("*****************************************************");
				System.out.println("MasterMind Statistics");
				System.out.println("***************************");
				System.out.println("Standard Mode");
				MastermindPlans stats = new MastermindPlans();
				stats.setMode(STANDARD_MODE);
				stats.displayStats();
				System.out.println("***************************");
				System.out.println("Advanced Mode");
				stats.setMode(CHALLENGE_MODE);
				stats.displayStats();
				System.out.println("*****************************************************");

				successfulStart = false;
			} else {
				System.out.println("Error in reading your input.");
				successfulStart = false;
			}
		}

		while (!successfulStart);

		return successfulStart;
	}

	public boolean setMode() {

		boolean successfulSetMode = false;

		do {
			System.out.println("Please choose: s = standard mode ( use 6 colors and 4 holes)");
			System.out.println(" c = challenge mode( use 7 colors and 5 holes)");
			input = keyboard.nextLine();

			if (input.equalsIgnoreCase("s")) {
				mode = STANDARD_MODE;
				successfulSetMode = true;
				return true;
			} else if (input.equalsIgnoreCase("c")) {
				mode = CHALLENGE_MODE;
				successfulSetMode = true;
				return true;
			} else {
				System.out.println("Error in reading your input.");
				successfulSetMode = false;
			}
		}

		while (!successfulSetMode);

		return successfulSetMode;
	}

	public int getMode() {
		return mode;
	}

	public char[] getGuess() {

		int colorPosition = 1;

		boolean successfulGetGuess = false;

		do {

			if (mode == STANDARD_MODE) {
				guess[totalGuesses] = new char[4];
				System.out.println("Please choose four colors from:");
				System.out.println("r = red o = orange y = yellow g = green b = blue i = indigo");
				successfulGetGuess = getColorInput(colorPosition);

				for (colorPosition = 2; colorPosition <= 4 && successfulGetGuess; colorPosition++) {
					successfulGetGuess = false;
					successfulGetGuess = getColorInput(colorPosition);
				}
			}

			if (mode == CHALLENGE_MODE) {
				guess[totalGuesses] = new char[5];
				System.out.println("Please choose the colors for 5 holes from:");
				System.out.println("r = red o = orange y = yellow g = green b = blue i = indigo v = violet");
				successfulGetGuess = getColorInput(colorPosition);

				for (colorPosition = 2; colorPosition <= 5 && successfulGetGuess; colorPosition++) {
					successfulGetGuess = false;
					successfulGetGuess = getColorInput(colorPosition);
				}
			}

			if (!successfulGetGuess) {
				System.out.println("Problem with getting your guess.");
			}
		}

		while ((!successfulGetGuess) && continueCurrentGame());

		System.out.print("\n Your guess: ");
		for (int i = 0; i <= guess[totalGuesses].length - 1; i++) {
			System.out.print(guess[totalGuesses][i] + " ");

		}
		System.out.println();

		return guess[totalGuesses];
	}

	public boolean getColorInput(int colorPosition) {

		boolean successfulGetColor = false;

		if (mode == STANDARD_MODE) {
			do {
				System.out.print(colorPosition + ": ");
				input = keyboard.nextLine();
				if (input.equalsIgnoreCase("r") || input.equalsIgnoreCase("red")) {
					guess[totalGuesses][colorPosition - 1] = 'r';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("o") || input.equalsIgnoreCase("orange")) {
					guess[totalGuesses][colorPosition - 1] = 'o';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("y") || input.equalsIgnoreCase("yellow")) {
					guess[totalGuesses][colorPosition - 1] = 'y';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("g") || input.equalsIgnoreCase("green")) {
					guess[totalGuesses][colorPosition - 1] = 'g';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("b") || input.equalsIgnoreCase("blue")) {
					guess[totalGuesses][colorPosition - 1] = 'b';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("i") || input.equalsIgnoreCase("indigo")) {
					guess[totalGuesses][colorPosition - 1] = 'i';
					successfulGetColor = true;
					return true;
				} else {
					System.out.println("Error in reading you input.");
					successfulGetColor = false;
				}
			} while (!successfulGetColor);

			return successfulGetColor;
		}
		if (mode == CHALLENGE_MODE) {
			do {
				System.out.print(colorPosition + ": ");

				input = keyboard.nextLine();
				if (input.equalsIgnoreCase("r") || input.equalsIgnoreCase("red")) {
					guess[totalGuesses][colorPosition - 1] = 'r';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("o") || input.equalsIgnoreCase("orange")) {
					guess[totalGuesses][colorPosition - 1] = 'o';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("y") || input.equalsIgnoreCase("yellow")) {
					guess[totalGuesses][colorPosition - 1] = 'y';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("g") || input.equalsIgnoreCase("green")) {
					guess[totalGuesses][colorPosition - 1] = 'g';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("b") || input.equalsIgnoreCase("blue")) {
					guess[totalGuesses][colorPosition - 1] = 'b';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("i") || input.equalsIgnoreCase("indigo")) {
					guess[totalGuesses][colorPosition - 1] = 'i';
					successfulGetColor = true;
					return true;
				} else if (input.equalsIgnoreCase("v") || input.equalsIgnoreCase("violet")) {
					guess[totalGuesses][colorPosition - 1] = 'v';
					successfulGetColor = true;
					return true;
				} else {
					System.out.println("Error in reading you input.");
					successfulGetColor = false;
				}
			} while (!successfulGetColor);

			return successfulGetColor;
		}

		return successfulGetColor;
	}

	public boolean continueCurrentGame() {
		boolean successfulContinueCurrentGame = false;

		do {
			System.out.println("\nWould you like to continue or start a new game or get a hint?\n"
					+ "c = continue\ns = start a new game\nh = hint.");
			input = keyboard.nextLine();

			if (input.equalsIgnoreCase("c") || input.equalsIgnoreCase("continue")) {

				return true;

			}

			else if (input.equalsIgnoreCase("s") || input.equalsIgnoreCase("start"))
				return false;

			else if (input.equalsIgnoreCase("h") || input.equalsIgnoreCase("hint")) {
				MasterMind hint = new MasterMind(answer, hintsUsed);
				hintsUsed = hint.getHint();
				return true;
			}

			else {
				System.out.println("Error in reading your input.");
				successfulContinueCurrentGame = false;
			}
		}

		while (!successfulContinueCurrentGame);

		return successfulContinueCurrentGame;
	}

}

class MasterMind {
	private char[] answer;
	private int guessesUsed = 0;

	public MasterMind(char[] answer, int guesses) {
		this.answer = answer;
		this.guessesUsed = guesses;

	}

	public int getHint() {
		if (guessesUsed < answer.length) {
			System.out.println("There is at least one " + answer[guessesUsed] + " peg.");
		}

		guessesUsed++;

		return guessesUsed;
	}

	public static void main(String args[]) {
		MasterminChoice testAnswer = new MasterminChoice(6);
		System.out.println(testAnswer.getAnswer());

		for (int i = 0; i < 4; i++) {
			MasterMind hint = new MasterMind(testAnswer.getAnswer(), i);
			hint.getHint();
		}

	}

}

class GuessMastermind {
	private char[] answer;
	private char[] key;
	private char[] guess;
	private boolean[] guessUsed;
	private boolean[] answerUsed;
	private int singleHits;

	public GuessMastermind(char[] guess, char[] answer) {
		this.answer = answer;
		this.guess = guess;

		key = new char[answer.length];
		guessUsed = new boolean[answer.length];
		answerUsed = new boolean[answer.length];
		singleHits = 0;

		for (int i = 0; i <= answer.length - 1; i++) {
			key[i] = '0';
			guessUsed[i] = false;
			answerUsed[i] = false;

		}

	}

	public boolean evaluateGuess() {

		for (int i = 0; i <= answer.length - 1; i++) {
			if (guess[i] == answer[i] && guessUsed[i] == false && answerUsed[i] == false) {
				key[i] = 'X';
				guessUsed[i] = true;
				answerUsed[i] = true;

				singleHits += 2;
			}
		}

		for (int i = 0; i <= answer.length - 1; i++) {
			if (guessUsed[i] == false) {
				for (int j = 0; j <= answer.length - 1; j++) {
					if (guess[i] == answer[j] && guessUsed[i] == false && answerUsed[j] == false) {
						key[i] = 'x';
						guessUsed[i] = true;
						answerUsed[j] = true;

						singleHits++;
					}

				}
			}
		}

		if (singleHits == 2 * key.length)
			return true;
		else
			return false;
	}

	public char[] getKey() {
		Arrays.sort(key);
		return key;
	}

	public int getSingleHits() {
		return singleHits;
	}

	public String toString() {
		return "GuessMastermind [answer=" + Arrays.toString(answer) + ", key=" + Arrays.toString(key) + ", guess="
				+ Arrays.toString(guess) + ", guessUsed=" + Arrays.toString(guessUsed) + ", answerUsed="
				+ Arrays.toString(answerUsed) + ", singleHits=" + singleHits + " ]";
	}

	public static void main(String args[]) {
		char[] testGuess1 = { 'a', 'b', 'c', 'd' };
		char[] testAns1 = { 'x', 'y', 'z', 'c' };
		GuessMastermind tester1 = new GuessMastermind(testGuess1, testAns1);
		if (tester1.evaluateGuess())
			System.out.println("win");
		if (!tester1.evaluateGuess())
			System.out.println("lose");
		System.out.println(tester1);

		char[] testGuess2 = { 'c', 'o', 'g', 'c' };
		char[] testAns2 = { 'r', 'o', 'o', 'c' };
		GuessMastermind tester2 = new GuessMastermind(testGuess2, testAns2);
		if (tester2.evaluateGuess())
			System.out.println("win");
		if (!tester2.evaluateGuess())
			System.out.println("lose");
		System.out.println(tester2);

	}

}

class MasterminChoice {
	private char[] answer;
	private final int STANDARD_MODE = 6;
	private final int CHALLENGE_MODE = 7;

	public MasterminChoice(int mode) {

		if (mode == STANDARD_MODE) {

			answer = new char[4];

			int rand;

			rand = 1 + (int) (Math.random() * 6);
			answer[0] = convert(rand);

			rand = 1 + (int) (Math.random() * 6);
			answer[1] = convert(rand);

			rand = 1 + (int) (Math.random() * 6);
			answer[2] = convert(rand);

			rand = 1 + (int) (Math.random() * 6);
			answer[3] = convert(rand);
		}

		if (mode == CHALLENGE_MODE) {

			answer = new char[5];

			int rand;

			rand = 1 + (int) (Math.random() * 7);
			answer[0] = convert(rand);

			rand = 1 + (int) (Math.random() * 7);
			answer[1] = convert(rand);

			rand = 1 + (int) (Math.random() * 7);
			answer[2] = convert(rand);

			rand = 1 + (int) (Math.random() * 7);
			answer[3] = convert(rand);

			rand = 1 + (int) (Math.random() * 7);
			answer[4] = convert(rand);

		}

	}

	private char convert(int answerIndex) {
		switch (answerIndex) {

		case 1:
			return 'r';

		case 2:
			return 'o';

		case 3:
			return 'y';

		case 4:
			return 'g';

		case 5:
			return 'b';

		case 6:
			return 'i';

		case 7:
			return 'v';
		}

		return 'x';
	}

	public char[] getAnswer() {
		return answer;
	}

	public static void main(String args[]) {
		MasterminChoice standAns = new MasterminChoice(6);
		System.out.println(standAns.getAnswer());

		MasterminChoice chanAns = new MasterminChoice(7);
		System.out.println(chanAns.getAnswer());
	}

}

class MastermindPlans {
	private String FILE;
	int totalGames = 0;
	int MAX_SIZE = 101;
	int[] guessArray = new int[MAX_SIZE];
	int mode;

	public void setMode(int currentMode) {
		mode = currentMode;
	}

	private void loadStats() throws IOException {

		if (mode == 7) {
			FILE = "AdvancedMasterMind.txt";
		} else {
			FILE = "StandardMasterMind.txt";
		}

		String line;
		int guessCount = 0;
		boolean hasTotal = false;
		int tokenItem;
		BufferedReader br = new BufferedReader(new FileReader(FILE));

		while ((line = br.readLine()) != null) {

			StringTokenizer token = new StringTokenizer(line);

			while (token.hasMoreTokens()) {

				tokenItem = Integer.parseInt(token.nextToken());
				if (hasTotal) {
					if (tokenItem != 0) {
						guessArray[guessCount] = tokenItem;
					}
				} else {
					totalGames = tokenItem;
					hasTotal = true;
				}

				guessCount++;
			}
		}

		br.close();
	}

	public void displayStats() throws IOException {

		loadStats();
		int guessCount = 0;

		System.out.println(totalGames + " Total Games Played");

		for (int i = 0; i < MAX_SIZE; i++) {
			if (guessArray[i] != 0) {
				System.out.println(guessArray[i] + " users took " + guessCount
						+ " guess(es) to successfully solve the MasterMind. ("
						+ (guessArray[i] / ((double) totalGames)) * 100 + "%)");
			}
			guessCount++;
		}
	}

	public void saveStats(int guessesUntilSuccess) throws IOException {

		loadStats();
		totalGames++;

		guessArray[guessesUntilSuccess] = guessArray[guessesUntilSuccess] + 1;

		BufferedWriter writer = new BufferedWriter(new FileWriter(FILE));

		writer.write(Integer.toString(totalGames));

		for (int i = 1; i < MAX_SIZE; i++) {
			writer.newLine();
			writer.write(Integer.toString(guessArray[i]));
		}

		writer.close();

	}

	public static void main(String args[]) throws IOException {

		MastermindPlans test = new MastermindPlans();
		test.displayStats();
	}

}

 

1 0

Discussions

Post the discussion to improve the above solution.