/* *********************************************************************************** Programmer: Joshua Beitelspacher Course Sec: 1323.001 Instructor: Mujiba Zaman T.A.: Warren Hsieh Project No: 5 Date: 11-29-2001 Description: SecretWordGame() Contains the main method. SecretWordWindow(SecretWord secretWord) Creates a window that implements the functionality of the SecretWord class. SecretWord(String path, String file),(String file),() Creates a secret word object that reads from a file. Can be constructed with a path and file name, just a file name for a file in the same directory, or with no argument for the default file ("WordList.txt" in the same directory). The file must be in a format with number of words on first line and words on each subsequent line up to the number. The secret word object is a game where the user attempts to guess a secret word. The user guesses one character at a time, and all instances of that character are then revealed, regardless of capitalization. Public methods public void reset() Randomly generates a new secret word for the user to guess. public boolean isGuessed() Returns true if the word has been guessed, false otherwise. public String checkProgress() Returns a string with the correct guessed characters revealed. Other characters remain as '*'s. public String getSecretWord() Returns the complete secret word. public boolean makeGuess(char guess) Used to guess a character in the secret word. Returns true if the character was in the secret word one or more times. public int guessesLeft() Tells the number of guesses left. Guesses initially equals the number of unknown charcters and is decremented for every incorrect guess. *************************************************************************************/ import java.io.*; import java.awt.*; import java.awt.event.*; class SecretWordGame { // main method public static void main(String[] args) { SecretWord secretWord = new SecretWord(); SecretWordWindow secretWordWindow = new SecretWordWindow(secretWord); secretWordWindow.show(); } } class SecretWordWindow extends Frame implements KeyListener, MouseListener, WindowListener { // -------------------------------------------------------------------------------- // Data Members // -------------------------------------------------------------------------------- private SecretWord secretWord; private final int FRAME_WIDTH = 340, FRAME_HEIGHT = 200, FRAME_MARGIN = 10, LETTER_WIDTH = 20, LETTER_HEIGHT = 20, LETTER_MARGIN = 5, TITLE_BAR_HEIGHT = 19; private final Color BACKGROUND_COLOR = new Color(40,77,70); private final Color BUTTON_COLOR = new Color(110,178,167); private final Color BUTTON_OVER_COLOR = new Color(90,153,143); private final Color BUTTON_DOWN_COLOR = new Color(71,134,123); private final Color BUTTON_CLICK_COLOR = new Color(54,101,93); private final Color LABEL_COLOR = new Color(178,221,212); private Label[] letterButton = new Label[26]; private Label solveButton, nextButton; private Label secretWordLabel, guessesLabel, blankLabel; private int buttonTop; private boolean buttonLock = false; // -------------------------------------------------------------------------------- // Constructor // -------------------------------------------------------------------------------- public SecretWordWindow(SecretWord secretWord) { // call parent constructor super("Secret Word Game"); // set passed secretWord to the class object this.secretWord = secretWord; // set frame properties setSize(FRAME_WIDTH,FRAME_HEIGHT); setResizable(false); Toolkit toolkit = Toolkit.getDefaultToolkit(); int xLocation = (toolkit.getScreenSize().width - FRAME_WIDTH) / 2; int yLocation = (toolkit.getScreenSize().height - FRAME_HEIGHT) / 2; setLocation(xLocation,yLocation); // run methods to place buttons and labels on frame letterButtonPlacer(); otherButtonPlacer(); labelPlacer(); // regester this frame as its own key and window listener addWindowListener(this); addKeyListener(this); } // -------------------------------------------------------------------------------- // Methods // -------------------------------------------------------------------------------- // place letter buttons on frame private void letterButtonPlacer() { // calculate information necessary to place letter buttons int lengthPerButton = LETTER_WIDTH + LETTER_MARGIN; int lengthPerRow = FRAME_WIDTH - 2 * FRAME_MARGIN + LETTER_MARGIN; int buttonsPerRow = lengthPerRow / lengthPerButton; int rowsNeeded = (int) Math.ceil((double) letterButton.length / buttonsPerRow); int xLocation, yLocation; // place letter buttons from left to right at frame bottom for (int i = 0; i < letterButton.length; i++) { // calculate individual button position xLocation = FRAME_MARGIN + (i % buttonsPerRow) * (LETTER_WIDTH + LETTER_MARGIN); yLocation = FRAME_HEIGHT - FRAME_MARGIN - (rowsNeeded - i / buttonsPerRow) * (LETTER_HEIGHT + LETTER_MARGIN) + LETTER_MARGIN; // place individual letter button letterButton[i] = new Label("" + (char) (i + 'A'), Label.CENTER); letterButton[i].setBounds(xLocation, yLocation, LETTER_WIDTH, LETTER_HEIGHT); letterButton[i].setBackground(BUTTON_COLOR); add(letterButton[i]); letterButton[i].addMouseListener(this); letterButton[i].addKeyListener(this); } // store variable to be used to position other elements buttonTop = FRAME_HEIGHT - FRAME_MARGIN - rowsNeeded * (LETTER_HEIGHT + LETTER_MARGIN); } // place other buttons on frame private void otherButtonPlacer() { // calculate information necessary to place other buttons int lengthPerButton = (FRAME_WIDTH - 2 * FRAME_MARGIN - LETTER_MARGIN) / 2; // place solve button across left half of frame and above letters solveButton = new Label("Solve Secret Word", Label.CENTER); solveButton.setBounds(FRAME_MARGIN, buttonTop - LETTER_HEIGHT, lengthPerButton, LETTER_HEIGHT); solveButton.setBackground(BUTTON_COLOR); add(solveButton); solveButton.addMouseListener(this); // place next buttons across right half of frame and above letters nextButton = new Label("Next Secret Word", Label.CENTER); nextButton.setBounds(FRAME_WIDTH - FRAME_MARGIN - lengthPerButton, buttonTop - LETTER_HEIGHT, lengthPerButton, LETTER_HEIGHT); nextButton.setBackground(BUTTON_COLOR); add(nextButton); nextButton.addMouseListener(this); // store variable to be used to position other elements buttonTop -= LETTER_HEIGHT + LETTER_MARGIN; } // place labels on frame private void labelPlacer() { // place guesses label above buttons guessesLabel = new Label("Guesses left: " + secretWord.guessesLeft(), Label.CENTER); guessesLabel.setBounds(FRAME_MARGIN, buttonTop - LETTER_HEIGHT, FRAME_WIDTH - 2 * FRAME_MARGIN, LETTER_HEIGHT); guessesLabel.setBackground(LABEL_COLOR); add(guessesLabel); // place secret word label above buttons secretWordLabel = new Label(secretWord.checkProgress(), Label.CENTER); secretWordLabel.setFont(new Font("Courier", Font.BOLD, 32)); secretWordLabel.setBounds(FRAME_MARGIN, FRAME_MARGIN + TITLE_BAR_HEIGHT, FRAME_WIDTH - 2 * FRAME_MARGIN, buttonTop - FRAME_MARGIN - LETTER_HEIGHT - TITLE_BAR_HEIGHT); secretWordLabel.setBackground(LABEL_COLOR); add(secretWordLabel); // place blank label in background blankLabel = new Label(); blankLabel.setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT); blankLabel.setBackground(BACKGROUND_COLOR); add(blankLabel); } // implementation of mouse listener public void mouseClicked(MouseEvent event) { // get label of clicked button Label sourceButton = (Label) event.getSource(); // pass to event handler eventHandler(sourceButton.getText()); } // implementation of key listener public void keyTyped(KeyEvent event) { // get char of key press char keyChar = event.getKeyChar(); // check if letter if (Character.isLetter(keyChar)) { // convert to uppercase keyChar = Character.toUpperCase(keyChar); // pass to event handler eventHandler("" + keyChar); } // if space, pass event as next button click else if (keyChar == ' ') { eventHandler("Next Secret Word"); } } // handles all events private void eventHandler(String label) { // check if it was a letter button if (!buttonLock && label.length() == 1) { // get number of the letter button int buttonNumber = (int) label.charAt(0) - 'A'; // check if letterButton has not already been pushed if (letterButton[buttonNumber].getBackground() != BUTTON_DOWN_COLOR) { // change button color and run make a guess letterButton[buttonNumber].setBackground(BUTTON_DOWN_COLOR); secretWord.makeGuess(label.charAt(0)); // display winning message if word guessed if (secretWord.isGuessed()) { guessesLabel.setText("You got the word with " + secretWord.guessesLeft() + " guesses left"); secretWordLabel.setText(secretWord.checkProgress()); // lock all buttons other than next buttonLock = true; } // display losing message if out of guesses else if (secretWord.guessesLeft() == 0) { guessesLabel.setText("Out of guesses, secret word shown"); secretWordLabel.setText(secretWord.getSecretWord()); // lock all buttons other than next buttonLock = true; } // display guesses left if guesses remain else { guessesLabel.setText("Guesses left: " + secretWord.guessesLeft()); secretWordLabel.setText(secretWord.checkProgress()); } } } // display secret word if solve button pressed else if (!buttonLock && label.equals("Solve Secret Word")) { guessesLabel.setText("Click 'Next Secret Word' to start a new game"); secretWordLabel.setText(secretWord.getSecretWord()); // lock all buttons other than next buttonLock = true; } // reset secret word else if (label.equals("Next Secret Word")) { buttonLock = false; for (int i = 0; i < letterButton.length; i++) { letterButton[i].setBackground(BUTTON_COLOR); } secretWord.reset(); guessesLabel.setText("Guesses left: " + secretWord.guessesLeft()); secretWordLabel.setText(secretWord.checkProgress()); } // prompt user to click next if a locked button clicked else { guessesLabel.setText("Click 'Next Secret Word' to start a new game"); } } public void mouseEntered(MouseEvent event) { // get label of clicked button Label sourceButton = (Label) event.getSource(); // if not down change color if (sourceButton.getBackground() != BUTTON_DOWN_COLOR) { sourceButton.setBackground(BUTTON_OVER_COLOR); } } public void mouseExited(MouseEvent event) { // get label of clicked button Label sourceButton = (Label) event.getSource(); // if not down change color if (sourceButton.getBackground() != BUTTON_DOWN_COLOR) { sourceButton.setBackground(BUTTON_COLOR); } } public void mousePressed(MouseEvent event) { // get label of clicked button Label sourceButton = (Label) event.getSource(); // if not down change color if (sourceButton.getBackground() != BUTTON_DOWN_COLOR) { sourceButton.setBackground(BUTTON_CLICK_COLOR); } } public void mouseReleased(MouseEvent event) { // get label of clicked button Label sourceButton = (Label) event.getSource(); // if not down change color if (sourceButton.getBackground() != BUTTON_DOWN_COLOR) { sourceButton.setBackground(BUTTON_COLOR); } } public void keyReleased(KeyEvent event) {} public void keyPressed(KeyEvent event) {} // implementation of window listener to activate close button public void windowClosing(WindowEvent event) {System.exit(0);} public void windowActivated(WindowEvent event) {} public void windowClosed(WindowEvent event) {} public void windowDeactivated(WindowEvent event) {} public void windowDeiconified(WindowEvent event) {} public void windowIconified(WindowEvent event) {} public void windowOpened(WindowEvent event) {} } class SecretWord { // -------------------------------------------------------------------------------- // Data Members // -------------------------------------------------------------------------------- private String[] wordList; private static final char UNKNOWN = '*'; private int chosenIndex; private int lastIndex; private String secretWord; private StringBuffer guessedWord; private int guessesLeft; // -------------------------------------------------------------------------------- // Constructors // -------------------------------------------------------------------------------- // constructor used for file in different directory public SecretWord(String path, String file) { // attempt to load specified file try { // open stream BufferedReader wordListBuffer = new BufferedReader(new FileReader(new File(path, file))); // get number of word list entries int length = Integer.decode(wordListBuffer.readLine()).intValue(); wordList = new String[length]; lastIndex = length; // fill array from file for (int i = 0; i < length; i++) { wordList[i] = wordListBuffer.readLine(); } // close stream wordListBuffer.close(); // run method to initialize to valid state reset(); } // if file load fails, initialize to a valid state catch (Exception e) { wordList = new String[1]; wordList[0] = "File I/O Error"; lastIndex = 0; reset(); } } // constructor used for file in same directory public SecretWord(String file) { this(".", file); } // constructor used for default file in same directory public SecretWord() { this("WordList.txt"); } // -------------------------------------------------------------------------------- // Methods // -------------------------------------------------------------------------------- // select new secret word public void reset() { // set last index to full array size if depleted if (lastIndex == 0) { lastIndex = wordList.length; } // get random secret word occuring before last index chosenIndex = (int) (Math.random() * lastIndex); secretWord = new String(wordList[chosenIndex]); // rearrange array so value at chosen index comes at last index lastIndex--; String temp = new String(wordList[chosenIndex]); wordList[chosenIndex] = new String(wordList[lastIndex]); wordList[lastIndex] = new String(temp); // call next method makeBlankGuess(); } // create blank guess from secret word private void makeBlankGuess() { // set current values to blank values guessesLeft = 0; guessedWord = new StringBuffer(); // run loop to make guessedWord and guessesLeft for (int i = 0; i < secretWord.length(); i++) { // add unknown character to guessed word and increment guesses left if (Character.isLetter(secretWord.charAt(i))) { guessedWord.append(UNKNOWN); guessesLeft++; } // copy character from secret word when it is not a letter else { guessedWord.append(secretWord.charAt(i)); } } } // return true if guessed word matches secret word public boolean isGuessed() { if (secretWord.equals(guessedWord.toString())) { return true; } else { return false; } } // return guessedWord as string public String checkProgress() { return guessedWord.toString(); } // return secret word public String getSecretWord() { return secretWord; } // take character and return true if it appears in secret word public boolean makeGuess(char guess) { // set initial boolean to false boolean wasCorrect = false; // run loop to replace characters in guessed with for (int i = 0; i < secretWord.length(); i++) { // check if passed character equal a character in secret word if (Character.toLowerCase(secretWord.charAt(i)) == Character.toLowerCase(guess)) { // replace character in guessed word with character in secret word guessedWord.setCharAt(i, secretWord.charAt(i)); // set boolean to correct wasCorrect = true; } } // decrement guesses left if guess was incorrect if (!wasCorrect) { guessesLeft--; } // return true if character was in secret word, false otherwise return wasCorrect; } // return guesses left public int guessesLeft() { return guessesLeft; } }