diff --git a/Building.java b/Building.java new file mode 100644 index 00000000..dcec5030 --- /dev/null +++ b/Building.java @@ -0,0 +1,13 @@ +public class Building { + + public String name; + public String description; + public Coordinates location; + + public Building(String name, String description, Coordinates location) { + this.name = name; + this.description = description; + this.location = location; + } + +} diff --git a/Command.java b/Command.java new file mode 100644 index 00000000..a77aa5ff --- /dev/null +++ b/Command.java @@ -0,0 +1,91 @@ +// import java.util.Scanner; +// import javax.xml.transform.Templates; + + +// public class Command{ +// private Player player; +// private Scanner scanner = new Scanner (System.in); +// public Command(Player player, Map map){ +// this.player=player; +// this.map=map; +// } + +// public String interpret(String input){ +// if (input==null){ +// return "You need to enter a command."; +// } +// input=input.trim().toLowerCase(); +// if (input.startsWith("inspect") ){ +// String target =input.replace("inspect","").trim(); +// } +// for (Item item: player.showInventory()){ +// if (item.name.toLowerCase().equal(target)){ +// return item.temDescription(); +// } +// } +// for (Building building: player.showInventory()){ +// if (item.name.toLowerCase().equal(target)){ +// return item.getItemDescription(); +// } +// } +// switch(userInput contains "inspect") && (userInput contains ListOfItems){ +// case NEWSPAPER: +// System.out.println(newspaper.itemDescription); +// break; +// case EPIPEN: +// System.out.println(epipen.itemDescription); +// break; +// case ESSAY: +// System.out.println(essay.itemDescription); +// break; +// case BACKPACK: +// System.out.println(backpack.itemDescription); +// break; +// case PHOTO: +// System.out.println(photo.itemDescription); +// break; +// case CAKE: +// System.out.println(cake.itemDescription); +// break; +// } +// // Change this switch statement so the Player can only inspect the building they are currently in. +// // That means check the current coordinates of the player, and if they match the coordinates of the building then allow the description to be printed out. +// switch(input contains "inspect") && (input contains ListOfBuildings){ +// case QUAD: +// System.out.println(quad.description); +// break; +// case TALBOT_HOUSE: +// System.out.println(talbotHouse.description); +// break; +// case LAMONT_DINING: +// System.out.println(lamontDining.description); +// break; +// case SEELYE_BASEMENT: +// System.out.println(seelyeBasement.description); +// break; +// case CAMPUS_CENTER: +// System.out.println(campusCenter.description); +// break; +// case COLLEGE_HALL: +// System.out.println(collegeHall.description); +// break; +// case OUTDOOR_TRACK: +// System.out.println(outdoorTrack.description); +// break; +// case CHEMISTRY_LAB: +// System.out.println(chemistryLab.description); +// break; +// case CERAMICS_BUILDING: +// System.out.println(ceramicsBuilding.description); +// break; +// } +// } +// } +/* + * accuse still needs to be added to the code, as well as what this command does. + * go north/south/east/west still needs to be added to the code. + * talk to , pick up and put down are all in Player.java. This means that Command.java should extend Player.java + */ + + + diff --git a/Coordinates.java b/Coordinates.java new file mode 100644 index 00000000..1e8f6d96 --- /dev/null +++ b/Coordinates.java @@ -0,0 +1,17 @@ +public class Coordinates { + public double x; + public double y; + + public Coordinates(int x, int y) { + this.x = x; + this.y = y; + } + + public String toString() { + return "You're at (" + this.x + " , " + this.y + ")"; + } + + public boolean equals(Coordinates other) { + return this.x == other.x && this.y == other.y; + } +} diff --git a/Gameloop.java b/Gameloop.java new file mode 100644 index 00000000..8878526c --- /dev/null +++ b/Gameloop.java @@ -0,0 +1,188 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class Gameloop { + public Player player; + private boolean ShakilaAccusedHanyu; + // private boolean StillPlaying; + public List buildings = new ArrayList<>(); + public List items = new ArrayList<>(); + public Gameloop(){ + player= new Player(); + ShakilaAccusedHanyu=false; + +// 9 buildings + Building quad = new Building("Quad", + "Home to many dorms on Smith College.", + new Coordinates(0, 0)); + Building talbotHouse = new Building("Talbot House", + "A dorm, where Boba used to live, so that’s why something feels off now.Hanyu is standing in the aisle. Hanyu lives in Talbot House, just like the victim! Maybe Hanyu wanted her room next year.Did the person die from regular poisoning? Did one of the suspects intentionally poison them with peanuts Do you wanna talk to Hanyu to find out? And look! there is a cake at the corner of the sofa.", + new Coordinates(0, 1)); + Building campusCenter = new Building("Campus Center", + "A common place for studying and meeting with friends. Also there is a cafe.There is a newspaper on the table in the cafe.", + new Coordinates(1, 1)); + Building collegeHall = new Building("College Hall", + "Home to the offices for Class Deans as well as the Student Financial Aid office.", + new Coordinates(1, 2)); + Building chemistryLab = new Building("Chemistry Lab", + "Hanyu does her experiments there, but maybe she knows something about the poison that killed Boba...", + new Coordinates(2, 1)); + Building lamontDining = new Building("Lamont Dining Hall", + "Lamont Dining Hall. An Allergy-free dining hall. Savannah works in Lamont Dining Hall, just like the victim. Didn’t like how lazy they were in the dining hall. Had a chance to poison the student with peanuts! Do you wanna talk to her?", + new Coordinates(0, 2)); + Building seelyeBasement = new Building("Seelye Basement", + "Workplace for Student technology consultant, where Shakila works so she has access to onecards as a worker. The one card has access to any building on campus.Victim copied Shakila’s homework and accusations of plagiarism nearly got her to the honor board. Do you wanna talk to her?", + new Coordinates(1, 0)); + Building outdoorTrack = new Building("Outdoor Track", + "Anjia and Boba used to meet here several times a week because running club practices here. Anjia was on the running club just like the victim. Jealous of her mile time. Do you wanna talk to her?", + new Coordinates(2, 0)); + Building ceramicsBuilding = new Building("Ceramics Building", + "Ceramics Club meets in this lovely location to make pottery together.There is an essay lying on the ground with Shakila’s name on it.", + new Coordinates(2, 2)); + + // add the buildings into the list + buildings.add(quad); + buildings.add(talbotHouse); + buildings.add(campusCenter); + buildings.add(chemistryLab); + buildings.add(lamontDining); + buildings.add(seelyeBasement); + buildings.add(outdoorTrack); + buildings.add(collegeHall); + buildings.add(ceramicsBuilding); + + // 6 items + Item newspaper = new Item("Newspaper", new Coordinates(1, 1), "Today's issue of the Sophian. Its main headline states 'Beloved Student Boba T. Slain Last Night in Talbot House!' Underneath it, there's another story about the Ceramics Club enjoying their pottery-making. Savannah is mentioned in this story.", false); + Item epipen = new Item("EpiPen", new Coordinates(0, 2), "A medication used to treat allergic reactions. It seems like Boba used this sometime ago.", false); + Item essay = new Item("Shakila's Essay", new Coordinates(2, 2), "A five-page essay. The very top of it says 'Shakila, this is the same paper that Boba give me! See me after class.'", false); + //Item backpack = new Item("Boba's Backpack", new Coordinates(1, 2), "There's a photo inside the front pocket of the backpack! You should be able to pick up this photo. Apart from that, the backpack appears to be empty.", false); + Item photo = new Item("Photo", new Coordinates(1, 2), "A nice Polaroid picture of Boba, Shakila, Anjia, Savannah, and Hanyu. But it seems like Anjia's face has been written over with black marker.", false); + Item cake = new Item("Cake", new Coordinates(0, 1), "A slice of vanilla cake on a paper plate. It doesn't seem like there are allergens in here, but you'd have to check...maybe go to the chemistry lab?", false); + + // add the items into the list + items.add(newspaper); + items.add(epipen); + items.add(essay); + //items.add(backpack); + items.add(photo); + items.add(cake); + } + + // NPCs + String [] shakila_d={ + "Look closely at the EpiPen - it was broken! Someone messed with it so it wouldn’t work properly." + , "I was framed! I wrote the essay a few days ago and showed it to Hanyu to help me make edits. But Hanyu and Boba both lived in Talbot House. Maybe Hanyu was involved…", + "I forgot to say this earlier, but I lent Anjia my OneCard earlier, and she could access all sorts of buildings with it…" + }; + NPC Shakila= new NPC("Shakila","Works in Seelye basement, and has access to every door on campus with Seelye OneCard. Victim copied Shakila’s homework and accusations of plagiarism nearly got her to the honor board.", + new ArrayList<>(Arrays.asList(shakila_d)), new Coordinates(1, 0)); + + + String [] hanyu_d={ + "I think it was Savannah! She was acting weird, asking me about peanut allergies when I don’t do food science, I do other things in Chemistry. If you want to look for Savannah I think she’s working a shift in Lamont dining hall. Also my lab is nearly over so I’m going to go back to my House." + ,"Didn’t we just talk earlier? I’d like to help you more but I don’t know what else to say.","I didn’t help Boba cheat. Actually… I think Anjia hates Boba’s most because in every running race, Boba is the winner and Anjia is the runner up." + }; + NPC Hanyu=new NPC("Hanyu","lives in Talbot House, just like the victim! Maybe Hanyu wanted her room next year.", new ArrayList<>(Arrays.asList(hanyu_d)),new Coordinates(2, 1)); + + + String [] savannah_d={ + "Look at the newspaper! There’s a photo of me in Ceramics Club during the night of the murder. I have to be innocent!If you don't believe me, you can go to ceramics buidling." + }; + NPC Savannah= new NPC("Savannah","Works in Lamont Dining Hall, just like the victim. Didn’t like how lazy they were in the dining hall. Had a chance to poison the student with peanuts!",new ArrayList<>(Arrays.asList(savannah_d)),new Coordinates(0, 2)); + + + String [] anjia_d={ + "There is no way I will kill Boba! I always run with her and she is awesome! Now it seems like every suspect doesn't admit they are related to Boba's death. Do you wanna go to College Hall where Baba last was. " + ,"We weren’t really friends when Boba passed away, but that doesn’t mean I killed her. She died from a peanut poisoning, right? I had no way of poisoning her." + }; + NPC Anjia=new NPC("Anjia","Was on the running club just like the victim. Jealous of her mile time.",new ArrayList<>(Arrays.asList(anjia_d)), new Coordinates(2, 0)); + + + public void run(){ + Scanner scanner = new Scanner(System.in); + System.out.println("Hello, Detective! You have been commissioned by the Chief of Northampton Police Station to investigate a murder case at Smith College. Your initial coordinates are (1, 1), Campus Center. Please check the cheatsheet if you are confused about your location or your commands."); + + while (true) { + System.out.print(">>> "); + String input = scanner.nextLine().trim(); + if (input.equalsIgnoreCase("show inventory")) { + player.showInventory(); + } else if (input.equals("exit")) { + System.out.println("Goodbye, detective."); + break; + } else if (input.startsWith("go ")) { + String direction = input.substring(3); + player.move(direction); + System.out.println(player.playerLocation); + } else if (input.startsWith("inspect ")) { + String playerInspect = input.substring(8); + player.inspect(playerInspect, buildings); + } else if (input.startsWith("pick up ")) { + String itemName = input.substring(8); + player.pickUp(itemName, items); + } else if (input.startsWith("put down ")) { + String itemName = input.substring(8); + player.putDown(itemName); + + } else if (input.startsWith("talk to ")) { + String playerTalkTo = input.substring(8); + + if (playerTalkTo.equalsIgnoreCase(Shakila.name) && player.playerLocation.equals(Shakila.location)) { + if (player.getInventory().contains(items.get(1))) { + System.out.println(Shakila.dialogue.get(0)); + } + if (player.getInventory().contains(items.get(2))) { + System.out.println(Shakila.dialogue.get(1)); + ShakilaAccusedHanyu=true; + } + if (player.getInventory().containsAll(items)) { + System.out.println(Shakila.dialogue.get(2)); + } + } else if (playerTalkTo.equalsIgnoreCase(Hanyu.name)) { + if (player.playerLocation.equals(buildings.get(3).location)) { + System.out.println(Hanyu.dialogue.get(0)); + } else if (player.playerLocation.equals(buildings.get(1).location)) { + if (!ShakilaAccusedHanyu) { + System.out.println(Hanyu.dialogue.get(1)); + } else { + System.out.println(Hanyu.dialogue.get(2)); + } + } + } else if (playerTalkTo.equalsIgnoreCase(Savannah.name)&& player.playerLocation.equals(Savannah.location)) { + System.out.println(Savannah.dialogue.get(0)); + } else if (playerTalkTo.equalsIgnoreCase(Anjia.name)&& player.playerLocation.equals(Anjia.location)) { + if (player.getInventory().contains(items.get(3))) { + System.out.println(Anjia.dialogue.get(1)); + } else { + System.out.println(Anjia.dialogue.get(0)); + } + } + } else { + System.out.println("I don't understand that command."); + } + if (input.equalsIgnoreCase("The murderer is Anjia") && player.getInventory().containsAll(items)) { + System.out.println("Anjia was taken to the police station for questioning. Faced with your reasoning and sufficient evidence, she confessed to the crime. Congratulations, case solved!"); + } + } + + scanner.close(); + + } + public static void main(String[] args) { + Gameloop murderMystery = new Gameloop(); + murderMystery.run(); + } + +} + + + + + + + + + + diff --git a/Item.java b/Item.java new file mode 100644 index 00000000..2878d50f --- /dev/null +++ b/Item.java @@ -0,0 +1,13 @@ +public class Item { + String itemName; + String itemDescription; + boolean hasBeenPickedUp; + Coordinates itemLocation; + + public Item(String itemName, Coordinates itemLocation, String itemDescription, boolean hasBeenPickedUp){ + this.itemName = itemName; + this.itemLocation = itemLocation; + this.itemDescription = itemDescription; + this.hasBeenPickedUp = hasBeenPickedUp; + } +} diff --git a/NPC.java b/NPC.java new file mode 100644 index 00000000..6d169df1 --- /dev/null +++ b/NPC.java @@ -0,0 +1,15 @@ +import java.util.ArrayList; +public class NPC{ + public String name; + public String description; + public ArrayList dialogue; + public Coordinates location; + + public NPC(String name,String description,ArrayList dialogue, Coordinates location){ + this.name=name; + this.description=description; + this.dialogue=dialogue; + this.location= location; + } + + } diff --git a/Player.java b/Player.java new file mode 100644 index 00000000..bc6b4a39 --- /dev/null +++ b/Player.java @@ -0,0 +1,103 @@ +import java.util.ArrayList; +import java.util.List; + +/* + * keeps track of the player's name, location, and stuff they carry (inventory) + * is a Coordinates object (inherits x, y, name, and description) + */ + public class Player{ + + private List inventory; //items player has picked up + public Coordinates playerLocation; + + + /* + * Constructor – player with a name and starting location + */ + public Player() { + playerLocation = new Coordinates(1, 1); // initially player is at Campus Center + inventory = new ArrayList<>(); + } + public List getInventory() { + return inventory; + } + + public Coordinates move(String direction) { + if (direction.equalsIgnoreCase("east")) { + playerLocation.x += 1; + } else if (direction.equalsIgnoreCase("west")) { + playerLocation.x -= 1; + } else if (direction.equalsIgnoreCase("north")) { + playerLocation.y += 1; + } else if (direction.equalsIgnoreCase("south")) { + playerLocation.y -= 1; + } else { + System.out.println("Direction unavailable"); + } + return playerLocation; + } + + + //what the player have (what objects) + public void showInventory(){ + if(inventory.isEmpty()){ + System.out.println("You don't have anything yet"); + } else { + System.out.println("You have: "); + for(Item item : inventory){ + System.out.println(item.itemName); //just show item names + } + } + } + + //picks up an item if it hasn't already been picked up + public void pickUp(String playerPickedItem, List items){ + boolean beenFound = false; + for (Item item : items) { + if (playerPickedItem.equalsIgnoreCase(item.itemName) && !inventory.contains(item) && (item.hasBeenPickedUp == false)) { + inventory.add(item); //add it to the bag + item.hasBeenPickedUp = true; // mark the item as picked up! + beenFound = true; + System.out.println("You picked up: " + item.itemName); + break; + } } + if (!beenFound) { + System.out.println("Action unsuccessful."); + } + } + + + + //remove an item from invwntory + public void putDown(String playerPutDownItem){ + for (Item item : inventory) { + if (playerPutDownItem.equalsIgnoreCase(item.itemName)){ + inventory.remove(item); + item.hasBeenPickedUp = false; + System.out.println("You put down: " + item.itemName); + } + System.out.println("You don't even have that item!");} + } + + + public void inspect(String playerInspect, List buildings) { + //System.out.println(inventory); + //Check items in inventory + for (Item item : inventory) { + if (item.itemName.equalsIgnoreCase(playerInspect)) { + System.out.println(item.itemDescription); + } + System.out.println("Please pick up the item before inspecting it."); + } + + // Check buildings + for (Building building : buildings) { + if (playerLocation.equals(building.location) && playerInspect.equalsIgnoreCase(building.name)) { + System.out.println(building.description); + } + } + + } + } + + diff --git a/cheatsheet.md b/cheatsheet.md index d5dc4294..b6b10d29 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -1,8 +1,44 @@ -This file will contain documentation for all commands available in your game. +# Basic commands and info + go(south, north,east,west) + talk to(Shakila, Anjia, Savannah, Hanyu) + pick up + put down + inspect(building and item) + exit + show inventory +
+(0,0) - The Quad +(0,1) - Talbot House +(0,2) - Lamont Dining Hall +(1,0) - Seelye Basement +(1,1) - Campus Center +(1,2) - College Hall +(2,0) - Outdoor Track +(2,1) - Chemistry Lab +(2,2) - Ceramics Building +
+Item names: +Newspaper +EpiPen +Photo +Cake +Shakila's Essay -Note: It's a good idea to also make this list available inside the game, in response to a `HELP` command. +## Warning: the names of non-player characters are case-SENSITIVE. +# End of the game +After you collected all the items, type down "the murderer is....(name of one of the four suspects)." If you find the true cirminal, +a congratulations message will pop up. # SPOILER ALERT +### Recommended route: +We highly recommend you go to Chemistry Lab to talk to Hanyu first. +### Item locations: +Newspaper - Campus Center +Epipen - Lamont Dining Hall +Photo - College Hall +Cake - Talbot House +Shakila's Essay - Ceramics Building + + -If your game includes challenges that must be overcome to win, also list them below. diff --git a/diagram.png b/diagram.png new file mode 100644 index 00000000..c9508f9c Binary files /dev/null and b/diagram.png differ diff --git a/rubric.md b/rubric.md index 8bb8f4c8..7cc75a3f 100644 --- a/rubric.md +++ b/rubric.md @@ -1,37 +1,37 @@ ## Front-End Design (10 pts) -_____ 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. +__Yes___ 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. -_____ 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. +__Yes___ 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. +__Yes___ 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). -_____ 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: 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). -_____ 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.). +__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.). ## Back-End Design (10 pts) -_____ 2 pts: Selected classes(s) are **effective, efficient** at supporting the desired operations and program behavior. +__Yes___ 2 pts: Selected classes(s) are **effective, efficient** at supporting the desired operations and program behavior. -_____ 2 pts: Design justification includes a discussion of at least one (reasonable) **alternative design** that could have been used, and the reasons why you decided against this alternative. +___Yes__ 2 pts: Design justification includes a discussion of at least one (reasonable) **alternative design** that could have been used, and the reasons why you decided against this alternative. -_____ 2 pts: The project makes effective use of **Java built-in classes** whenever they are appropriate. +__Yes___ 2 pts: The project makes effective use of **Java built-in classes** whenever they are appropriate. -_____ 2 pts: The project's design is **extensible** (i.e. someone else could pick up where you left off, adding on or modifying the game without requiring a total rewrite). +__Yes___ 2 pts: The project's design is **extensible** (i.e. someone else could pick up where you left off, adding on or modifying the game without requiring a total rewrite). -_____ 2 pts: Submission includes an **architecture diagram** describing the relationships between all classes. +__Yes___ 2 pts: Submission includes an **architecture diagram** describing the relationships between all classes. ## General Items (10 pts): -_____ 4 pts: Program compiles without errors or warnings. +___Yes__ 4 pts: Program compiles without errors or warnings. -_____ 2 pts: Executes fully & consistently without crashing (exception/freeze). +__Yes___ 2 pts: Executes fully & consistently without crashing (exception/freeze). -_____ 2 pt: Complies with style guidelines (missing items 1 pt each): +___Yes__ 2 pt: Complies with style guidelines (missing items 1 pt each): _____ Classes & class members all have Javadoc header comments.