Files
HW-04-JAVA-KNIGHT-farnam/Java-Knight/src/main/java/org/project/Main.java
T

333 lines
12 KiB
Java

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<Location> 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();
}
}
}