/* * BoggleGUI.java * * @author PaulKube and Michael Green * see http://www-cse.ucsd.edu/~kube/100/boggle/ */ package cs310; import java.awt.*; import javax.swing.*; import javax.swing.border.*; import java.util.*; import java.awt.event.*; import java.io.*; /** A GUI for the game of Boggle. * * BoggleGUI defines and implements methods to do these things: * * 1. Draw the boggle board * 2. Manage the computer and human players' word lists * 3. Update the scoreboard * * BoggleGUI requires class BogglePlayer, to define these instance methods: *
 * public void buildLexicon(Set wordList)
 * public void setBoard(String[] letterArray)
 * public SortedSet getAllValidWords(int minimumWordLength)
 * public boolean isInLexicon(String wordToCheck)
 * public java.util.List isOnBoard(String wordToCheck)
 * public String[] getCustomBoard()
 * 
* * @author Michael Green * @author Paul Kube * * Copyright (C) 2002 Michael Green * Copyright (C) 2002 Paul Kube * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. See * http://www.gnu.org/copyleft/gpl.html */ public class BoggleGUI extends JFrame { public static String WORDLISTFILENAME; public static int DICEROWS = 4; // default public static int DICECOLS = 4; // default public static int MINIMUMWORDLENGTH = 4; // default private BogglePlayer computerPlayer; private BoggleBoard theBoard; private ScoreArea humanArea, computerArea; private WordEntryField wordEntryField; public BoggleGUI() { super( "Welcome to B00GLE!"); // create a BogglePlayer computer player to use computerPlayer = new BogglePlayer(); // Read word list from file and initialize computerPlayer's Lexicon initLexicon(); /* Intialize graphics panelsur option) any later version. See * http://www.gnu.org/copyleft/gpl.html */ public class BoggleGUI extends JFrame { public static String WORDLISTFILENAME; public static int DICEROWS = 4; // default public static int DICECOLS = 4; // default public static int MINIMUMWORDLENGTH = 4; // default private BogglePlayer computerPlayer; private BoggleBoard theBoard; private ScoreArea humanArea, computerArea; private WordEntryField wordEntryField; public BoggleGUI() { super( "Welcome to B00GLE!"); // create a BogglePlayer computer player to use initPanels(); // Establish menu bar options and listeners for them setUpMenuBar(); // WindowClosing listener: for JDK 1.2 compatibility addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }}); // Trust contained components to set their sizes; top level frame packs pack(); } /** * Get ready for a new game, given a letter list specification of * the Boggle board. */ public void newGame(String[] letterList) { // Tell theBoard about the board layout theBoard.setBoard(letterList); // Tell computerPlayer about the board layout computerPlayer.setBoard(letterList); // Prepare score areas humanArea.setReady(); computerArea.setReady(); // Clear board highlighting theBoard.unHighlightAllDice(); // Allow edits to text area and set focus wordEntryField.setReady(); // redraw the whole thing so it looks as nice as can be repaint(); } /** * Consider a word entered by the human player. */ public void checkAndAddWordHuman(String wordToCheck) { // clear any board highlighting theBoard.unHighlightAllDice(); // if empty word, the computer gets to take its turn if(wordToCheck.length() == 0) { wordEntryField.setUnready(); computerPlay(); return; } // check that word is: // (1) at least minimum length, (2) on the board, (3) in the lexicon, // (4) not already entered by the player if(wordToCheck.length() < MINIMUMWORDLENGTH) { chideUser(wordToCheck, "Less Than " + MINIMUMWORDLENGTH + " Letters"); return; } java.util.List letterLocations; // letterLocations = theBoard.getLocationsForWord(wordToCheck); // String wordOnBoard = theBoard.getWordFromLocations(letterLocations); // if(!wordToCheck.equalsIgnoreCase(wordOnBoard)) { // double check // we just trust the computer player to check this letterLocations = computerPlayer.isOnBoard(wordToCheck); if(letterLocations == null) { chideUser(wordToCheck, "Not On Board"); return; } if(!computerPlayer.isInLexicon(wordToCheck)) { chideUser(wordToCheck, "Not In Lexicon"); return; } if(humanArea.containsWord(wordToCheck)) { chideUser(wordToCheck, "Duplicate Word"); return; } // OK, this word passed our rigorous suite of tests. Add it humanArea.addWord(wordToCheck); // Highlight locations on board theBoard.highlightDice(letterLocations); wordEntryField.clear(); //clear the wordEntryField text } public void chideUser(String attemptedWord, String complaint) { JOptionPane.showMessageDialog(this, attemptedWord + ": " + complaint + "!!!", complaint, JOptionPane.ERROR_MESSAGE); wordEntryField.clear(); //clear the wordEntryField text } /** * Let the computer player take its turn. */ public void computerPlay() { computerArea.setName("Thinking!"); computerArea.paintImmediately(computerArea.getVisibleRect()); SortedSet allWords = computerPlayer.getAllValidWords(MINIMUMWORDLENGTH); Iterator allWordsIterator = allWords.iterator(); computerArea.setName("Computer"); while(allWordsIterator.hasNext()) { String newWord = allWordsIterator.next(); java.util.List wordPath = computerPlayer.isOnBoard(newWord); // Add word to appropriate score area & highlight appropriate dice computerArea.addWord(newWord); theBoard.highlightDice(wordPath); // pause for a tenth of a second // try {Thread.sleep(100); } catch (Exception e) {} } theBoard.unHighlightAllDice(); // leave board unhighlighted when done } /** * Read word list from file with name WORDLISTFILENAME, and pass a Set * containing those words to the computer player to intialize its lexicon. */ private void initLexicon() { boolean EOF = false; ArrayList wordsFromFile = new ArrayList (); System.err.print("Reading word list from file " + WORDLISTFILENAME + "..."); try { // Open File BufferedReader input = new BufferedReader( new FileReader(WORDLISTFILENAME)); String nextWord; while((nextWord = input.readLine()) != null) wordsFromFile.add(nextWord.toLowerCase()); //Close the file input.close(); } catch (FileNotFoundException fnfex ) { JOptionPane.showMessageDialog(null, "Unable to find word list file " + WORDLISTFILENAME, "Error", JOptionPane.ERROR_MESSAGE); } catch( IOException e) { JOptionPane.showMessageDialog(null, "Error Opening File", "Error", JOptionPane.ERROR_MESSAGE); } System.err.println(" Read " + wordsFromFile.size() + " words."); System.err.print("Building player's lexicon... "); computerPlayer.buildLexicon(wordsFromFile); System.err.println("done."); } private void initPanels() { Container contentPane = getContentPane(); humanArea = new ScoreArea("Me"); computerArea = new ScoreArea("Computer"); theBoard = new BoggleBoard(DICEROWS,DICECOLS,computerPlayer); wordEntryField = new WordEntryField(); contentPane.add(wordEntryField,BorderLayout.SOUTH); contentPane.add(humanArea, BorderLayout.WEST); contentPane.add(theBoard, BorderLayout.CENTER); contentPane.add(computerArea, BorderLayout.EAST); } private void setUpMenuBar() { //Set Up Menu Bar JMenuBar menu = new JMenuBar(); // Game Menu JMenu gameMenu = new JMenu("Game"); gameMenu.setMnemonic('G'); menu.add(gameMenu); JMenuItem newRandom = new JMenuItem("New Random"); gameMenu.add(newRandom); newRandom.setMnemonic('N'); newRandom.addActionListener(new ActionListener() { public void actionPerformed( ActionEvent e) { newGame(theBoard.getRandomBoard()); }}); JMenuItem customGame = new JMenuItem("New Custom"); gameMenu.add(customGame); customGame.setMnemonic('C'); customGame.addActionListener(new ActionListener() { public void actionPerformed( ActionEvent e) { newGame(computerPlayer.getCustomBoard()); }}); JMenuItem quitGame = new JMenuItem("Quit"); gameMenu.add(quitGame); quitGame.setMnemonic('Q'); quitGame.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e) { System.exit(0); }}); // Help menu JMenu helpMenu = new JMenu("Help"); menu.add(helpMenu); helpMenu.setMnemonic('H'); JMenuItem aboutGame = new JMenuItem("About..."); helpMenu.add(aboutGame); aboutGame.setMnemonic('A'); aboutGame.addActionListener(new ActionListener() { public void actionPerformed( ActionEvent e) { JOptionPane.showMessageDialog(BoggleGUI.this, "It's ABOUT time you got to work", "About Game", JOptionPane.PLAIN_MESSAGE); }}); setJMenuBar(menu); } /** * A class defining the visual appearance of a Boggle board, and * defining some related methods. */ static class BoggleBoard extends JPanel { public static final Color BACKGROUNDCOLOR = new Color(255, 219, 13); private DiePanel theDice[][]; private Vector diceBag; // used for drawing dice for a random game private int rows, cols; private BogglePlayer theComputer; BoggleBoard(int rows, int cols, BogglePlayer theComputer ) { this.rows = rows; this.cols = cols; this.theComputer = theComputer; // create some dice to use when getting a random game initDiceBag(); // create a JPanel with rowsXcols GridLayout to hold the DiePanels JPanel innerPanel = new JPanel(); innerPanel.setLayout(new GridLayout(rows,cols,1,1)); innerPanel.setBackground(BACKGROUNDCOLOR); // Create Individual DiePanels, and add them theDice = new DiePanel[rows][cols]; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { theDice[row][col] = new DiePanel(); innerPanel.add(theDice[row][col]); } } innerPanel.setBorder(BorderFactory.createMatteBorder(10,10,10,10, BACKGROUNDCOLOR)); this.add(innerPanel); } // fill the diceBag with the 16 "official" Boggle dice for the 4X4 game private void initDiceBag() { diceBag = new Vector(16); diceBag.add(new Die("A", "O", "B", "B", "O", "J")); diceBag.add(new Die("W", "H", "G", "E", "E", "N")); diceBag.add(new Die("N", "R", "N", "Z", "H", "L")); diceBag.add(new Die("N", "A", "E", "A", "G", "E")); diceBag.add(new Die("D", "I", "Y", "S", "T", "T")); diceBag.add(new Die("I", "E", "S", "T", "S", "O")); diceBag.add(new Die("A", "O", "T", "T", "W", "O")); diceBag.add(new Die("H", "Qu", "U", "M", "N", "I")); diceBag.add(new Die("R", "Y", "T", "L", "T", "E")); diceBag.add(new Die("P", "O", "H", "C", "S", "A")); diceBag.add(new Die("L", "R", "E", "V", "Y", "D")); diceBag.add(new Die("E", "X", "L", "D", "I", "R")); diceBag.add(new Die("I", "E", "N", "S", "U", "E")); diceBag.add(new Die("S", "F", "F", "K", "A", "P")); diceBag.add(new Die("I", "O", "T", "M", "U", "C")); diceBag.add(new Die("E", "H", "W", "V", "T", "R")); } /** * Return an array of Strings showing the sequence of faces on * a randomly generated board. */ public String[] getRandomBoard() { // Get random faces from randomy selected dice to fill the letterList int diceBagSize = diceBag.size(); int boardSize = rows * cols; String[] letterList = new String[(rows * cols)]; // we try to handle any size board with a fixed diceBag for (int i = 0; i 0) WORDLISTFILENAME = args[0]; if(args.length > 1) DICEROWS = Integer.parseInt(args[1]); if(args.length > 2) DICECOLS = Integer.parseInt(args[2]); if(args.length > 3) MINIMUMWORDLENGTH = Integer.parseInt(args[3]); System.err.println("Starting " + DICEROWS + "x" + DICECOLS + " game," + " words from " + WORDLISTFILENAME + ", min word length " + MINIMUMWORDLENGTH + "."); (new BoggleGUI()).setVisible(true); } }