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 Main { // Colors private static final String RESET = "\u001B[0m"; // Reset ANSI code private static final String RED = "\u001B[31m"; private static final String GREEN = "\u001B[32m"; private static final String YELLOW = "\u001B[33m"; private static final String BLUE = "\u001B[34m"; private static final String PURPLE = "\u001B[35m"; private static final String LIGHT_GRAY = "\u001B[37m"; private static boolean gameRunning = true; static List locations = new ArrayList<>(); public static void main(String[] args) { // Scanner Scanner scanner = new Scanner(System.in); Random random = new Random(); // for initial location Location castle = new Location("Castle", new Dragon()); Location forest = new Location("Forest"); Location ruins = new Location("Ruins"); Location village = new Location("Village"); locations.add(forest); locations.add(ruins); locations.add(village); locations.add(castle); // Main loop boolean isRunning = true; while (isRunning){ System.out.println(YELLOW + "------------------Legend of AP------------------" + RESET); System.out.println(" Choose your option :"); System.out.println(BLUE + " 1." + RESET + " Start a new game"); System.out.println(BLUE + " 2." + RESET + " Exit"); int option = scanner.nextInt(); switch (option){ case 1: startNewGame(scanner, random); break; case 2: System.out.println("Goodbye!"); isRunning = false; break; default: continue; } } } public static void startNewGame(Scanner scanner, Random random){ Player player; int randNum1 = random.nextInt(3); // used for random initial location. System.out.println("Enter your name : "); String name = scanner.next(); Location currentLocation = locations.get(randNum1); int charOption = 0; while ( (charOption <= 0) || (charOption >= 4)) { System.out.println("Choose your character :"); System.out.println(BLUE + " 1." + RESET + " Knight"); System.out.println(BLUE + " 2." + RESET + " Assassin (it has a cool" + GREEN + " green" + RESET + " light saber!)"); System.out.println(BLUE + " 3." + RESET + " Wizard"); charOption = scanner.nextInt(); } player = switch (charOption) { case 1 -> new Knight(name); case 2 -> new Assassin(name); case 3 -> new Wizard(name); default -> null; }; // Resetting running flag gameRunning = true; System.out.println("Going to : " + GREEN + currentLocation.getName() + RESET); spawnRandomEnemy(currentLocation,random); while (gameRunning && !player.isDead()){ int choice = miniMenu(currentLocation,player); switch (choice){ case 1: if (currentLocation.hasEnemy()) { fight(player, currentLocation.getEnemy(), currentLocation); if (!player.isDead() && !currentLocation.hasEnemy()) { // gain XP and recover player.gainXP(100); player.fullRestore(); System.out.println(GREEN + "HP and MP restored." + RESET); // spawn a new enemy spawnRandomEnemy(currentLocation, random); } } break; case 2: currentLocation = moveToLocation(scanner, currentLocation, player); if (!currentLocation.hasEnemy()) { spawnRandomEnemy(currentLocation, random); } System.out.println(GREEN + "Arrived at: " + currentLocation.getName() + RESET); break; case 3: if (player.hasAllKeys()){ currentLocation = locations.get(3); System.out.println(PURPLE + "--DRAGON FIGHT--" + RESET); Enemy dragon = new Dragon(); fight(player,dragon,currentLocation); if (dragon.isDead()){ System.out.println(YELLOW + "VICTORY!" + RESET); System.out.println("Level : " + player.getLevel()); gameRunning = false; } }else { System.out.println("Locked !"); } break; } } } public static int miniMenu(Location loc,Player player){ boolean castleUnLocked = player.hasGoblinKey() && player.hasSkelKey() && player.hasVampKey(); Scanner scanner = new Scanner(System.in); int chosenOpt = 0; while (chosenOpt <= 0 || chosenOpt >= 4){ System.out.println("Choose an option : "); System.out.println(BLUE + " 1." + RESET + " Stay at " + loc.getName() + " and fight with " + loc.getEnemy().getName()); System.out.println(BLUE + " 2." + RESET + " Move to another place"); if (castleUnLocked){ System.out.println(BLUE + " 3." + PURPLE + " Go to castle and fight with the dragon" + RESET); } else { System.out.println(" \uD83D\uDD12" + LIGHT_GRAY + "3. Go to castle and fight with the dragon" + RESET); } chosenOpt = scanner.nextInt(); } return chosenOpt; } private static void spawnRandomEnemy(Location location, Random random) { int enemyType = random.nextInt(3); switch (enemyType){ case 0: location.setEnemy(new Vampire()); System.out.println("A " + RED + "Vampire" + RESET + " Spawned !"); break; case 1: location.setEnemy(new Skeleton()); System.out.println("A Skeleton Spawned !"); break; case 2: location.setEnemy(new Goblin()); System.out.println("A " + GREEN + "Goblin" + RESET + " Spawned !"); break; } } private static Location moveToLocation(Scanner scanner, Location current, Player player) { int choice = -1; do { System.out.println("Choose a location to move to:"); for (int i = 0; i < locations.size(); i++) { String prefix = locations.get(i).equals(current) ? " * " : " "; System.out.println(BLUE + " " + (i + 1) + "." + RESET + " " + prefix + locations.get(i).getName()); } choice = scanner.nextInt() - 1; if (choice == 3 && !player.hasAllKeys()){ System.out.println("Locked!"); choice = -1; } } while (choice < 0 || choice >= locations.size()); return locations.get(choice); } private static void fight(Player player, Enemy enemy, Location location) { System.out.println(RED + " COMBAT STARTED!" + RESET); while (!player.isDead() && !enemy.isDead()) { // Player turn playerTurn(player, enemy); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } // Enemy turn if (!enemy.isStunned()) { enemyTurn(player, enemy); } else { System.out.println(BLUE + enemy.getName() + RESET + " is stunned. skipping to player..."); enemy.stun(false); } } if (player.isDead()){ System.out.println("Game over."); System.out.println("Level : " + player.getLevel()); gameRunning = false; } else if (enemy.isDead()) { System.out.println(player.getName() + RED + " Killed " + "a " + RESET + enemy.getName() + " at " + GREEN + location.getName() + RESET); keyMechanic(player,enemy); location.clearEnemy(); } } private static void playerTurn(Player player, Enemy enemy) { Scanner scanner = new Scanner(System.in); System.out.println("\n" + BLUE + "Your Turn:" + RESET); System.out.println(RED + "HP : " + RESET + player.getHp() + "/" + player.getMaxHP() + GREEN + " | MP: " + RESET + player.getMp() + "/" + player.getMaxMP()); System.out.println(BLUE + " 1." + RESET + " Light Attack " + GREEN + "(0 MP)" + RESET); System.out.println(BLUE + " 2." + RESET + " Heavy Attack " + GREEN + "(-" + player.getWeapon().getManaCost() + " MP)" + RESET); System.out.println(BLUE + " 3." + RESET + " Defend " + GREEN + "(-5 MP)" + RESET); System.out.println(BLUE + " 4." + RESET + " Heal " + GREEN + "(-10 MP)" + RESET); System.out.println(BLUE + " 5." + RESET + " Special Ability " + GREEN + "(-" + player.specialAblMPCost() + " MP)" + RESET); int choice; do { choice = scanner.nextInt(); } while (choice <= 0 || choice >= 6); switch (choice) { case 1: player.lightAttack(enemy); break; case 2: if (player.getMp() >= player.getWeapon().getManaCost()) { player.heavyAttack(enemy); } else { System.out.println(RED + "Not enough MP!, light attacking." + RESET); player.lightAttack(enemy); } break; case 3: player.defend(); break; case 4: if (player.getMp() >= 10) { player.heal(30); } else { System.out.println(RED + "Not enough MP!" + RESET); } break; case 5: if (player.getMp() >= player.specialAblMPCost()) { player.specialAbility(enemy); } else { System.out.println(RED + "Not enough MP!" + RESET); } break; } System.out.println(RED + "HP : " + RESET + player.getHp() + "/" + player.getMaxHP() + GREEN + " | MP: " + RESET + player.getMp() + "/" + player.getMaxMP()); System.out.println(RED + "Enemy's HP : " + RESET + enemy.getHp()); } private static void enemyTurn(Player player,Enemy enemy) { System.out.println(RED + "\n" + enemy.getName() + "'s Turn:" + RESET); // randomly choosing between attack and specialAbility with probability of 1/3 Random random = new Random(); if (random.nextInt(3) == 0) { enemy.specialAbility(player); } else { enemy.attack(player); } System.out.println(RED + "Your HP : " + RESET + player.getHp() + "/" + player.getMaxHP()); } private static void keyMechanic(Player player, Enemy enemy){ Random random = new Random(); if (enemy instanceof Goblin){ if (player.hasGoblinKey()) return; if (random.nextInt(3) == 0) player.gotGoblinKey(); } else if (enemy instanceof Vampire){ if (player.hasVampKey()) return; if (random.nextInt(3) == 0) player.gotVampKey(); } else if (enemy instanceof Skeleton) { if (player.hasSkelKey()) return; if (random.nextInt(3) == 0) player.gotSkelKey(); } } }