Program 4: Morph

Write a program to change one word into another.  At each step only a single letter can be changed at a time, and each word must be a word found in the dictionary.

Use dictionary.txt (taken on a Mac from /usr/share/dict/words) of 235,886 words.  Running the program should look like the following, where user input is shown in bold (though your program when run will not display that in bold):

Program #4: Morph Words    

Author: Dale Reed    

Lab: Tues 8am     

System:  Mac OS X, Qt Creator IDE 

 

Total number of words: 235886 

Word lengths where there are more than 2000 words:

Length  How Many

------  --------

    4      5272

    5     10230

    6     17706

    7     23869

    8     29989

    9     32403

   10     30878

   11     26013

   12     20462

   13     14939

   14      9765

   15      5925

   16      3377

What length words do you want to use? 4

Number of words read was 5272

Enter starting and ending words, or 'r' for either for a random word: zong zichs

'zong' is not in the dictionary. Please retry.

Enter starting and ending words, or 'r' for either for a random word: song zichs

'zichs' is not of length 4. Please retry.

Enter starting and ending words, or 'r' for either for a random word: song r

Morphing from song to whig.

On each move enter a word of the same length that is at   

most 1 character different and is also in the dictionary, 

or type in 'exit' to exit the interactive portion of the program.

 

1. Previous word is 'song'.  Next word: soig

Your suggestion of soig is not in the dictionary.  Please retry.

1. Previous word is 'song'.  Next word: sing

2. Previous word is 'sing'.  Next word: wing

3. Previous word is 'wing'.  Next word: wink

4. Previous word is 'wink'.  Next word: wook

New word must be exactly 1 character different.  Please retry.

4. Previous word is 'wink'.  Next word: wine

5. Previous word is 'wine'.  Next word: exit

You chose 'exit' to exit the interactive part of the program.

Now Computer will display a solution path, if there is one.

Solution is: 

   0. song

  16. tong

 122. toug

 671. thug

2270. thig

3887. whig

See here for the same program that includes debugging / trace information.  I suggest you develop your program one stage at a time, breaking down section using functions.  Here are some ideas on data declarations and parameter passing that may help you if you choose to follow a similar approach to the one I chose.

Hints

Dictionary

You will read the dictionary file twice.  The first time you will accumulate counts of how many words of each length there are, storing this in an array.  You know that the longest possible word is around 30 characters, so make your counting array of integers that size.  As you read each word, check its size and add one to the corresponding array location in your word length counting array.

You will then close the file.  Then prompt the user for what size words she wants to deal with, dynamically creating an array to handle these, since in the previous step you already figured out how many there are.  You will need to dynamically allocate space for this array.

This array should be declared in main as:  char **theWords   and then passed as a parameter to functions that need it.  When initially creating it you will pass it simply using its name (theWords) and when declaring it on the (for example) readInWordsFromFile(..) function parameter list, you will need to declare it as    char ** &theWords  Because it is a char ** that will change (and point to a newly allocated array), and you want that change reflected back to the calling part of the program.  Note that dynamic memory allocation for this must occur in two stages: 

Random Number Generator

Debugging

I highly recommend that you develop your program one step at a time, printing out debugging information as you go.  For instance see the version of the output shown near the top of this page, that includes extensive debugging information.

Prompting for start and end Words

This code should be in a function.  startWord and endWord should be declared in main as arrays of char of some fixed size (probably 81), and then passed to functions where they are used.  You should use some kind of loop to read in those values.  Note that the user can enter two words, or enter two single character 'r' which represent random selection of each word.  Read in both words and then handle the cases.  If a word is 'r' then choose a random word, as illustrated above.  Otherwise validate each word to make sure it is in the dictionary and is the proper length.  Since this code is in a loop, if there is some problem, simply use the continue statement to go back up to the top of the loop to retry.  Then use the break statement to break out of the loop once both words are verified.

Handling Interactive User Input

You will need a loop to handle user input.  It should keep going until the end word is found, or the user types in 'exit' to quit the interactive part of the program.  For each user input word you should:

Computer Generates Solution Path

This is the challenging part of the program.  You will essentially create a tree of all words reachable form the starting word.  The tree keeps growing as you expand each word already in the tree, keeping track of its "children."  Actually using a tree structure for this is beyond what we can comfortably do so far, so instead we will use an array.  Start by putting the starting word on this array.  Find all words that are at most 1 letter away from this starting word.  Store each of these words successively in this array, adding them to the end.  Then repeat, moving to the next line to expand that word, and so on.

This process will end once there are no more words to be expanded, or when the ending word is found.  Once the ending word is found we need a way to trace its ancestry back to the starting word.  This means that for each word we need to also store the index number of its parent, so rather than an array of words, we will instead be dealing with an array of struct, where each struct member has a word as well as the index of its parent.  The resulting array will at most be the size of the original array of words.  Similar to when char ** theWords was declared, we have to declare this in steps.  

Points Breakdown:

Turn in Instructions:

Remember that the name of your project should be your netid.  Once you are done with your program, rename main.cpp to be netid.cpp, where netid is your netid.  Zip up only your netid.cpp file and turn it in to Blackboard into the Program 4 assignment.