import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; class WordInfo { String originalWord; // Store the full word here. You must do this. int subWordLength; // What is the length of each subword here. Again, you need to set this correctly. LinkedList subWords; // The list of subwords of that length. LinkedList foundSubWords; // This is all the words currently found by the user. // This will print out all the subwords into a string. public String toString () { String s = "Subwords of string \"" + originalWord + "\" of length " + subWordLength + ": \n"; if ( (subWords == null) || (subWords.size() == 0) ) { s += " NONE"; return s; } for (int i=0; i wordList; // This is a list of words or puzzles, one per game. int wordListCount; // Where we are in our list. String currentWord; // The current word, unscrambled. WordInfo[] subWordInfo; // For the current word, all the subword info. ///////////////////////////////////////////////////////////////////////////////// // // Constructor. This has all the GUI building stuff. public TextTwistGUI () { // Set some parameters of the frame (window) that's brought up. this.setSize (600, 600); this.setTitle ("TextTwist"); this.setResizable (true); // This is how stuff is put into a frame. Container cPane = this.getContentPane(); // Label at the top. topLabel = new JLabel(" "); cPane.add (topLabel, BorderLayout.NORTH); // Create an instance of the text area and put that in a scrollpane. textArea = new JTextArea (); scrollPane = new JScrollPane (textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); cPane.add (scrollPane, BorderLayout.CENTER); // Make the controls. This has two parts. JPanel bottomPanel = new JPanel (); bottomPanel.setLayout (new GridLayout(2,1)); JPanel topPart = new JPanel (); wordLabel = new JLabel (" "); wordLabel.setFont (new Font ("Serif", Font.BOLD, 30)); topPart.add (wordLabel); topPart.add (new JLabel (" ")); bottomPanel.add (topPart); JPanel bottomPart = new JPanel (); JLabel label = new JLabel ("Enter sub-word: "); bottomPart.add (label); stringField = new JTextField (10); bottomPart.add (stringField); JButton button = new JButton ("Add"); button.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { handleAddButtonClick(); } } ); bottomPart.add (button); bottomPart.add (new JLabel (" ")); JButton shuffleButton = new JButton ("Shuffle"); shuffleButton.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { handleShuffleButtonClick(); } } ); bottomPart.add (shuffleButton); bottomPart.add (new JLabel (" ")); JButton nextButton = new JButton ("Next word"); nextButton.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { handleNextButtonClick(); } } ); bottomPart.add (nextButton); bottomPanel.add (bottomPart); bottomPart.add (new JLabel (" ")); JButton quitButton = new JButton ("Quit"); quitButton.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { System.exit(0); } } ); bottomPart.add (quitButton); bottomPanel.add (bottomPart); // The GUI is now built. cPane.add (bottomPanel, BorderLayout.SOUTH); // Get the list of puzzles. wordList = getWords(); wordListCount = 0; // Bring up the GUI. this.setVisible (true); } LinkedList getWords() { // First, the dictionary. dictionary = WordTool.getDictionary (); // This is just a test for now, with just two puzzle words. // What we should do is populate the list with "reasonable" // words that don't have too many subwords. For example, // "Conversation" is not a good word because it has too // many subwords. One approach may be to fill this from // the dictionary with all words that are between 5 and 8 // letters long. LinkedList list = new LinkedList(); list.add ("house"); list.add ("theory"); return list; } ///////////////////////////////////////////////////////////////////////////////// // // Handle input. // When the user clicks the add button, this method gets called. void handleAddButtonClick () { // Extract the string from the textfield where the user typed the strings. String inputStr = stringField.getText (); // Some sanity checks. if (inputStr == null) { writeOutput (); return; } inputStr = inputStr.trim (); if (inputStr.length() == 0) { writeOutput (); return; } // Check word against those already put up. int len = inputStr.length(); if (subWordInfo[len].subWords == null) { writeOutput (); return; } // If this is not a subword, ignore it. if (! subWordInfo[len].subWords.contains (inputStr) ) { writeOutput (); return; } // We've got a new subword, so add that to the list of "found" subwords. if (subWordInfo[len].foundSubWords == null) { subWordInfo[len].foundSubWords = new LinkedList(); } subWordInfo[len].foundSubWords.add (inputStr); // Put the output string in the text box. writeOutput (); // Clear the textfield. stringField.setText (""); } // Build the string that goes into the text box. void writeOutput () { // Sanity check. if (currentWord == null) { return; } // This is the string we will build. String s = ""; boolean finished = true; // Repeat for each possible subword size. for (int n=3; n<= currentWord.length(); n++) { int numWords = subWordInfo[n].subWords.size(); int numWordsFound = 0; if (subWordInfo[n].foundSubWords != null) { numWordsFound = subWordInfo[n].foundSubWords.size(); } if (numWordsFound != numWords) { finished = false; } s += "Found " + numWordsFound + " words out of " + numWords + " words of length " + n + ":\n"; if (subWordInfo[n].foundSubWords != null) { for (int i=0; i= wordList.size()) { // No more words left. topLabel.setText ("Game over. No more puzzles left"); return; } currentWord = wordList.get (wordListCount); wordListCount ++; topLabel.setText ("Building subwords ... wait..."); // Compute all sub-words. subWordInfo = findSubWords (currentWord); // Make a random perm and display it. setPermutedWordLabel (); topLabel.setText (" "); } boolean isDictionaryWord (String word) { for (int i=0; i