package org.project; import org.project.entity.enemies.*; import org.project.entity.players.Assassin; import org.project.entity.players.Knight; import org.project.entity.players.Player; import org.project.entity.players.Wizard; import org.project.location.Location; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Scanner; public class Game { private final ArrayList players; private final ArrayList regularEnemies; private final ArrayList locations; private final Scanner sc; private Player player; private final ArrayList> collectedKeyTypes = new ArrayList<>(); public Game() { sc = new Scanner(System.in); players = new ArrayList<>(); players.add(new Assassin()); players.add(new Knight()); players.add(new Wizard()); regularEnemies = new ArrayList<>(); regularEnemies.add(new Goblin()); regularEnemies.add(new Skeleton()); regularEnemies.add(new Vampire()); locations = new ArrayList<>(); locations.add(new Location("Jungle", regularEnemies)); locations.add(new Location("China", new ArrayList<>(regularEnemies.subList(0, 2)))); locations.add(new Location("Iran", new ArrayList<>(regularEnemies.subList(1, 3)))); } public void start() { player = choosePlayer(); while (true) { displayKeys(); Location location = chooseLocation(); Enemy enemy = chooseEnemy(location); System.out.println("Wanna fight?\n1. Yes\n2. No"); int choice = sc.nextInt(); if (choice != 1) continue; combat(player, enemy); System.out.println("Player HP: " + player.getHP()); if (!player.isAlive()) { System.out.println("Game over."); break; } if (canChallengeDragon()) { System.out.println("\nYou have collected all keys! The Dragon awaits..."); System.out.println("Challenge the Dragon?\n1. Yes\n2. No"); if (sc.nextInt() == 1) { challengeDragon(); break; } } } } private boolean canChallengeDragon() { for (Enemy enemy : regularEnemies) { if (!collectedKeyTypes.contains(enemy.getClass())) return false; } return true; } private void challengeDragon() { Dragon dragon = new Dragon(); combat(player, dragon); if (player.isAlive()) { System.out.println("Congratulations! You defeated the Dragon and completed the game!"); } else { System.out.println("The Dragon was too powerful. Better luck next time."); } } private Player choosePlayer() { System.out.print("1. Assassin\n2. Knight\n3. Wizard\nChoose your character: "); int choice = sc.nextInt(); Player chosen = switch (choice) { case 1 -> players.get(0); case 2 -> players.get(1); default -> players.get(2); }; System.out.println("You chose " + chosen.getName() + " (" + chosen.getClass().getSimpleName() + ")"); return chosen; } private void displayKeys() { System.out.println("=".repeat(30)); System.out.print("Keys collected: "); List collected = new ArrayList<>(); List missing = new ArrayList<>(); for (Enemy enemy : regularEnemies) { if (collectedKeyTypes.contains(enemy.getClass())) collected.add(enemy.getClass().getSimpleName()); else missing.add(enemy.getClass().getSimpleName()); } if (collected.isEmpty()) { System.out.println("none"); } else { System.out.println(String.join(", ", collected)); } if (!missing.isEmpty()) { System.out.println("Still needed: " + String.join(", ", missing)); } System.out.println("=".repeat(30)); } private void displayLocations() { for (Location location : locations) { System.out.println(location); } } private Location chooseLocation() { displayLocations(); System.out.print("1. Jungle\n2. China\n3. Iran\nChoose location: "); int choice = sc.nextInt(); Location location = switch (choice) { case 1 -> locations.get(0); case 2 -> locations.get(1); default -> locations.get(2); }; System.out.println("You chose " + location.getName()); return location; } private Enemy chooseEnemy(Location location) { int index = new Random().nextInt(location.getEnemies().size()); Enemy enemy = location.getEnemies().get(index); enemy.setHP(enemy.getMaxHP()); enemy.setMP(enemy.getMaxMP()); System.out.println("The enemy is: " + enemy.getClass().getSimpleName()); return enemy; } private void combat(Player player, Enemy enemy) { int turn = 0; while (player.isAlive() && enemy.isAlive()) { if (turn == 0) { System.out.println("Choose your action:"); System.out.println("1. Light attack 2. Heavy attack 3. Defend" + " 4. Heal 5. Special ability 6. Flask"); int choice = sc.nextInt(); boolean actionTaken = handlePlayerAction(choice, enemy); if (!actionTaken) continue; turn = 1; printCombatStatus(enemy); if (!enemy.isAlive()) break; } else { System.out.println("-".repeat(30)); if (player instanceof Assassin && player.getUsingSpecialAbility()) { System.out.println(enemy.getClass().getSimpleName() + " skipped its turn!"); turn = 0; continue; } System.out.println(enemy.getClass().getSimpleName() + "'s turn:"); boolean enemyActed = handleEnemyAction(enemy); if (!enemyActed) continue; turn = 0; printCombatStatus(enemy); if (!player.isAlive()) break; } } if (!player.isAlive()) { System.out.println("You lost!"); } else { System.out.println("You won!"); player.gainXP(Player.xpRewardFor(enemy)); player.setHP(player.getMaxHP()); player.setMP(player.getMaxMP()); if (!(enemy instanceof Dragon)) { Class type = enemy.getClass(); if (!collectedKeyTypes.contains(type)) { collectedKeyTypes.add(type); System.out.println(enemy.getClass().getSimpleName() + "'s key dropped!"); player.achieveKey(enemy); } else { System.out.println("You already have " + enemy.getClass().getSimpleName() + "'s key."); } } } } private boolean handlePlayerAction(int choice, Enemy enemy) { switch (choice) { case 1 -> { player.lightAttack(enemy); return true; } case 2 -> { player.heavyAttack(enemy); return player.isSuccessfulAction();} case 3 -> { player.defend(); return player.isSuccessfulAction(); } case 4 -> { player.heal(10); return player.isSuccessfulAction(); } case 5 -> { player.specialAbility(enemy); return player.isSuccessfulAction(); } case 6 -> { player.getFlask().use(player); return true; } default -> { System.out.println("Invalid choice."); return false; } } } private boolean handleEnemyAction(Enemy enemy) { int choice = new Random().nextInt(3); switch (choice) { case 1 -> { enemy.defend(); return enemy.isSuccessfulAction(); } case 2 -> { enemy.heal(10); return enemy.isSuccessfulAction(); } } enemy.attack(player); return true; } private void printCombatStatus(Enemy enemy) { System.out.println("[" + player.getClass().getSimpleName() + " - " + player.getHP() + "/" + player.getMaxHP() + " HP | " + player.getMP() + "/" + player.getMaxMP() + " MP]"); System.out.println("[" + enemy.getClass().getSimpleName() + " - " + enemy.getHP() + "/" + enemy.getMaxHP() + " HP | " + enemy.getMP() + "/" + enemy.getMaxMP() + "MP]"); } }