CS 161 Lab H - Shakespearean Insult Generator
Due Thurs Mar 28 at 11:59pm
Overview
If you've read any plays by William Shakespeare, you may have noticed the man's skill at writing creative insults. In this lab, you will harness that mastery. You will implement a Java program that generates random insults using Shakespearean language and vocabulary. Moreover, because nothing helps make text more insulting like fancy windows, you'll be giving your insult generator fancy pop-ups that allow you to really stick it to someone, without requiring them to look at the terminal.
Your program will welcome the user and then prompt them to open a text file that contains lists of Shakespearean words:
After reading and processing this file, your program will show a pop-up message that insults the user and then dares them to get insulted again: (Note that since the insult is random, the generated insult will likely be different).
If you user clicks "Yes", your program will show them another insult and again prompt them for more. Once the user clicks "No," your program will get in one more jibe, showing a final insult before exiting.
This lab will be completed in pairs. Be sure to review the pair programming guidelines. You also must work with a different partner than you have before!
Objectives
- To practice working with and parsing text files.
- To practice with ArrayLists and arrays.
- To practice reading java documentation to learn about new classes and methods.
- To use JOptionPanes to create a simple graphical interface for a program.
Necessary Files
You will need to download and extract the BlueJ project from the LabH.zip file. This project will supply you with the following classes:
-
Insulter
This class represents your insult generating program. You will need to make significant changes to this class. Specific changes are marked with a//TODO
comment, as well as detailed below. -
InsulterTester
A simple tester for the Insulter. You are welcome to modify this as needed to test your program!
The zip file also contains the list of insulting words, in a file called Shakespeare.txt
. Each line in the text file contains multiple words (but not an exact number) separated by commas and spaces. There are first a set of lines listing adjectives, then a blank line, then a set of lines listing nouns. You will need to parse each piece of this file separately.
- Note that any file that fits the format should be usable, in case you want to write your own insulting vocabulary!
Details
In this lab, you will not need to write any new classes! However, you will need to modify the Insulter
class in order to complete the program.
BEFORE YOU BEGIN: read over the provided code carefully. Make sure you understand the code that is already there, and you see what functionality needs to be added. Can you write in some pseudocode that will detail the functionality?
-
Your
Insulter
will likely need some instance variables, particularly to represent the list of words that are loaded from a file. Note that the file includes two lists of words: adjectives and nouns. As we don't know how long these lists will be, what might be an appropriate data structure for them?- Be sure to initialize your instance variables in the constructor!
-
In order to insult the users, you will need to load the vocabulary data by filling in the
loadData()
method. We have provided the code needed to load the file---you just need to read and parse the file so that the data is accessible!-
Reading from a text file is as easy as reading from the keyboard using the
Scanner
class. You will need to create a new Scanner object that takes the file object as a parameter. You can check that there is more of the file to read by using thehasNextLine()
method, and you can read each line of the file into a String by using thenextLine()
method, just like we did in class. Some pseudocode is below:make a new Scanner object using the Scanner(File) constructor while the scanner hasNextLine() make a local string that represents the line and put the scanner's nextLine() into it if the line is blank, change from the adjective to the noun section) otherwise process the words in the line if in the adjective section, put them in the adjectives list if in the noun section, put them in the noun list close the scanner when you're done!
-
Each line in the file contains a number of comma-separated words. You will need to break this line apart into its individual words in order to add them to the lists. You can go about this in one of two ways:
- Create a NEW Scanner object on the String that is that line, and use a similar (now nested) loop to scan through that String. You should set the delimiter to be a comma+space ", " and use
.hasNext()
and.next()
to see if there are ruther words, and if so read them into a String. -
An easier method is to just use the
.split()
method of the String class. This method takes a delimiter as an argument (again, you can use ", ") and returns an array of Strings that are separated by that delimiter--it "splits" the String! You will then need to go through this array of words and add each one to the lists.
- Create a NEW Scanner object on the String that is that line, and use a similar (now nested) loop to scan through that String. You should set the delimiter to be a comma+space ", " and use
-
Note that you will need to keep track of what "section" of the file you're in. You'll want to use a local variable for this (what type of variable should it be?). When you read a blank line (a line whose contents are the empty String
""
), you can change sections.- This isn't too complicated, but if you get stuck be sure to ask for help!
- Remember to close any Scanners (using the
.close()
method) when you're done! - You can test this method by printing out the lists of words after you load them; make sure to comment out this printing though before you turn in the lab!
-
Reading from a text file is as easy as reading from the keyboard using the
-
You will need to fill in the
buildInsult()
helper method so that it returns an insulting String. To do this, you will need to construct a String from multiple words (remember that you can combine Strings using String concatenation through the + sign).- The first word of each insult is "Thou". You can use this to initialize the String you are constructing.
- Next, you will need to pick two (2) different random words from the adjectives list. Remember that you can use the .size() method to figure out how big the list is! Add these words to your String.
- Finally, you will need to pick one (1) random word from the nouns list. This is basically the same as picking from the adjectives list.
- Once you've completed the String, remember to return it!
-
You will also need to fill in the
showInsult()
method. This method displays an insult to the user through a pop-up dialog. You will create this pop-up using the static showConfirmDialog() method of the JOptionPane class. This method can take a number of parameters to define its behavior: a simple example is below:JOptionPane.showConfirmDialog(null, "Hello world!", "An example", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
Try out the above code and study the documentation to figure out what parameters you will need to give this method.
- Note that as a static method, this method is called on the JOptionPane class rather than a JOptionPane object.
- You can use newline characters
"\n"
to add line breaks to your displayed message. - The
showConfirmDialog()
method returns an integer representing a status code: whether the user hit the "Yes" or "No" button. We don't know exactly what these integers are, but we know that they match the constantsJOptionPane.YES_OPTION
andJOptionPane.NO_OPTION
You will want to store this returned value in a local variable (i.e.,int response = ...
), and then return it so that the main loop (in the constructor) knows to keep insulting the user. - Note that this method will call the
buildInsult()
helper method in order to actually produce an insult to show! - You should be able to test this method by running the main method of the tester class, clicking on the "Yes" button each time to see more insults. Clicking on the "No" button should stop the program.
-
Finally, you should fill in the
showGoodbye()
method. This method should display a farewell insult.- For this method, you will want to use the
showMessageDialog()
method of theJOptionPane
class. You can find an example of this in the showGreeting() method.
- For this method, you will want to use the
- Be sure to test your code thoroughly before you submit it--make sure it's doing the right thing!
- Also be sure and add a few inline comments describing your code.
- And As always, be sure to fill out the lab partner evaluation survey on Moodle after you turn in your work!
Submitting
- Once you are sure that your program works, make sure that both your and your partner's names are in a class comment at the top of the file. Then submit your program to the submissions folder.
- Upload the your modified
Insulter.java
class to the LabH folder on the submission folder on hedwig. Make sure you upload your work to the correct folder! The lab is due at midnight on the day of the lab. - Again, please fill out the lab partner evaluation on Moodle.
Grading
This assignment will be graded on approximately the following criteria:
- Initialing the lists. [10%]
- Loading the vocabulary. [30%]
- Showing the insult. [25%]
- Saying goodbye. [20%]
- You have used good programming style and documentation [10%]
- You completed your lab partner evaluation [5%]