Homework: Ultimate Battle


Scenario

You are programming a game where 2 objects of your choosing (e.g., Robots, Dinosaurs, People) battle. Each object has health and power.


Instructions

  1. Create a class representing your object with:

    Instance variables:

    • String name
    • int power
    • int health
    • MAKE YOUR OWN

    Static variables:

    • double fightDuration

    Instance methods:

    • void attack()
    • void printStatus()
    • MAKE YOUR OWN

    Class methods:

    • static int strongerFighter()
    • static void beginBattle()
    • MAKE YOUR OWN
  2. In main:

    • Create two objects.
    • Use instance methods to attack and print status.
    • Use static methods to compare, print a fact, and start the battle.
import java.util.Random;

class Fighter {
    // ==== Instance variables ====
    String name;
    int power;
    int health;
    int armor;          
    int wins = 0;       

    // ==== Static variables ====
    static double fightDuration = 0.0; 
    private static final Random RNG = new Random();

    private static Fighter challengerA;
    private static Fighter challengerB;

    Fighter(String name, int power, int health, int armor) {
        this.name = name;
        this.power = power;
        this.health = health;
        this.armor = armor;
    }

    // ==== Instance methods ====
    void attack() {
        int gain = 1 + RNG.nextInt(2); // +1 to +2 power
        power += gain;
        System.out.printf("%s charges up! Power +%d (now %d)%n", name, gain, power);
    }

    void attack(Fighter target) {
        if (this == target) {
            System.out.println("Don't attack yourself");
            return;
        }
        int variance = RNG.nextInt(3) - 1; 
        boolean crit = RNG.nextDouble() < 0.15;
        int raw = power + variance;
        if (crit) raw += 2;
        int damage = Math.max(1, raw - target.armor);
        target.health = Math.max(0, target.health - damage);

        System.out.printf(
            "%s strikes %s for %d damage%s (target armor %d). %s health: %d%n",
            name, target.name, damage, crit ? " [CRIT!]" : "", target.armor, target.name, target.health
        );
    }

    void printStatus() {
        System.out.printf(
            "[%s] Health: %d | Power: %d | Armor: %d | Wins: %d%n",
            name, health, power, armor, wins
        );
    }

    boolean isAlive() {
        return health > 0;
    }

    void heal(int amount) {
        health += amount;
        System.out.printf("%s heals %d. Health now %d%n", name, amount, health);
    }

    void taunt(String line) {
        System.out.printf("%s: \"%s\"%n", name, line);
    }

    // ==== Class (static) methods ====
    static void registerChallengers(Fighter a, Fighter b) {
        challengerA = a;
        challengerB = b;
        System.out.printf("Challengers registered: %s vs %s%n", a.name, b.name);
    }

    static int strongerFighter() {
        ensureChallengers();
        if (challengerA.power > challengerB.power) return 1;
        if (challengerA.power < challengerB.power) return -1;
        return Integer.compare(challengerA.health, challengerB.health);
    }

    static void beginBattle() {
        ensureChallengers();
        System.out.println("\n=== BATTLE BEGINS ===");
        long start = System.nanoTime();

        Fighter a = challengerA;
        Fighter b = challengerB;

        boolean aTurn = RNG.nextBoolean();
        System.out.printf("Initiative: %s goes first.%n", aTurn ? a.name : b.name);

        int round = 1;
        while (a.isAlive() && b.isAlive()) {
            System.out.printf("\n-- Round %d --%n", round++);
            if (aTurn) {
                a.attack(b);
                if (b.isAlive()) b.attack(a);
            } else {
                b.attack(a);
                if (a.isAlive()) a.attack(b);
            }
            // small chance both "catch their breath"
            if (RNG.nextDouble() < 0.10) {
                System.out.println("Both fighters catch their breath (+1 health).");
                a.health += 1;
                b.health += 1;
            }
            aTurn = !aTurn;
        }

        long end = System.nanoTime();
        fightDuration = (end - start) / 1_000_000_000.0;

        Fighter winner = a.isAlive() ? a : b;
        winner.wins++;

        System.out.printf(
            "%n=== BATTLE OVER ===%nWinner: %s  |  Fight Duration: %.3f s%n",
            winner.name, fightDuration
        );
        System.out.println("Final status:");
        a.printStatus();
        b.printStatus();
    }

    static void printArenaFact() {
        System.out.println("Arena Fact: Critical hits are 15% likely and add +2 damage before armor.");
    }

    private static void ensureChallengers() {
        if (challengerA == null || challengerB == null) {
            throw new IllegalStateException(
                "No challengers registered. Call Fighter.registerChallengers(a, b) first."
            );
        }
    }
}

public class Battle {
    public static void main(String[] args) {
        // Create two fighters
        Fighter alpha = new Fighter("Dino", 7, 20, 2);
        Fighter beta  = new Fighter("Robot", 6, 24, 3);

        System.out.println("Initial status:");
        alpha.printStatus();
        beta.printStatus();

        System.out.println("\nSome pre-fight skirmishing with instance methods:");
        alpha.taunt("Sharp claws, sharper wit!");
        beta.taunt("Stone never breaks.");
        alpha.attack();            // charge up (no-arg version)
        alpha.attack(beta);        // actual attack on target
        beta.heal(2);              // patch up a bit
        beta.attack(alpha);
        alpha.printStatus();
        beta.printStatus();

        // Register fighters for static methods
        Fighter.registerChallengers(alpha, beta);

        // Use static method to compare strength
        int cmp = Fighter.strongerFighter();
        if (cmp > 0) {
            System.out.println("\nStronger fighter (by power, health tiebreaker): " + alpha.name);
        } else if (cmp < 0) {
            System.out.println("\nStronger fighter (by power, health tiebreaker): " + beta.name);
        } else {
            System.out.println("\nStronger fighter: It's an exact tie!");
        }

        // Print a class fact (another static method)
        Fighter.printArenaFact();

        // Start the battle (static, parameterless)
        Fighter.beginBattle();

        // Show the recorded static fight duration
        System.out.printf("%nRecorded fightDuration (seconds): %.3f%n", Fighter.fightDuration);
    }
}