# Java Knight ⚔️ A turn-based, roguelike-inspired RPG that runs entirely in the terminal, written in Java for the fourth Advanced Programming assignment. > *For centuries, the land of Javanest lived in peace, until a magical Dragon > plunged it into darkness, cursing its people into monsters and scattering the > three keys to its lair among them. Battle the cursed creatures, recover the > Goblin, Skeleton and Vampire keys, grow strong, and slay the Dragon to break > the curse and restore peace to Javanest!* --- ## Table of Contents 1. [How to Compile & Run](#how-to-compile--run) 2. [How to Play](#how-to-play) 3. [Classes, Enemies & Stats](#classes-enemies--stats) 4. [Project Structure](#project-structure) 5. [OOP Principles Used](#oop-principles-used) 6. [Bonus Features](#bonus-features) --- ## How to Compile & Run The project is a standard Maven project. You need **JDK 21+** installed. ### Using Maven (recommended) ```bash cd Java-Knight mvn compile mvn exec:java -Dexec.mainClass=org.project.Main ``` ### Using plain `javac` / `java` ```bash cd Java-Knight # compile every source file into the target/classes folder find src/main/java -name "*.java" > sources.txt javac -d target/classes @sources.txt # run it java -cp target/classes org.project.Main ``` > The game uses ANSI colour codes, so run it in a real terminal (macOS Terminal, > Linux shell, Windows Terminal) for the intended colourful output. --- ## How to Play 1. **Name your hero** and **pick a class** (Knight, Wizard, or Assassin). 2. You wander into a random **location** and a random standard enemy appears. For each encounter you choose: - **1. Fight** – enter turn-based combat. - **2. Move** – skip this enemy and travel somewhere new. - **3. Visit the Merchant** – spend coins on potions, a weapon, or repairs. - **4. Go to the Castle** – *only appears once you hold all 3 keys* – fight the Dragon. 3. **Combat is turn-based.** On your turn you pick one of five actions. Only **Light Attack** is free; the rest cost Mana/Stamina, and the class **Special** costs the most. If you run out of Mana, you can still Light Attack. | # | Action | Cost | Effect | |---|---------------|-----------|--------| | 1 | Light Attack | 0 | Moderate damage | | 2 | Heavy Attack | 8 | Double damage | | 3 | Defend | 6 | Blocks ~75% of the next hit | | 4 | Heal | 12 | Restores 40% of max HP | | 5 | Special | 15 | Unique class ultimate | | 6 | Use Item | – | Drink a potion from your inventory | 4. **Winning a fight** grants **XP** (scaled to the enemy's power), **coins**, and a chance to drop that species' **key**. Your HP and Mana are then fully restored. 5. **Leveling up** automatically raises your Max HP, Max Mana and base damage. 6. Collect **all 3 keys**, go to the Castle, and defeat the **Dragon** to win. Dying at any point is **Game Over**. --- ## Classes, Enemies & Stats ### Player Classes Each class has deliberately different starting stats, so they play differently. | Class | HP | Mana | Base Dmg | Weapon | Special ability | |------------|----|------|----------|-------------|-----------------| | **Knight** ⚔️ | 50 | 40 | **8 (highest)** | Iron Sword | **Shield Bash** – heavy damage + stuns the enemy (skips its next turn) | | **Wizard** 🧙 | **65 (highest)** | 45 | 5 | Oak Staff | **Arcane Blast** – heavy damage AND heals the caster | | **Assassin** 🗡️ | 45 | **55 (highest)** | 6 | Twin Dagger | **Vanish** – dodges the next attack + guarantees a crit on the next strike | ### Enemies | Enemy | HP | Ability | Key | |------------|-----|---------|-----| | **Goblin** 👹 | 30 | 40% chance to land a **critical hit** (double damage) | Goblin Key | | **Skeleton** ☠️ | 40 | **Resurrects once** per battle at 50% HP | Skeleton Key | | **Vampire** 🦇 | 48 | **Lifesteal** – heals for 50% of the damage it deals | Vampire Key | | **Dragon** 🐉 | 160 | **True damage** – fiery breath ignores armor *and* the Defend stance | — | Standard enemies each have a **25% chance** to drop their key, and only **one key per species** can ever drop (once you have the Goblin Key, no other Goblin will drop one). --- ## Project Structure ``` org.project ├── Main.java // entry point – builds the world, starts the game ├── Game.java // the game controller / main loop ├── Merchant.java // bonus shop system ├── entity │ ├── Entity.java // interface every combatant implements │ ├── players │ │ ├── ICombatActions.java // interface: the 5 required actions │ │ ├── Player.java // abstract base for all heroes │ │ ├── Knight.java / Wizard.java / Assassin.java │ └── enemies │ ├── Enemy.java // abstract base for all monsters │ ├── KeyType.java // enum of the three keys │ ├── Goblin.java / Skeleton.java / Vampire.java / Dragon.java ├── item │ ├── Item.java // interface for anything ownable/sellable │ ├── weapons (Weapon abstract → Sword, Dagger, Staff, GreatAxe) │ ├── armors (Armor abstract → KnightArmor, LeatherArmor, Robe) │ └── consumables (Consumable abstract → Flask, ManaPotion) ├── location │ └── Location.java // a place that spawns random enemies └── util ├── ConsoleColors.java // ANSI colour helpers └── Dice.java // random-number helpers ``` --- ## OOP Principles Used This project was designed around the seven principles the assignment asks for: - **Encapsulation** – all fields are `private`/`protected` with getters. HP, Mana and XP can only be changed through methods like `takeDamage`, `heal` and `gainXP`, which enforce their own rules (clamping to max, capping at zero, leveling up). - **Inheritance** – shared logic lives in abstract base classes so it isn't duplicated. `Player` holds the HP/Mana bars, leveling, inventory and four of the five actions; `Knight`, `Wizard` and `Assassin` only add what's unique. Same idea for `Enemy` → its four monster subclasses, and for `Weapon`/`Armor`/`Consumable` → their concrete items. - **Interfaces** – `Entity` is the contract every combatant obeys, which is what lets the combat loop treat a Knight and a Dragon identically. `ICombatActions` guarantees every player class implements exactly the five required actions. `Item` unifies weapons, armor and consumables so the merchant can sell any of them. - **Abstract classes** – `Player`, `Enemy`, `Weapon`, `Armor` and `Consumable` are all abstract: they provide shared state/behaviour but can't be instantiated on their own, forcing subclasses to fill in the specifics (e.g. `Player.specialAbility` is abstract). - **Polymorphism** – the whole game loop is polymorphic. `Game` only ever calls `Player`/`Enemy`/`Entity` methods; the correct `specialAbility`, `attack` or `takeDamage` runs depending on the real object. Each enemy overrides `attack` to add its signature move. - **Overriding** – subclasses override base behaviour, e.g. `Skeleton` overrides `takeDamage` to resurrect, `Vampire`/`Goblin`/`Dragon` override `attack`, and every player class overrides `specialAbility`. - **Overloading** – `takeDamage(int)` vs `takeDamage(int, boolean)` in `Player`. The second, overloaded version ignores defenses and is how the Dragon's breath bypasses armor and shields. The `Sword` also overloads its constructor. --- ## Bonus Features - **Coins & Merchant system** – enemies drop coins; the Merchant sells Health Flasks, Mana Potions, a stronger **Great Axe**, and can **repair** armor. - **Inventory & consumables** – potions can be bought, stored and used mid-combat (action 6). - **Durable armor** – armor loses durability as it absorbs hits and eventually breaks, until repaired at the merchant. - **Colourful narrative console** – ANSI colours (red for damage, blue for mana, green for healing) make the combat log easy to read. --- *Born of God and Void. You shall seal the blinding light that plagues their dreams. You are the Vessel. You are the Java Knight.*