/* SENG111 Assignment I - the PNZ Game By Geoff Knagge (9806135) */ import java.awt.*; import BreezyGUI.*; public class PNZApplet extends GBApplet { // The globals variables are all declared here String winningString; int numberGuesses; final String gameOverMsg = "Game Over. Select \"Start New Game\" to restart."; // set up the input section Label guessLabel = addLabel("Enter your guess here: ",6,1,1,1); TextField guessField = addTextField("",6,2,3,1); Button evaluate = addButton("Evaluate Guess",7,2,1,1); Button giveUp = addButton("Give Up!",7,3,1,1); Button newGame = addButton("Start New Game",7,4,1,1); // set up the feedback section TextArea history = addTextArea("",1,1, 6, 5); char randomDigit() // returns a random character in the range '0' to '9' inclusive // no inputs { return (char)('0' + Math.random() * 10); } String randomString() // Generates a string of 3 unique digits // Inputs : none // Output : a string of length 3, each character is a unique numeric digit { String target = "\0\0\0"; //dummy characters to avoid out of range errors char digit; for (int cnt=0; cnt <3; cnt++) //loop until we have 3 digits do { digit = randomDigit(); if ( (target.charAt(0) != digit) && (target.charAt(1) != digit) && (target.charAt(2) != digit)) target = digit + target; // If unique, add it! else digit = '-'; // Otherwise, clear it } while (digit == '-'); // loop until we find a unique digit return target.substring(0,3); // return the string of unique digits } String evaluateGuess(String target, String guess) // Compares the user's guess to the winning combination, and generates // feedback according to the rules of the PNZ Game. // Inputs : The winning combination, the user's guess // Output : A string of varying length containing the characters // 'P','N','Z' { int perfectMatches = 0; int numberMatches = 0; String feedback = ""; for (int cnt=0; cnt<3; cnt++) // check all 3 digits for matches... { if (target.charAt(cnt)==guess.charAt(cnt)) perfectMatches++; // digit is in the right spot if ( (target.charAt(0)==guess.charAt(cnt)) || (target.charAt(1)==guess.charAt(cnt)) || (target.charAt(2)==guess.charAt(cnt))) numberMatches++; // digit is anywhere in the winning string } for (int cnt=0; cnt < perfectMatches; cnt++) feedback += 'P'; // add one "P" for each perfect match for (int cnt = perfectMatches; cnt < numberMatches; cnt++) feedback += 'N'; // the rest of the matches must be in the wrong spot if (numberMatches==0) feedback = "Z"; return feedback; } boolean guessValid(String guess) // checks to see if the user's guess is of length 3 and contains only // numeric digits, each of which are unique. // Input : the user's guess // Output : true if the above conditions are met, false if not { if (guess.length()!=3) return false; // wrong number of digits for (int count1=0; count1<3; count1++) // validifying all 3 digits... { if ( ! Character.isDigit(guess.charAt(count1)) ) return false; // it wasn't a numeric digit for (int count2=count1+1; count2<3; count2++) if ((guess.charAt(count1)==guess.charAt(count2)) ) return false; // the digit is repeated elsewhere in the string } return true; } void displayResults(String guess, String result) // Input : The user's guess, the results to be displayed // Output : none returned to caller, Inputs displayed on GUI { history.append(" "+guess+" "+result+'\n'); //write to the text box } void disableInputs() // disables the inputs on the GUI so that no more guesses can be made after // the game has finished. { guessField.setEnabled(false); //disable the input things so no evaluate.setEnabled(false); //more guesses can be made giveUp.setEnabled(false); history.append(gameOverMsg); guessField.setText(gameOverMsg); } void focusInput() // Gives the focus to the input field and selects the text in the field // so that it's more user friendly :-) { guessField.requestFocus(); // game still going: make input box active guessField.selectAll(); // and select text so it is easily overwritten } void processValidGuess(String guess) // Checks the user's guess to see how closely it matches, and returns // appropriate feedback, including if the game has been won. // Input : The user's guess (assumed to have been checked for validity // elsewhere in the program), the number of guesses made in this // game { String results = evaluateGuess(winningString,guess); //get the PNZ output numberGuesses++; displayResults(guess,results); if ( results.compareTo("PPP")==0 ) // if the game has been won... { disableInputs(); String cntStr; // generate a message depending guess count... if (numberGuesses==1) cntStr="first guess!!!"; else cntStr="in "+String.valueOf(numberGuesses)+" Guesses"; messageBox("That's the correct combination!\nYou found it "+cntStr); } else focusInput(); } void processGuess(String guess) // Check if the user's guess conforms to the rules. If so, go and process // it, otherwise return an error message. // Inputs : the user's guess, the number of guesses made during this game { guess = guess.trim(); // remove whitespace if (guessValid(guess)) processValidGuess(guess); else { focusInput(); messageBox("That's an invalid Guess!\n" +"You must only enter 3 unique digits!"); } } void startNewGame() // reinitialise all the variables and objects in preparation for a new game { winningString = randomString(); // get a new set of 3 digits giveUp.setEnabled(true); // ensure inputs are enabled evaluate.setEnabled(true); guessField.setEnabled(true); guessField.setText(""); // clear the input field guessField.requestFocus(); // activate input field - user friendly :-) numberGuesses = 0; history.setEditable(false); // stop user messing with the feedback :-P // the following long line sets up the instructions in feedback box history.setText("A number consisting of three unique digits has been" +" chosen. The aim is\nto guess these digits in the " +"correct order, using the provided feedback\nas a " +"guide.\n\nFor each guess, a P will be displayed for" +" each correct digit in the\ncorrect position, " +"followed by an N for each digit that is correct, " +"but\nin an incorrect position. A Z indicates that " +"all digits are incorrect\n\nGuess Feedback\n" ); } public void buttonClicked(Button buttonObj) // Event handler for the clicking of one of the buttons. Determines which // has been pressed and calls the corresponding methods. // Input : the button which was pressed. { if (buttonObj==newGame) { startNewGame(); history.setCaretPosition(0); } if (buttonObj==giveUp) { history.append("Given up?! The correct combination was "+winningString+'\n'); disableInputs(); messageBox("Given up after "+String.valueOf(numberGuesses)+ " guesses?!\nThe correct combination was "+winningString); } if (buttonObj==evaluate) processGuess(guessField.getText()); } public void init() // the class constructor to do some special initialisation { startNewGame(); } }