This is actually my version of a project I'm giving to my class of High School juniors. I'm not the greatest programmer and also a new teacher so I was hoping someone could check out this code and give me any suggestions or advice they see on it.
Please just keep in mind that it's written to be at a High School student level, not a college or professional level.
You have been commissioned to create a Mad Libs game. Mad Libs is a phrasal template word game which consists of prompting a player for a list of words to substitute for blanks in a story before reading aloud. The game will present the player with a welcome screen which allows them to select a story from a list of available stories; they will also be allowed the option for the computer to randomly choose a story for them if they would like.
After selecting a story, the player will be asked to enter a series of words to substitute for “blanks” (placeholders) in the story (i.e. “give me a noun”, “give me a verb”, “give me a color”, etc). The player’s responses will be saved and recalled later once all the words have been entered for that story. Finally, the story will be displayed, substituting the “blanks” with the responses the player entered in earlier.
In order to support the complexity of having multiple Mad Libs stories along with keeping track of their placeholders, we will be creating this using object oriented programming (OOP) in Java. You will implement the following Java classes:
MadLibsStory
- This will hold an entire Mad Libs story, along with a list of placeholders.MadLibsPlaceholder
- This will hold both the placeholder’s type (i.e. noun, adjective, verb, etc) and the word (the response from the player)MadLibsGame
- This will be the game’s “driver” class that will set up the list of stories, display them to the player, handle the user’s selection, and ultimately display the story.
A utility class called MadLibsStoryBuilder
, along with a Main
class, have been provided to you. There are a number of Mad Lib stories that have been saved in text files as well. The Main
class will use the MadLibsStoryBuilder
class to read the contents of the text files, create an array of MadLibsStory
objects, and then create a new instance of MadLibsGame
using this array. (Note, this has been provided to you and you will not have to create this part).
In order to implement this according to the description provided in the previous section, your game will need to support the following:
Display a welcome message.
Display a list of all the stories available to the player. a. Every story listed will need to display the title and the choice number (The number the player will need to enter to select that story) starting with number 1.
Ask the player to choose a story using the stories’ choice number.
Allow the player to select a random story by entering the number 0.
Once the player selects a story, it should begin by asking them for all the placeholder words.
Once the player finishes entering all the placeholder words, it needs to display the story using the responses the player entered in.
After displaying the story, it should go back to step 2.
Main
import java.io.File;
// Class supplied to students. Shouldn't be modified.
public class Main {
public static void main(String[] args) {
File directory = new File("stories/");
String[] directoryList = directory.list();
MadLibsStory[] stories = new MadLibsStory[directoryList.length];
for (int i = 0; i < stories.length; i++) {
stories[i] = MadLibsStoryBuilder.makeStoryFromFile("stories/" + directoryList[i]);
}
MadLibsGame ml = new MadLibsGame(stories);
ml.play();
}
}
MadLibsStoryBuilder
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
// Class supplied to students. Shouldn't be modified.
public class MadLibsStoryBuilder {
/**
* Precondition: The format of the file
* @param fileName
* @return
*/
public static MadLibsStory makeStoryFromFile(String fileName) {
StringBuilder sb = new StringBuilder();
String[] storyList;
ArrayList<MadLibsPlaceholder> placeholderList = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
while(line != null) {
sb.append(line).append('\n');
line = br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
String storyStr = new String(sb);
storyList = storyStr.split("\\[.*?\\]");
while(storyStr.contains("[")) {
int i = storyStr.indexOf("[");
int j = storyStr.indexOf("]");
String placeholderType = storyStr.substring(i + 1, j);
MadLibsPlaceholder placeholder = new MadLibsPlaceholder(placeholderType);
placeholderList.add(placeholder);
storyStr = storyStr.substring(j + 1);
}
String title = fileName.substring(fileName.indexOf("/") + 1, fileName.indexOf(".txt"));
MadLibsPlaceholder[] placeholderArray = new MadLibsPlaceholder[placeholderList.size()];
placeholderArray = placeholderList.toArray(placeholderArray);
return new MadLibsStory(title, storyList, placeholderArray);
}
}
MadLibsPlaceholder
public class MadLibsPlaceholder {
private String type;
private String word;
public MadLibsPlaceholder() {
type = "NOUN";
word = Constants.PLACE_HOLDER_PHRASE;
}
public MadLibsPlaceholder(String type) {
this.type = type;
word = Constants.PLACE_HOLDER_PHRASE;
}
public String getType() {
return type;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String toString() {
return String.format("%s (%s)", word, type);
//Same just without the formating
//return word + " (" + type + ")";
}
}
MadeLibsStory
// Change this file
public class MadLibsStory {
private final String title;
private final String[] story;
private final MadLibsPlaceholder[] placeholders;
private int placeholderIndex;
public MadLibsStory() {
title = "";
story = new String[0];
placeholders = new MadLibsPlaceholder[0];
}
public MadLibsStory(String title, String[] story, MadLibsPlaceholder[] placeholders) {
this.title = title;
this.story = story;
this.placeholders = placeholders;
}
public String getTitle() {
return title;
}
public MadLibsPlaceholder getNextPlaceholder()
{
// The current index is held in a variable, and is incremented each time.s
if (placeholderIndex >= placeholders.length) {
placeholderIndex = 0;
return null;
}
return placeholders[placeholderIndex++];
}
public String toString()
{
StringBuilder finishedStory = new StringBuilder(title + "\n\n");
// Since the story does not end with a placeholder, do not do last item in the loop
for (int i = 0; i < story.length - 1; i++) {
System.out.println(story[i] + "/");
finishedStory.append(story[i]);
finishedStory.append(placeholders[i].getWord());
}
// Append the last part of the story
finishedStory.append(story[story.length - 1]);
return finishedStory.toString();
}
}
MadLibsGame
import java.util.Scanner;
public class MadLibsGame {
private final MadLibsStory[] stories;
public MadLibsGame() {
this.stories = new MadLibsStory[0];
}
public MadLibsGame(MadLibsStory[] stories) {
this.stories = stories;
}
public MadLibsStory getRandomStory() {
// Generate a random index between 0 and the story's length. stories.length is exclusive. Then return it
int index = (int) (Math.random() * stories.length);
return stories[index];
}
// Generate the listing string, with index being 1 over i (so it starts at 1 not 0.)
public void listStories() {
for (int i = 0; i < stories.length; i++)
System.out.printf(("%d. %s%n"), (i+1), stories[i].getTitle());
}
public void play() {
String selection;
System.out.println("Welcome to Mad Libs, the most popular phrasal word template game.\n");
Scanner scan = new Scanner(System.in);
do {
int index = -1;
// Print menu and take user input
printMenu();
selection = scan.nextLine();
// Allow user to exit
if (selection.equalsIgnoreCase("e")) {
break;
}
// Handle input
try {
index = Integer.parseInt(selection);
} catch (NumberFormatException fe) {
System.out.println("Not a valid input, a number was expected. Please try again");
} finally {
if (boundsCheck(index)) {
// Print random story or user defined story
MadLibsStory story = (index == 0) ? getRandomStory() : getStoryAtIndex(index-1) ;
assert story != null;
fillStory(story, scan);
System.out.println(story);
} else {
System.out.println("Please choose a number 1-" + stories.length);
}
}
} while (true);
}
// Helper functionss
private void printMenu(){
System.out.println("******************************\n");
System.out.println("SELECT A STORY (to pick a random story enter '0', to exit enter 'E')\n");
listStories();
System.out.print("\nSelection: ");
}
private boolean boundsCheck(int i){
return i >= 0 && i <= stories.length;
}
private MadLibsStory getStoryAtIndex(int index) {
// If index is less than 0 or greater/equal to stories.length, return null
if (index < 0 || index >= stories.length) return null;
return stories[index];
}
private void fillStory(MadLibsStory story, Scanner scan){
MadLibsPlaceholder placeholder = story.getNextPlaceholder();
// While there is a next placeholder, keep replacing them.
while (placeholder != null) {
System.out.println("Give me a " + placeholder.getType());
String newWord = scan.nextLine();
placeholder.setWord(newWord);
placeholder = story.getNextPlaceholder();
}
}
}
Constants - I actually thought I was going to use this class more than I did. Probably don't need it tbh.
public class Constants {
public static final String PLACE_HOLDER_PHRASE = "[BLANK]";
}