diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..19d9aa74 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "java.project.referencedLibraries": [ + "lib/**/*.jar", + "guava-31.1-jre.jar" + ] +} \ No newline at end of file diff --git a/AnemoneRiddle.txt b/AnemoneRiddle.txt new file mode 100644 index 00000000..fb6ed12e --- /dev/null +++ b/AnemoneRiddle.txt @@ -0,0 +1,5 @@ +In the ocean's sway, I gently hide, +With tendrils waving, a colorful guide. +But beware my touch, for it may chide, +A sea creature's secret, nestled inside. +What am I? \ No newline at end of file diff --git a/Aquatic.java b/Aquatic.java new file mode 100644 index 00000000..7323ff34 --- /dev/null +++ b/Aquatic.java @@ -0,0 +1,70 @@ +import java.util.Scanner; + +/** + * The aquatic class that extends the biome and contains the dolphin and sea anemone + */ +public class Aquatic extends Biome { + private FloraFauna dolphin; + private FloraFauna sea_anemone; + private String imagePath; + + /** + * Constructor for aquatic class with information about FloraFauna + */ + public Aquatic() { + super("cs120_lab_image.png"); + this.dolphin = new FloraFauna("dolphin", 4, "Dorothy"); + this.sea_anemone = new FloraFauna("sea anemone", 5, "Flounder"); + this.imagePath = ("ocean.png"); + } + + /** + * Getter for dolphin + * @return the dolphin object + */ + public FloraFauna getAnimal() { + return this.dolphin; + } + + /** + * Getter for anemone + * @return the anemone object + */ + public FloraFauna getPlant() { + return this.sea_anemone; + } + + public String getImagePath() { + return imagePath; + } + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return dolphin or null. + * @param Scanner s from the game loop class + * @return dolphin object or null + */ + public FloraFauna animalRiddle(Scanner s) { + if (riddle(s, "dolphin", "kraken", "DolphinRiddle.txt")) { + return this.dolphin; + } else { + return null; + } + } + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return anemone or null. + * @param Scanner s from the game loop class + * @return sea anemone object or null + */ + public FloraFauna plantRiddle(Scanner s) { + if (riddle(s, "sea anemone", "kraken", "AnemoneRiddle.txt")) { + return this.sea_anemone; + } else { + return null; + } + } + + public String toString() { + return "aquatic"; + } +} \ No newline at end of file diff --git a/Biome.java b/Biome.java new file mode 100644 index 00000000..2cdada27 --- /dev/null +++ b/Biome.java @@ -0,0 +1,94 @@ +import java.util.Scanner; + + +/** + * Biome class which has the file reader attribute. + */ +public class Biome { + private FileClass FileReader; + private FloraFauna animal; + private FloraFauna plant; + private String imagePath; + + + /** + * Constructor for biome class + */ + public Biome(String imagePath) { + this.FileReader = new FileClass(); + this.animal = new FloraFauna(null, null, null); + this.plant = new FloraFauna(null, null, null); + this.imagePath = imagePath; + + } + + /** + * Getter for plant + * @return the plant object + */ + public FloraFauna getAnimal() { + return this.animal; + } + + /** + * Getter for plant + * @return the plant object + */ + public FloraFauna getPlant() { + return this.plant; + } + + + public FloraFauna animalRiddle(Scanner s) { + return this.animal; + } + + + public FloraFauna plantRiddle(Scanner s) { + return this.plant; + } + + public String getImagePath() { + return imagePath; + } + + /** + * Allows riddles for child classes to be read and answered. + * @param Scanner s that reads user response + * @param String FloraFauna that is riddle subject + * @param String Monster that is attacking user + * @param String filename that is associated with riddle subject + * @return boolean (whether riddle was answered correctly) + */ + public boolean riddle(Scanner s, String FloraFauna, String Monster, String filename) { + System.out.println(""); + this.FileReader.fileReader(filename); + String userResponse = ""; + int incorrectCounter = 0; + while (true) { + System.out.println("\nEnter your answer:"); + userResponse = s.nextLine().toLowerCase(); + if (!userResponse.equals(FloraFauna)) { + System.out.println("\nYou've answered incorrectly!"); + incorrectCounter += 1; + if (incorrectCounter < 3) { + System.out.println("The " + Monster + " is " + (3 - incorrectCounter) + " feet away."); + } + if (incorrectCounter == 3) { + System.out.println("Your inventory has been eaten!"); + return false; + } + } + if (userResponse.equals(FloraFauna)) { + System.out.println("\nYou've answered correctly! The " + FloraFauna + " has been added to your inventory."); + return true; + } + } + } + + public String toString() { + return "This is the default biome toString"; + } +} + + diff --git a/BiomeMap.java b/BiomeMap.java new file mode 100644 index 00000000..9833535b --- /dev/null +++ b/BiomeMap.java @@ -0,0 +1,44 @@ + +import com.google.common.graph.ImmutableValueGraph; +import com.google.common.graph.ValueGraphBuilder; + +/** + * Class for a map of the biomes + */ +public class BiomeMap { + private ImmutableValueGraph Graph; + + /** + * Creates a graph that maps all the biomes and their named connections + */ + public BiomeMap() { + this.Graph = ValueGraphBuilder.directed() + .immutable() + .putEdgeValue("rainforest", "aquatic", "east") + .putEdgeValue("aquatic", "rainforest", "west") + .putEdgeValue("rainforest", "desert", "south") + .putEdgeValue("desert", "rainforest", "north") + .putEdgeValue("lab", "rainforest", "northwest") + .putEdgeValue("rainforest", "lab", "southeast") + .putEdgeValue("aquatic", "tundra", "south") + .putEdgeValue("tundra", "aquatic", "north") + .putEdgeValue("lab","aquatic", "northeast") + .putEdgeValue("aquatic", "lab", "southwest") + .putEdgeValue("desert","tundra", "east") + .putEdgeValue("tundra", "desert", "west") + .putEdgeValue("lab", "desert", "southwest") + .putEdgeValue("desert", "lab", "northeast") + .putEdgeValue("lab", "tundra", "southeast") + .putEdgeValue("tundra", "lab", "northwest") + .build(); + } + + /** + * Getter for the biome map/graph + * @return the biome graph + */ + public ImmutableValueGraph getGraph() { + return this.Graph; + } + +} \ No newline at end of file diff --git a/CacaoRiddle.txt b/CacaoRiddle.txt new file mode 100644 index 00000000..194c0818 --- /dev/null +++ b/CacaoRiddle.txt @@ -0,0 +1,6 @@ +***RIDDLE*** +I am a tree with fruit that's sweet, +My seeds are used for a tasty treat. +I can be made into a bar or a drink, +In many desserts, I'm the missing link. +What am I? \ No newline at end of file diff --git a/CactusRiddle.txt b/CactusRiddle.txt new file mode 100644 index 00000000..a470c073 --- /dev/null +++ b/CactusRiddle.txt @@ -0,0 +1,6 @@ +***RIDDLE*** +I'm a plant that's tough and spiny, +In the desert, I'm prickly and tiny. +My shape is unique, you cannot mistake, +I can survive in the heat, with very little to take. +What am I? \ No newline at end of file diff --git a/CamelRiddle.txt b/CamelRiddle.txt new file mode 100644 index 00000000..7d7131f4 --- /dev/null +++ b/CamelRiddle.txt @@ -0,0 +1,8 @@ +The sun is low over the horizon and you spot a sea of orange sand in the distance. The wind is harsh and creates swirling sand spires. Dr. Athene hands you a bottle with a strange message... + +***RIDDLE*** +I am an animal with a hump, +In the desert, I can easily jump. +I store water in my body and can go days without, +My feet are padded and never wear out. +What am I? \ No newline at end of file diff --git a/Desert.java b/Desert.java new file mode 100644 index 00000000..a3375167 --- /dev/null +++ b/Desert.java @@ -0,0 +1,75 @@ +import java.util.Scanner; + +/** + * The desert class that extends the biome and contains the camel and cactus + */ +public class Desert extends Biome { + private FloraFauna camel; + private FloraFauna cactus; + private String imagePath; + + + /** + * Constructor for desert class with information about FloraFauna + */ + public Desert() { + super("cs120_lab_image.png"); + this.camel = new FloraFauna("camel", 2, "Tom"); + this.cactus = new FloraFauna("cactus", 3, "Janice"); + this.imagePath = "desert.png"; + + } + + /** + * Getter for camel + * @return the camel object + */ + public FloraFauna getAnimal() { + return this.camel; + } + + /** + * Getter for cactus + * @return the cactus object + */ + public FloraFauna getPlant() { + return this.cactus; + } + + public String getImagePath() { + return imagePath; + } + + + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return camel or null. + * @param Scanner s from the game loop class + * @return camel object or null + */ + public FloraFauna animalRiddle(Scanner s) { + if (riddle(s, "camel", "sharknado", "CamelRiddle.txt")) { + return this.camel; + } else { + return null; + } + } + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return cactus or null. + * @param Scanner s from the game loop class + * @return cactus object or null + */ + public FloraFauna plantRiddle(Scanner s) { + if (riddle(s, "cactus", "sharknado", "CactusRiddle.txt")) { + return this.cactus; + } else { + return null; + } + } + + public String toString() { + return "desert"; + } + +} \ No newline at end of file diff --git a/DisplayImage.java b/DisplayImage.java new file mode 100644 index 00000000..e5c13bc2 --- /dev/null +++ b/DisplayImage.java @@ -0,0 +1,40 @@ +import javax.swing.*; +import java.awt.*; +/* + * class to implement graphics for lab and biomes + */ +public class DisplayImage extends JFrame { + + private JLabel label; + + public DisplayImage() { + setTitle("Image Display"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(400, 400); + + label = new JLabel(); + + getContentPane().add(label, BorderLayout.CENTER); + + /* + * sets initial image for start of game (lab image) + */ + ImageIcon initialIcon = new ImageIcon("cs120_lab_image.png"); + label.setIcon(initialIcon); + } + /* + * method to update image as game progresses through biomes + * @param imagePath + */ + public void updateImage(String imagePath) { + ImageIcon icon = new ImageIcon(imagePath); + label.setIcon(icon); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + DisplayImage imageDisplay = new DisplayImage(); + imageDisplay.setVisible(true); + }); + } +} diff --git a/DolphinRiddle.txt b/DolphinRiddle.txt new file mode 100644 index 00000000..4135b060 --- /dev/null +++ b/DolphinRiddle.txt @@ -0,0 +1,6 @@ +***RIDDLE*** +Beneath the waves, I gracefully roam, +A mammal in waters, I call my home. +With echolocation, I navigate, +In ocean's vastness, I dominate. +What am I? \ No newline at end of file diff --git a/FernRiddle.txt b/FernRiddle.txt new file mode 100644 index 00000000..03d5f75b --- /dev/null +++ b/FernRiddle.txt @@ -0,0 +1,6 @@ +***RIDDLE*** +In shadows deep, I unfurl my fronts, +A relic of ancient, verdant bonds. +Through spores I spread, my lineage profound, +A symbol of resilience, forever unbound. +What am I? \ No newline at end of file diff --git a/FileClass.java b/FileClass.java new file mode 100644 index 00000000..6395618f --- /dev/null +++ b/FileClass.java @@ -0,0 +1,127 @@ +import java.io.File; // Import the File class +import java.io.FileNotFoundException; // Import this class to handle errors +import java.io.FileWriter; //Might use these later for leaderboard +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Scanner; // Import the Scanner class to read text files + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import java.io.BufferedWriter; // Import this class to write to a file + +public class FileClass { + private Multimap scoreMap; + private ArrayList scoreList; + private LinkedHashMap sortedScoreMap; + + public FileClass() { + this.scoreMap = ArrayListMultimap.create(); + this.scoreList = new ArrayList<>(); + this.sortedScoreMap = new LinkedHashMap<>(); + } + + public void fileReader(String fileName) { + try { + File myFile = new File(fileName); + Scanner fileReader = new Scanner(myFile); // <- Same kind of object we used to read from the command line! But instead of System.in, we're reading from the file + // Loop until we run out of lines + if (fileName.equals("Scoreboard.txt")) { + int nLine = 1; + while (nLine <= 5) { + String data = fileReader.nextLine(); + System.out.println(data); + nLine ++; + } + } else { + while (fileReader.hasNextLine()) { + String data = fileReader.nextLine(); + System.out.println(data); + } + } + + // Tidy up + fileReader.close(); + + } catch (FileNotFoundException e) { // Sometimes things go wrong; we'll handle that here + System.out.println("An error occurred."); + e.printStackTrace(); + } + } + + public void sortedFileWriter() { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter("Scoreboard.txt", false)); + for (Map.Entry entry : sortedScoreMap.entrySet()) { + writer.write(entry.getKey() + ":" + entry.getValue()); + writer.newLine(); + } + writer.close(); + } catch (IOException e) { + System.out.println(e); // print error message + } + } + + + public void fileWriter(String message) { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter("Scoreboard.txt", true)); + writer.write(message); + writer.close(); + } catch (IOException e) { + System.out.println(e); // print error message + } + } + + + public void sortedFile() { + try { + Path nameFile = Path.of("Scoreboard.txt"); + String stringFile = Files.readString(nameFile); + String[] splitLine = stringFile.split("\n"); + for (int i=0; i entry : this.scoreMap.entries()) { + this.scoreList.add(entry.getValue()); + } + Collections.sort(this.scoreList, Collections.reverseOrder()); + for (int num : this.scoreList) { + for (Map.Entry entry : this.scoreMap.entries()) { + if (entry.getValue().equals(num) && !this.sortedScoreMap.containsKey(entry.getKey())) { + this.sortedScoreMap.put(entry.getKey(), num); + } + } + } + sortedFileWriter(); + } catch (IOException e) { + System.out.println(e); // print error message + } +} + + + + public static void main(String[] args) { + FileClass file = new FileClass(); + file.sortedFile(); + } +} + + + + +//Sources +// https://stackoverflow.com/questions/15649567/sorting-a-text-file-in-java +// https://stackoverflow.com/questions/10514473/how-to-convert-a-string-to-a-hashmap +// https://www.digitalocean.com/community/tutorials/sort-hashmap-by-value-java ---) taught me how to sort hashmap +// https://www.geeksforgeeks.org/write-hashmap-to-a-text-file-in-java/ --) taught me how to write to file +// https://www.geeksforgeeks.org/how-to-sort-an-arraylist-in-descending-order-in-java/ ---) taught reverse order +// https://www.coderanch.com/t/408361/java/print-lines-file --) prints first 5 lines \ No newline at end of file diff --git a/FloraFauna.java b/FloraFauna.java new file mode 100644 index 00000000..649d11a1 --- /dev/null +++ b/FloraFauna.java @@ -0,0 +1,23 @@ +public class FloraFauna { + protected String species = "Default species"; + protected Integer age = 0; + protected String name = "Default name"; + + public FloraFauna(String species, Integer age, String name) { + if (species != null) { this.species = species;} + if (age != null) { this.age = age;} + if (name != null) { this.name = name;} + } + + public String getSpecies() { + return this.species; + } + + public String toString() { + return "* This creature is a " + this.species + " of age " + this.age + " named "+ this.name +"."; + } + + public String speak() { + return "Heyyyyyy, help me out!"; + } +} \ No newline at end of file diff --git a/FoxRiddle.txt b/FoxRiddle.txt new file mode 100644 index 00000000..9107a867 --- /dev/null +++ b/FoxRiddle.txt @@ -0,0 +1,6 @@ +***RIDDLE*** +In Arctic realms where snowflakes fall, +I'm the elusive one, agile and small. +My fur, a shield from the biting frost, +In frozen lands, my skills aren't lost. +What am I? \ No newline at end of file diff --git a/FrogRiddle.txt b/FrogRiddle.txt new file mode 100644 index 00000000..a76818d9 --- /dev/null +++ b/FrogRiddle.txt @@ -0,0 +1,8 @@ +You are surrounded by lush green foliage. You cannot see the sky above the forest canopy, but you feel a light sprinkle of rain. Birds are heard in the distance and you notice Dr. Athene. She drops a slip of paper that you begin to read... + +***RIDDLE*** +I am brightly colored, but don't be deceived, +I'm not here for your eyes to be pleased. +My skin is toxic, so beware, +Touch me and you'll be in despair. +What am I? \ No newline at end of file diff --git a/GameLoop.java b/GameLoop.java new file mode 100644 index 00000000..d17639e0 --- /dev/null +++ b/GameLoop.java @@ -0,0 +1,141 @@ +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Scanner; + +import com.google.common.graph.EndpointPair; +import com.google.common.graph.ImmutableValueGraph; + +/** + * Runs the commands of the game in order until user wins/loses + */ +public class GameLoop { //Maybe have a class w/ help commands? + + /** + * Main method that runs the whole game loop + */ + public static void main(String[] args) { + + //Attributes (organize somehow) + BiomeMap biomeMap = new BiomeMap(); + FileClass fileClass = new FileClass(); + ImmutableValueGraph Graph = biomeMap.getGraph(); + String userLocation = "lab"; + ArrayList targetArrayList = new ArrayList<>(); + ArrayList sourceArrayList = new ArrayList<>(); //Consider consolidating these arraylists into hashtable (dictionary) + ArrayList edgeArrayList = new ArrayList<>(); + Rainforest rainforest = new Rainforest(); + Desert desert = new Desert(); + Aquatic aquatic = new Aquatic(); + Tundra tundra = new Tundra(); + Lab lab = new Lab(); + ArrayList inventory = lab.getInventory(); + + ArrayList biomes = new ArrayList<>(); + biomes.add(rainforest); + biomes.add(desert); + biomes.add(tundra); + biomes.add(aquatic); + + // This is a "flag" to let us know when the loop should end + boolean stillPlaying = true; + + // We'll use this to get input from the user. + Scanner userInput = new Scanner(System.in); + + // Storage for user's responses + String userResponse = ""; + + // This could be replaced with a more interesting opening + fileClass.fileReader("Introduction.txt"); + DisplayImage imageDisplay = new DisplayImage(); + imageDisplay.setVisible(true); + System.out.println("\nEnter your username:"); + String username = userInput.nextLine().toLowerCase(); //Check for invalid and store in file possibly + while (username.length() > 10 || username.length() < 1) { + System.out.println("Your username is too long or short. Type another."); + username = userInput.nextLine().toLowerCase(); + } + + // The do...while structure means we execute the body of the loop once before checking the stopping condition + do { + + //Checks user location and shows paths available (Is there an easier way to do this?) + System.out.println("\nThe following paths you may take are listed below:"); + Iterator> GraphIterator = Graph.incidentEdges(userLocation).iterator(); + while (GraphIterator.hasNext()) { + EndpointPair edge = GraphIterator.next(); + String targetNode = edge.target(); + if (targetNode != userLocation) { + targetArrayList.add(targetNode); + } + String sourceNode = edge.source(); + if (sourceNode == userLocation) { + sourceArrayList.add(sourceNode); + } + } + for (int i=0; i < sourceArrayList.size(); i++) { + String source = sourceArrayList.get(i); + String target = targetArrayList.get(i); + edgeArrayList.add(Graph.edgeValueOrDefault(source, target, "None")); + System.out.println("* " + Graph.edgeValueOrDefault(source, target, "None")); + } + + //Choose a path + System.out.println("\nChoose a path:"); + userResponse = userInput.nextLine().toLowerCase(); + while (!edgeArrayList.contains(userResponse)) { + System.out.println("Invalid answer. Type new response."); //Class for help commands/inventory check? + userResponse = userInput.nextLine().toLowerCase(); + } + for (int i=0; i < sourceArrayList.size(); i++) { + String source = sourceArrayList.get(i); + String target = targetArrayList.get(i); + String nEdges = Graph.edgeValueOrDefault(source, target, "None"); + if (nEdges.equals(userResponse)) { + System.out.println("\nWelcome to the " + target + " biome!"); + userLocation = target; + targetArrayList.clear(); + sourceArrayList.clear(); + edgeArrayList.clear(); + } + } + + //Series of if statements to check user location, ask riddles, and update inventory + for (int i=0; i < biomes.size(); i++) { + String stringBiome = biomes.get(i).toString(); + if (userLocation.equals(stringBiome)) { + Biome classBiome = biomes.get(i); + String imagePath = classBiome.getImagePath(); + imageDisplay.updateImage(imagePath); + FloraFauna animal = classBiome.getAnimal(); + if (!inventory.contains(animal)) { + animal = classBiome.animalRiddle(userInput); + if (animal == null) { + userLocation = lab.resetInventory(); + } else { + inventory.add(animal); + FloraFauna plant = classBiome.plantRiddle(userInput); + if (plant == null) { + userLocation = lab.resetInventory(); + } else { + inventory.add(plant); + } + } + } else { + System.out.println("\nNo more creatures to find in the " + stringBiome + " biome!"); + } + } + } + + // Allows user to check and review inventory in the lab + if (userLocation.equals("lab")) { + lab.checkInventory(userInput); + stillPlaying = lab.submitInventory(userInput, username, fileClass, stillPlaying); + } + + } while (stillPlaying); + + // Tidy up + userInput.close(); + } +} \ No newline at end of file diff --git a/Introduction.txt b/Introduction.txt new file mode 100644 index 00000000..abca4251 --- /dev/null +++ b/Introduction.txt @@ -0,0 +1,11 @@ +****************** +BIOME BLAST: DR. FERNSBEE AND THE BIODIVERSITY QUEST +****************** + +You are a scientist for the world famous biologist Dr. Flora Fernsbee. She has tasked you with collecting 8 endangered species from 4 different biomes across the globe in efforts to save the planet’s biodiversity. Dr. Fernsbee has assigned her dear friend and trusted colleague (who just so happens to be an owl) Dr. Athene Strix. She is unable to collect the animals herself, however, she will gladly provide riddles to help you solve which species to save. + +BUT WAIT! It won’t be so simple. Her nemesis Dr. Fossileus Fueleus has released four different monsters in each biome in order to kill off these animals so he can build his Exxon plant. You will have a limited number of guesses for each riddle before the monsters will eat your inventory! The more times your inventory is eaten, the lower your final score. + +***************** + +You begin in a teleporting lab with 4 doors in opposite corners. Each door leads to a biome. It is up to you where you go next…good luck. diff --git a/Lab.java b/Lab.java new file mode 100644 index 00000000..0a7a8a2f --- /dev/null +++ b/Lab.java @@ -0,0 +1,75 @@ +import java.util.ArrayList; +import java.util.Scanner; +/* + * stores inventory for plants and animals + */ +public class Lab { + private ArrayList inventory; + private int nClearInventory; +/* + * constructor with new ArrayList for inventory + */ + public Lab() { + this.inventory = new ArrayList<>(); + this.nClearInventory = 0; + } +/* + * getter for inventory + * @return inventory + */ + public ArrayList getInventory() { + return this.inventory; + } +/* + * clears and resets inventory + */ + public String resetInventory() { + inventory.clear(); + nClearInventory += 1; + return "lab"; + } + + public void checkInventory(Scanner userInput) { + System.out.println("\nYou are back to the lab. Would you like to check your inventory?"); + String userResponse = userInput.nextLine().toLowerCase(); + while (!userResponse.equals("yes") && !userResponse.equals("no")) { + System.out.println("\nI don't recognize " + "'" + userResponse +"'"); + userResponse = userInput.nextLine().toLowerCase(); + } + if (userResponse.equals("yes")) { + System.out.println("\n=============="); + System.out.println("YOUR INVENTORY"); + System.out.println("=============="); + if (inventory.isEmpty()) { + System.out.println("Your inventory is empty."); + } else { + for (int i = 0; i < inventory.size(); i++) { + System.out.println(inventory.get(i)); + } + } + } else { + System.out.println("\nThe game continues!"); + } + } + + public boolean submitInventory(Scanner userInput, String username, FileClass fileClass, boolean stillPlaying) { + System.out.println("\nWould you like to submit your inventory for review? Warning: the game will end."); + String userResponse = userInput.nextLine().toLowerCase(); + while (!userResponse.equals("yes") && !userResponse.equals("no")) { + System.out.println("\nI don't recognize " + "'" + userResponse +"'"); + userResponse = userInput.nextLine().toLowerCase(); + } + if (userResponse.equals("yes")) { + int score = inventory.size() - nClearInventory; + System.out.println("\nYou found " + inventory.size()+ " animals. Your inventory was eaten " + nClearInventory + " time(s). Your final score is " + score + "."); + fileClass.fileWriter(username + ":" + score); + fileClass.sortedFile(); + System.out.println("\n***LEADERBOARD***"); + fileClass.fileReader("Scoreboard.txt"); + return stillPlaying = false; + } else { + System.out.println("\nThe game continues!"); + return stillPlaying = true; + } + } +} diff --git a/README.md b/README.md index c1a995eb..d4351782 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,38 @@ # CSC120-FinalProject ## Deliverables: - - Your final codebase - - Your revised annotated architecture diagram - - Design justification (including a brief discussion of at least one alternative you considered) - - A map of your game's layout (if applicable) - - `cheatsheet.md` + - Your final codebase ---) check rubric and add comments + - Your revised annotated architecture diagram ---) do this together + - Design justification (including a brief discussion of at least one alternative you considered) ---) do this + - A map of your game's layout (if applicable) ---) Do this together + - `cheatsheet.md` ---) do this together - Completed `rubric.md` ## Additional Reflection Questions - What was your **overall approach** to tackling this project? + + It started with a general idea for the game involving user-navigated biomes with added challenge of quizzing the user on biome facts. We began by creating the biome class and the subclasses for each individual biome, then building the game loop with guava to navigate between biomes, adding in the riddles for each species. We then built the lab to store the inventory, finally adding in graphics for the lab and the biome as the user travels through the game. + - What **new thing(s)** did you learn / figure out in completing this project? + +Adding graphics and using guava were both new challenges when completing this project. + - Is there anything that you wish you had **implemented differently**? + + I think there possibly could have been fewer classes to work with, however, having separate classes for our different elements made it easier to keep track of work and separate the different aspects of the game. + - If you had **unlimited time**, what additional features would you implement? + + I think it would be cool to have more graphics and/or more interactive graphics. With more time, we could have added graphics for the found animals/plants, or even the monsters as they approached. + - What was the most helpful **piece of feedback** you received while working on your project? Who gave it to you? + +I think the most helpful feedback I received was from Mikayle, whose project inspired the added level in our game beyond the riddles. We needed a more "locked" aspect of the game beyond not being able to get to certain biomes from others, so it was helpful to see their game and add the integer "quiz" portion of the game. + - If you could go back in time and give your past self some **advice** about this project, what hints would you give? + + I think I would advise my past self that our ideas for the project can evolve as we work. I think we went in with a solid plan, but did not originally go as planned, so we had to change how the biomes and lab were built. + - _If you worked with a team:_ please comment on how your **team dynamics** influenced your experience working on this project. + + I think our team worked well together. We both brought a lot of really good ideas to the project and did well to collaborate and let ourselves be more creative with the concepts. We worked both independently and together, and were able to get things done in a timely manner. diff --git a/Rainforest.java b/Rainforest.java new file mode 100644 index 00000000..4569c0c6 --- /dev/null +++ b/Rainforest.java @@ -0,0 +1,71 @@ +import java.util.Scanner; + +/** + * The rainforest class that extends the biome and contains the camel and cactus + */ +public class Rainforest extends Biome { + private FloraFauna poison_dart_frog; + private FloraFauna cacao; + private String imagePath; + + /** + * Constructor for rainforest class with information about FloraFauna + */ + public Rainforest() { + super("cs120_lab_image.png"); + this.poison_dart_frog = new FloraFauna("poison dart frog", 3, "Theo"); + this.cacao = new FloraFauna("cacao", 6, "Barbara"); + this.imagePath = "rainforest.png"; + } + + /** + * Getter for frog + * @return the frog object + */ + public FloraFauna getAnimal() { + return this.poison_dart_frog; + } + + /** + * Getter for cacao + * @return the cacao object + */ + public FloraFauna getPlant() { + return this.cacao; + } + + public String getImagePath() { + return imagePath; + } + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return poison dart frog or null. + * @param Scanner s from the game loop class + * @return poison dart frog object or null + */ + public FloraFauna animalRiddle(Scanner s) { + if (riddle(s, "poison dart frog", "croczilla", "FrogRiddle.txt")) { + return this.poison_dart_frog; + } else { + return null; + } + } + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return cacao or null. + * @param Scanner s from the game loop class + * @return cacao object or null + */ + public FloraFauna plantRiddle(Scanner s) { + if (riddle(s, "cacao", "croczilla", "CacaoRiddle.txt")) { + return this.cacao; + } else { + return null; + } + } + + public String toString() { + return "rainforest"; + } + +} \ No newline at end of file diff --git a/Scoreboard.txt b/Scoreboard.txt new file mode 100644 index 00000000..c7694319 --- /dev/null +++ b/Scoreboard.txt @@ -0,0 +1,12 @@ +abby:6 +sophia:4 +mo:4 +Bill:3 +Joe:2 +df:2 +sd:2 +Martha:1 +Alex:0 +penelope:-1 +maura:-1 +Steve:-2 diff --git a/Tundra.java b/Tundra.java new file mode 100644 index 00000000..1c740107 --- /dev/null +++ b/Tundra.java @@ -0,0 +1,71 @@ +import java.util.Scanner; + +/** + * The tundra class that extends the biome and contains the arctic fox and fern + */ +public class Tundra extends Biome { + private FloraFauna arctic_fox; + private FloraFauna fern; + private String imagePath; + + /** + * Constructor for tundra class with information about FloraFauna + */ + public Tundra() { + super("cs120_lab_image.png"); + this.arctic_fox = new FloraFauna("arctic fox", 6, "Gary"); + this.fern = new FloraFauna("fern", 5, "Finn"); + this.imagePath = "tundra.png"; + } + + /** + * Getter for arctic fox + * @return the fox object + */ + public FloraFauna getAnimal() { + return this.arctic_fox; + } + + /** + * Getter for fern + * @return the fern object + */ + public FloraFauna getPlant() { + return this.fern; + } + + public String getImagePath() { + return imagePath; + } + + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return fox or null. + * @param Scanner s from the game loop class + * @return fox object or null + */ + public FloraFauna animalRiddle(Scanner s) { + if (riddle(s, "arctic fox", "yeti", "FoxRiddle.txt")) { + return this.arctic_fox; + } else { + return null; + } + } + + /** + * Calls riddle method and checks if true or false is returned to determine whether to return fern or null. + * @param Scanner s from the game loop class + * @return fern object or null + */ + public FloraFauna plantRiddle(Scanner s) { + if (riddle(s, "fern", "yeti", "FernRiddle.txt")) { + return this.fern; + } else { + return null; + } + } + + public String toString() { + return "tundra"; + } +} \ No newline at end of file diff --git a/cheatsheet.md b/cheatsheet.md index d5dc4294..233e9054 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -6,3 +6,15 @@ Note: It's a good idea to also make this list available inside the game, in res # SPOILER ALERT If your game includes challenges that must be overcome to win, also list them below. + +Possible user input: +- Riddle answers: + - Rainforest animal: Poison dart frog (Source grammarly) + - Rainforest plant: cacao (Source grammarly) + - Desert animal: camel (Source grammarly) + - Desert plant: cactus (Source grammarly) + - Aquatic animal: dolphin (Source: ChatGPT) + - Aquatic plant: sea anemone (Source: ChatGPT) + - Tundra animal: arctic fox (Source: ChatGPT) + - Tundra plant: fern (Source: ChatGPT) + diff --git a/cs120_lab_image.png b/cs120_lab_image.png new file mode 100644 index 00000000..ac863d48 Binary files /dev/null and b/cs120_lab_image.png differ diff --git a/desert.png b/desert.png new file mode 100644 index 00000000..dee1a0db Binary files /dev/null and b/desert.png differ diff --git a/guava-31.1-jre.jar b/guava-31.1-jre.jar new file mode 100644 index 00000000..16819229 Binary files /dev/null and b/guava-31.1-jre.jar differ diff --git a/lib/hamcrest-core-1.3.jar b/lib/hamcrest-core-1.3.jar new file mode 100644 index 00000000..9d5fe16e Binary files /dev/null and b/lib/hamcrest-core-1.3.jar differ diff --git a/lib/junit-4.13.2.jar b/lib/junit-4.13.2.jar new file mode 100644 index 00000000..6da55d8b Binary files /dev/null and b/lib/junit-4.13.2.jar differ diff --git a/ocean.png b/ocean.png new file mode 100644 index 00000000..9d21c623 Binary files /dev/null and b/ocean.png differ diff --git a/rainforest.png b/rainforest.png new file mode 100644 index 00000000..a99e35fa Binary files /dev/null and b/rainforest.png differ diff --git a/rubric.md b/rubric.md index 8bb8f4c8..3a360f2b 100644 --- a/rubric.md +++ b/rubric.md @@ -2,15 +2,21 @@ _____ 2 pts: Game has a **robust, understandable text-based interface** that allows the player to control their movement through the game. Player should be able to enter any command at any time, and if it makes sense in the current context it will be carried out. +//Should there be end game option? Should there be hint/help option? + _____ 2 pts: Submission includes a **cheat sheet** (`cheatsheet.md`) documenting all of the available commands, as well as a **description of the layout** of your game world's underlying physical layout; this can be described in words, or included as a separate image file if you prefer to sketch a map by hand. If your game includes **challenges** that must be overcome to win, also describe them here. _____ 2 pts: Storyline driving the game is **engaging**, and individual elements of play make sense within the context of the story. -_____ 2 pts: Game has **multiple possible paths / outcomes** (i.e. gameplay depends on player's choices and is not the same every time). +Yes 2 pts: Game has **multiple possible paths / outcomes** (i.e. gameplay depends on player's choices and is not the same every time). + +Yes 1 pt: Gameplay supports **reversible moves** where reasonable (e.g., if you pick up an object, you should be able to put it back down again later, possibly in a different place; if you go north then you should be able to return to the previous location by going south unless something has blocked your return path). + +//Can't put objects down, since this is not the object of the game, but can go north or south. -_____ 1 pt: Gameplay supports **reversible moves** where reasonable (e.g., if you pick up an object, you should be able to put it back down again later, possibly in a different place; if you go north then you should be able to return to the previous location by going south unless something has blocked your return path). +Yes 1 pt: Some paths through the game have **restricted access** until the player has completed a task or acquired a specific item (i.e. a key to open a door, etc.). -_____ 1 pt: Some paths through the game have **restricted access** until the player has completed a task or acquired a specific item (i.e. a key to open a door, etc.). +//Can't access plants w/o animals first ## Back-End Design (10 pts) diff --git a/tundra.png b/tundra.png new file mode 100644 index 00000000..56e9cf1a Binary files /dev/null and b/tundra.png differ