commit 55e0908c78f42fa168a3c5824fbd5f123c821511 Author: Isaac Shoebottom Date: Thu Jun 16 19:21:05 2022 -0300 Initial check-in diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/artifacts/TextBasedGame.xml b/.idea/artifacts/TextBasedGame.xml new file mode 100644 index 0000000..a9afea3 --- /dev/null +++ b/.idea/artifacts/TextBasedGame.xml @@ -0,0 +1,11 @@ + + + $PROJECT_DIR$/out/artifacts/TextBasedGame + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..919ce1f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0548357 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6dc22ca --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..ecc1a3d --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + "keyToString": { + "ASKED_ADD_EXTERNAL_FILES": "true", + "Downloaded.Files.Path.Enabled": "false", + "Repository.Attach.Annotations": "false", + "Repository.Attach.JavaDocs": "false", + "Repository.Attach.Sources": "false", + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "SHARE_PROJECT_CONFIGURATION_FILES": "true", + "WebServerToolWindowFactoryState": "false", + "last_opened_file_path": "C:/GitHub/Java-TextBasedGame/out/production/Java-TextBasedGame", + "project.structure.last.edited": "Artifacts", + "project.structure.proportion": "0.15", + "project.structure.side.proportion": "0.29177958", + "settings.editor.selected.configurable": "web.server" + } +} + + + + + + + + + + + + + + + + + + + + + 1655054868910 + + + + + + \ No newline at end of file diff --git a/Java-TextBasedGame.iml b/Java-TextBasedGame.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/Java-TextBasedGame.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/character/Isaac.dat b/character/Isaac.dat new file mode 100644 index 0000000..9086a2c Binary files /dev/null and b/character/Isaac.dat differ diff --git a/src/Armor.java b/src/Armor.java new file mode 100644 index 0000000..c5c451e --- /dev/null +++ b/src/Armor.java @@ -0,0 +1,11 @@ +import java.io.Serializable; +public class Armor extends Item implements Serializable { + double armor; + String armorClass; + + Armor(String name, String description, long value, double armor, String armorClass){ + super(name, description, value); + this.armor = armor; + this.armorClass = armorClass; + } +} diff --git a/src/Enemy.java b/src/Enemy.java new file mode 100644 index 0000000..a0de847 --- /dev/null +++ b/src/Enemy.java @@ -0,0 +1,2 @@ +public class Enemy extends Person { +} diff --git a/src/Game.java b/src/Game.java new file mode 100644 index 0000000..625e605 --- /dev/null +++ b/src/Game.java @@ -0,0 +1,341 @@ +import java.io.*; +import java.util.*; + +/* + TODO: Implement move + TODO: Implement armor + TODO: Implement NPCs + TODO: Implement Fights (Implement armor and attack formula) + TODO: Implement enemy looting + TODO: Implement game over + TODO: Implement armor factory + TODO: Implement map + TODO: Implement player equipment + TODO: Add key to left map + TODO: Add gate to right of map + TODO: Make inventory more robust with damage/armor/value display + TODO: Save and load object //Test if can be broken + TODO: Save visited locations in player + TODO: Rewrite switch case to use either .startWith/.endsWith to .split input string and then able to use positional arguments + Maybe: + TODO: Make factory that can take locations as arguments + TODO: Town after gate + TODO: Interiors + TODO: Dungeons + TODO: Implement vendors + */ + +public class Game { + public static void main(String[] args) throws IOException { + boolean exit = false; + String input; + Player player; + if (args.length > 0 && Objects.equals(args[0], "load")) { + try { + FileInputStream saveFile = new FileInputStream("./character/" + args[1] + ".dat"); + ObjectInputStream save = new ObjectInputStream(saveFile); + player = (Player) save.readObject(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + else { + player = createPlayer(args); + System.out.println("You wake up feeling groggy, you feel like praying for help might provide you with direction."); + } + while (!exit) { + input = reader.readLine(); + input = input.toLowerCase(Locale.ROOT); + switch (input) { + case "help": + System.out.println("help: describes all given commands"); + System.out.println("inspect area/{direction}: gives you the name of the area you are in"); + System.out.println("describe area/{direction}: gives a description of the area along with the presence of items"); + System.out.println("move {direction}: moves in the specified cardinal direction"); + System.out.println("take: shows a list of all items on the ground"); + System.out.println("inspect items: shows a list of all items on the ground"); + System.out.println("save: saves player to file in directory \"character\" with the given character name. " + "load from the command line with load {character name}"); + System.out.println("inventory: shows which items are in player inventory"); + System.out.println("exit: close game"); + break; + + case "inventory": + System.out.println(player.inventory); + break; + + + + case "save": + try { + FileOutputStream saveFile = new FileOutputStream("./character/" + player.name + ".dat"); + ObjectOutputStream save = new ObjectOutputStream(saveFile); + save.writeObject(player); + save.close(); + saveFile.close(); + System.out.println("Data saved"); + } catch (IOException e) { + throw new RuntimeException(e); + } + break; + + case "inspect items": + if (player.current.items.length == 0) { + System.out.println("There are no items here"); + } + for(Item item: player.current.items) { + System.out.print(item.name + ": " + item.description + " Worth: " + item.value); + // if type is weapon show damage + if (item instanceof Weapon) { + System.out.println(". Damage: " + ((Weapon) item).damage); + } + } + break; + case "take": + // section which lists the name of the items + if (player.current.items.length == 0) { + System.out.println("There are no items to take."); + break; + } + if (player.current.items.length == 1) { + System.out.println("There appears to be an item around. It is a " + + Arrays.deepToString(player.current.items) + .replace(",", "") //remove the commas + .replace("[", "") //remove the right bracket + .replace("]", "") //remove the left bracket + .trim()); + } + if (player.current.items.length > 1) { + System.out.println(" There appears to be some items around. They are " + + Arrays.deepToString(player.current.items) + .replace(",", ", or") //remove the commas + .replace("[", "") //remove the right bracket + .replace("]", "") //remove the left bracket + .trim()); + } + //section asking which item + System.out.println("Which item do you take?: "); + input = reader.readLine(); + input = input.toLowerCase(Locale.ROOT); + int duplicateNameCount = 0; + Item itemToRemove; + ArrayList duplicateItems = new ArrayList<>(); + for(Item item: player.current.items) { + if (item.name.toLowerCase(Locale.ROOT).contains(input)) { + duplicateItems.add(item); + duplicateNameCount++; + } + } + // if there are no duplicates + if (duplicateNameCount == 1) { + itemToRemove = duplicateItems.get(0); + player.inventory.add(itemToRemove); + } + // if there are items with the same name, check for duplicates + // else because duplicateItemCount is always greater than 1, does not need to be else if + else { + // convert arraylist to array for the purpose of the for loop + Item[] duplicateItemsArray = new Item[duplicateItems.size()]; + duplicateItems.toArray(duplicateItemsArray); + // print duplicate items + int count = 1; + for(Item item: duplicateItemsArray) { + System.out.print("Item " + count + ": " + item.name + ": " + item.description + " Worth:" + item.value); + // if type is weapon show damage + if (item instanceof Weapon) { + System.out.println(". Damage: " + ((Weapon) item).damage); + } + } + // make sure choice is numeric + String choiceStr; + do { + System.out.print("Which " + duplicateItems.get(0).name + " do you take?: "); + choiceStr = reader.readLine(); + } while (isNotNumericString(choiceStr)); + //add item to player inventory + int choice = Integer.parseInt(choiceStr); + itemToRemove = duplicateItems.get(choice); + player.inventory.add(duplicateItems.get(choice)); + } + //search for index by object and remove item from location + int index = 0; + for (int i = 0; i < player.current.items.length; i++) { + if (itemToRemove == player.current.items[i]) { + index = i; + } + } + System.out.println("You took the " + itemToRemove.name + "."); + player.current.items = Item.removeElement(player.current.items, index); + break; + //inspect area + case "inspect area": + System.out.println("You appear to be in a " + player.current.name); + break; + case "inspect north": + System.out.println("This area appears to be a " + player.current.north.name); + break; + case "inspect east": + System.out.println("This area appears to be a " + player.current.east.name); + break; + case "inspect south": + System.out.println("This area appears to be a " + player.current.south.name); + break; + case "inspect west": + System.out.println("This area appears to be a " + player.current.west.name); + break; + + case "move": + System.out.println("Please provide a direction"); + case "move north": + if (player.current.north.canWalk) { + player.current = player.current.north; + System.out.println("You move north"); + //begin enemy encounter + enemyEncounter(player); + } + else { + System.out.println("This area seems too difficult to navigate"); + } + + case "move east": + + case "move south": + + case "move west": + + + //describe + + case "describe area": + System.out.print("The area appears to be a " + player.current.description); + if (player.current.items.length == 1) { + System.out.println(" There appears to be an item around. It is a " + + Arrays.deepToString(player.current.items) + .replace(",", "") //remove the commas + .replace("[", "") //remove the right bracket + .replace("]", "") //remove the left bracket + .trim()); + } + else if (player.current.items.length > 1) { + System.out.println(" There appears to be some items around. They are " + + Arrays.deepToString(player.current.items) + .replace(",", ", and") //remove the commas + .replace("[", "") //remove the right bracket + .replace("]", "") //remove the left bracket + .trim()); + } + else { + System.out.println(); + } + break; + case "describe north": + System.out.println("The area appears to be a " + player.current.north.description); + break; + case "describe east": + System.out.println("The area appears to be a " + player.current.east.description); + break; + case "describe south": + System.out.println("The area appears to be a " + player.current.south.description); + break; + case "describe west": + System.out.println("The area appears to be a " + player.current.west.description); + break; + case "exit": + exit = true; + break; + default: + System.out.println("Command not recognized"); + break; + } + } + } + static void enemyEncounter(Player player) { + Random random = new Random(); + double doesEncounter = random.nextDouble() * 100; + if (doesEncounter <= player.current.enemyChance) { + + } + + } + static Player createPlayer(String[] args) throws IOException { + String name; + int age; + String gender; + if (args.length > 0) { + name = args[0]; + System.out.println("What is your name?: " + name); + age = Integer.parseInt(args[1]); + System.out.println("What is your age?: " + age); + gender = args[2]; + System.out.println("Are you male (m), female (f), gender-fluid (g), or androgynous (a)?: " + gender); + } + else { + System.out.print("What is your name?: "); + name = reader.readLine(); + String ageString; + do { + System.out.print("What is your age?: "); + ageString = reader.readLine(); + } while (isNotNumericString(ageString)); + age = Integer.parseInt(ageString); + System.out.print("Are you male (m), female (f), gender-fluid (g), or androgynous (a)?: "); + gender = reader.readLine(); + } + boolean isMale = false; + boolean isFemale = false; + switch (gender){ + case "m": + case "M": + //male case + isMale = true; + break; + case "f": + case "F": + //female case + isFemale = true; + break; + case "g": + case "G": + //gender-fluid case + isMale = true; + isFemale = true; + break; + case "a": + case "A": + default: + //androgynous case + break; + } + return new Player(name, age, isMale, isFemale, startArea); + } + public static boolean isNotNumericString(String str) { + try { + Double.parseDouble(str); + return false; + } catch (NumberFormatException e) { + return true; + } + } + /* + --------------------------------- + | $ % % % % % x x x x x x x x # | + ---------------- % ------------- + | x | + | ! | + ----- + */ + //factories + static WeaponFactory weaponFactory = new WeaponFactory(); + + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + + //item lists + static Item[] startAreaItems = {weaponFactory.getWeapon("stick")}; + //locations + static Location impassibleShrubs = new Location("thick shrubs", "this location looks impossible to move through.", + false); + static Location startArea = new Location("forest clearing", "small clearing the the forest, light shines through from above.", + true, 0, + startAreaItems, + null, impassibleShrubs, impassibleShrubs, impassibleShrubs); + +} \ No newline at end of file diff --git a/src/Item.java b/src/Item.java new file mode 100644 index 0000000..757a6b5 --- /dev/null +++ b/src/Item.java @@ -0,0 +1,23 @@ +import java.io.Serializable; + +public class Item implements Serializable { + String name; + String description; + long value; + + Item(String name, String description, long value) { + this.name = name; + this.description = description; + this.value = value; + } + + public String toString() { + return name; + } + public static Item[] removeElement(Item[] original, int element){ + Item[] n = new Item[original.length - 1]; + System.arraycopy(original, 0, n, 0, element ); + System.arraycopy(original, element+1, n, element, original.length - element-1); + return n; + } +} diff --git a/src/Location.java b/src/Location.java new file mode 100644 index 0000000..8d779cc --- /dev/null +++ b/src/Location.java @@ -0,0 +1,41 @@ +import java.io.Serializable; + +public class Location implements Serializable { + + //locations + + + //end locations + + String name; + String description; + Item[] items; + boolean canWalk; + Location north; + Location east; + Location south; + Location west; + double enemyChance; + + Location(String name, String description, boolean canWalk) { + this.name = name; + this.description = description; + this.canWalk = false; + this.north = null; + this.east = null; + this.south = null; + this.west = null; + } + + Location(String name, String description, boolean canWalk, double enemyChance, Item[] items, Location north, Location east, Location south, Location west) { + this.name = name; + this.description = description; + this.canWalk = canWalk; + this.enemyChance = enemyChance; + this.items = items; + this.north = north; + this.east = east; + this.south = south; + this.west = west; + } +} diff --git a/src/Person.java b/src/Person.java new file mode 100644 index 0000000..203f42d --- /dev/null +++ b/src/Person.java @@ -0,0 +1,58 @@ +import java.io.Serializable; +import java.util.ArrayList; + +public class Person implements Serializable { + String name; + int age; + double heath; + boolean isMale; + boolean isFemale; + Weapon hands; + Armor head; + Armor chest; + Armor leftArm; + Armor rightArm; + Armor leftLeg; + Armor rightLeg; + ArrayList inventory; + + public Person() { + this.inventory = new ArrayList<>(); + } + + Person(String name, int age, double heath, boolean isMale, boolean isFemale, + Weapon hands, + Armor head, Armor chest, Armor leftArm, Armor rightArm, Armor leftLeg, Armor rightLeg, + ArrayList inventory) { + this.name = name; + this.age = age; + this.heath = heath; + this.isMale = isMale; + this.isFemale = isFemale; + this.hands = hands; + this.head = head; + this.chest = chest; + this.leftArm = leftArm; + this.rightArm = rightArm; + this.leftLeg = leftLeg; + this.rightLeg = rightLeg; + this.inventory = inventory; + + addEquipmentToInventory(); + } + + public double getDamage(){ + return hands.damage; + } + public double getArmor(){ + return head.armor + chest.armor + leftArm.armor + rightArm.armor + leftLeg.armor + rightLeg.armor; + } + private void addEquipmentToInventory() { + inventory.add(head); + inventory.add(chest); + inventory.add(leftArm); + inventory.add(rightArm); + inventory.add(leftLeg); + inventory.add(rightLeg); + } +} diff --git a/src/Player.java b/src/Player.java new file mode 100644 index 0000000..951884f --- /dev/null +++ b/src/Player.java @@ -0,0 +1,16 @@ +import java.io.Serializable; + +public class Player extends Person implements Serializable { + boolean isPlayer = true; + Location current; + + Player(String name, int age, boolean isMale, boolean isFemale, Location current) { + super(); + this.name = name; + this.age = age; + this.isMale = isMale; + this.isFemale = isFemale; + this.heath = 100; + this.current = current; + } +} diff --git a/src/Weapon.java b/src/Weapon.java new file mode 100644 index 0000000..26da292 --- /dev/null +++ b/src/Weapon.java @@ -0,0 +1,10 @@ +import java.io.Serializable; + +public class Weapon extends Item implements Serializable { + double damage; + Weapon(String name, String description, long value, double damage){ + super(name, description, value); + this.damage = damage; + } +} + diff --git a/src/WeaponFactory.java b/src/WeaponFactory.java new file mode 100644 index 0000000..dc7cbb3 --- /dev/null +++ b/src/WeaponFactory.java @@ -0,0 +1,24 @@ +import java.text.DecimalFormat; +import java.util.Random; + +public class WeaponFactory { + private double getRandomDouble(double min, double max) { + Random random = new Random(); + double randomValue = min + (max - min) * random.nextDouble(); + DecimalFormat df = new DecimalFormat("#.#"); + randomValue = Double.parseDouble(df.format(randomValue)); + return randomValue; + } + + public Weapon getWeapon(String weaponType) { + if (weaponType.equalsIgnoreCase("stick")) { + return new Weapon("Stick", "a pointed stick.", 1, getRandomDouble(1, 2)); + } + if (weaponType.equalsIgnoreCase("sword")) { + return new Weapon("Sword", "a shiny sword", 35, getRandomDouble(14, 16)); + } + else { + return null; + } + } +}