package org.project; import org.project.entity.Entity; 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.item.weapons.Dagger; import org.project.item.weapons.Sword; import org.project.location.Location; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Scanner; import static org.project.entity.enemies.Enemy.GREEN; import static org.project.entity.players.Player.*; public class Game { private Player player; private Scanner scanner; private Location currentLocation; private List allLocations; private Enemy currentEnemy; private Random random = new Random(); private boolean hasGoblinKey = false; private boolean hasSkeletonKey = false; private boolean hasVampireKey = false; private List allEnemiesInGame = new ArrayList<>(); protected static final String GREEN_LIGHT = "\033[92m"; protected static final String PURPLE = "\033[35m"; public Game() { this.scanner = new Scanner(System.in); this.allLocations = setupWorld(); } public void start() { System.out.println("\n🏰 Welcome to Java Knight!"); this.player = createPlayer(); selectStartingLocation(); spawnRandomEnemy(); gameLoop(); } public Player createPlayer() { System.out.println("Enter your name: "); String name = scanner.nextLine(); System.out.println("1. βš”οΈ Knight (High Damage, Balanced HP)"); System.out.println("2. πŸ§™ Wizard (High HP, Magic Power)"); System.out.println("3. πŸ—‘οΈ Assassin (High Mana, Critical Hits)"); int choice = getIntInput("Choose your character: "); Player newPlayer = null; switch (choice) { case 1: System.out.println("You chose the Knight!"); newPlayer = new Knight(name); break; case 2: System.out.println("You chose the Wizard!"); newPlayer = new Wizard(name); break; case 3: System.out.println("You chose the Assassin!"); newPlayer = new Assassin(name); break; default: System.out.println("Invalid choice. Defaulting to Knight."); newPlayer = new Knight(name); break; } return newPlayer; } public void selectStartingLocation() { System.out.println("πŸ—ΊοΈ Choose your starting location:"); for (int i = 0; i < allLocations.size(); i++) { System.out.println((i+1) + ". " + allLocations.get(i).getName()); } int choice = getIntInput("Enter your choice: "); if (choice > 0 && choice <= allLocations.size()) { this.currentLocation = allLocations.get(choice - 1); System.out.println("🚢 You have arrived at: " + currentLocation.getName()); } else { System.out.println("Invalid choice. Defaulting to Forest."); this.currentLocation = allLocations.get(0); } } private List setupWorld() { List locations = new ArrayList<>(); ArrayList forestEnemies = new ArrayList<>(); forestEnemies.add(new Goblin(new Dagger())); forestEnemies.add(new Goblin(new Dagger())); forestEnemies.add(new Goblin(new Dagger())); forestEnemies.add(new Goblin(new Dagger())); forestEnemies.add(new Skeleton(new Sword())); forestEnemies.add(new Vampire(new Dagger())); forestEnemies.add(new Skeleton(new Sword())); forestEnemies.add(new Vampire(new Dagger())); forestEnemies.add(new Skeleton(new Sword())); Location forest = new Location("Dark Forest", new ArrayList<>(), forestEnemies); allEnemiesInGame.addAll(forestEnemies); ArrayList caveEnemies = new ArrayList<>(); caveEnemies.add(new Skeleton(new Sword())); caveEnemies.add(new Skeleton(new Sword())); caveEnemies.add(new Skeleton(new Sword())); caveEnemies.add(new Skeleton(new Sword())); caveEnemies.add(new Goblin(new Dagger())); caveEnemies.add(new Vampire(new Dagger())); caveEnemies.add(new Goblin(new Dagger())); caveEnemies.add(new Vampire(new Dagger())); caveEnemies.add(new Vampire(new Dagger())); Location cave = new Location("Spooky Cave", new ArrayList<>(), caveEnemies); allEnemiesInGame.addAll(caveEnemies); ArrayList swampEnemies = new ArrayList<>(); swampEnemies.add(new Vampire(new Dagger())); swampEnemies.add(new Vampire(new Dagger())); swampEnemies.add(new Vampire(new Dagger())); swampEnemies.add(new Vampire(new Dagger())); swampEnemies.add(new Goblin(new Dagger())); swampEnemies.add(new Skeleton(new Sword())); swampEnemies.add(new Goblin(new Dagger())); swampEnemies.add(new Goblin(new Dagger())); swampEnemies.add(new Skeleton(new Sword())); Location swamp = new Location("Swamp", new ArrayList<>(), swampEnemies); allEnemiesInGame.addAll(swampEnemies); locations.add(forest); locations.add(cave); locations.add(swamp); return locations; } public void spawnRandomEnemy() { ArrayList enemies = currentLocation.getEnemies(); if (enemies == null || enemies.isEmpty()) { System.out.println("🌲 The area is quiet... no enemies nearby. Move to another location."); this.currentEnemy = null; return; } int index = random.nextInt(enemies.size()); this.currentEnemy = enemies.get(index); this.currentEnemy = enemies.remove(index); allEnemiesInGame.remove(this.currentEnemy); System.out.println("⚠️ A wild " + currentEnemy.getClass().getSimpleName() + " appears in " + currentLocation.getName() + "!"); } public void gameLoop() { while (player.isAlive()) { System.out.println("\n========================================"); System.out.println("πŸ“ Location: " + currentLocation.getName()); System.out.println("❀️ Player HP: " + player.getHp() + "/" + player.getMaxHP()); System.out.println("πŸ’Ž Player MP: " + player.getMp() + "/" + player.getMaxMP()); if (currentEnemy != null && currentEnemy.isAlive()) { System.out.println("Enemy: " + currentEnemy.getClass().getSimpleName() + " (HP: " + currentEnemy.getHp() + ")"); } System.out.println("---- Actions ----"); System.out.println("1. πŸ₯· Fight enemy"); System.out.println("2. 🚢 Move to another location"); System.out.println("3. πŸ”’ Go to Dragon Castle"); System.out.println("4. 🏳️ Quit game"); int choice = getIntInput("Enter your choice: "); switch (choice) { case 1: //fight if (currentEnemy == null) { spawnRandomEnemy(); } if (currentEnemy != null) { System.out.println("βš”οΈ Battle Started: " + player.getName() + " vs " + currentEnemy.getClass().getSimpleName()); fight(currentEnemy); postCombat(currentEnemy); spawnRandomEnemy(); } else { System.out.println("⚠️ No enemy found in this location."); } break; case 2: //move moveLocation(); spawnRandomEnemy(); break; case 3: if (hasGoblinKey && hasSkeletonKey && hasVampireKey) { System.out.println(PURPLE+"πŸ‰ Entering Dragon's lair..."+RESET); startDragonFight(); } else { System.out.println("πŸ”’ Locked! Collect all 3 keys."); } break; case 4: System.out.println("Byyyeee!"); return; default: System.out.println("Invalid."); break; } } System.out.println(RED+"==== πŸ’€ Game Over! ===="+RESET); } private void fight(Enemy enemy) { while (player.isAlive() && enemy.isAlive()) { handlePlayerTurn(enemy); if (enemy.isStunned()) { System.out.println("Enemy is stunned and skips its turn!"); enemy.unstun(); } else { enemy.attack(player); } } } private void handlePlayerTurn(Entity target) { System.out.println(BLUE+"\n--- Your Turn ---"+RESET); System.out.println("1. Light Attack | 2. Heavy Attack (-20 Mana) | 3. Defend (-15 Mana) | 4. Heal (-30 Mana) | 5. Special (-50 Mana)"); int action = getIntInput("Choose action: "); switch (action) { case 1: player.lightAttack(target); break; case 2: player.heavyAttack(target); break; case 3: player.defend(); break; case 4: player.heal(20); break; case 5: player.specialAbility(target); break; default: System.out.println("Invalid!"); break; } } public void postCombat(Enemy enemy) { if (player.isAlive()) { int xp = enemy.getXpReward(); player.addXp(xp); checkKeyDrop(enemy); player.setHp(player.getMaxHP()); player.fillMana(player.getMaxMP() - player.getMp()); System.out.println("πŸ’– HP and MP fully restored!"); } } public void checkKeyDrop(Enemy enemy) { if (enemy instanceof Goblin && hasGoblinKey) return; if (enemy instanceof Skeleton && hasSkeletonKey) return; if (enemy instanceof Vampire && hasVampireKey) return; String enemyType = enemy.getClass().getSimpleName(); boolean isLastOne = true; for (Enemy e : allEnemiesInGame) { if (e.getClass().getSimpleName().equals(enemyType)) { isLastOne = false; break; } } double dropChance; if (isLastOne) { dropChance = 1.0; System.out.println("✨ This is the last " + enemyType + " in the world!"); } else { dropChance = 0.2; //20% chance } if (Math.random() < dropChance) { if (enemy instanceof Goblin) { hasGoblinKey = true; System.out.println(GREEN + "πŸ”‘ You found the Goblin Key!" + RESET); } else if (enemy instanceof Skeleton) { hasSkeletonKey = true; System.out.println(GREEN + "πŸ”‘ You found the Skeleton Key!" + RESET); } else if (enemy instanceof Vampire) { hasVampireKey = true; System.out.println(GREEN + "πŸ”‘ You found the Vampire Key!" + RESET); } } } private void moveLocation() { System.out.println("πŸ—ΊοΈ Available destinations:"); for (int i = 0; i < allLocations.size(); i++) { System.out.println((i + 1) + ". " + allLocations.get(i).getName()); } int choice = getIntInput("Choose destination: "); if (choice > 0 && choice <= allLocations.size()) { currentLocation = allLocations.get(choice - 1); System.out.println("🚢 You traveled to " + currentLocation.getName()); } } private void startDragonFight() { System.out.println("πŸ‰ THE DRAGON APPEARS! PREPARE FOR BATTLE!"); Dragon dragon = new Dragon(null); fight(dragon); if (player.isAlive()) { System.out.println(GREEN_LIGHT + "\n== πŸ† VICTORY! You have defeated the Dragon and broken the curse! ==" + RESET); System.out.println("πŸŽ‰ You are the Hero of the Realm!"); } else { System.out.println(RED + "\n==== πŸ’€ You have been slain by the Dragon! ====" + RESET); } } private int getIntInput(String prompt) { System.out.print(prompt); while (!scanner.hasNextInt()) { System.out.println("⚠️ Please enter a valid number!"); scanner.next(); System.out.print(prompt); } return scanner.nextInt(); } }