import java.util.Random; import java.util.ArrayList; public class Pokemon { private String name; private int healthPoints; private int maxHealthPoints; private int strength; private double criticalChance; private Random random; private int catchRate; private int exp; private int level; private int fleeCount; public Pokemon(String name) { this.random = new Random(); this.name = name; this.healthPoints = 30 + random.nextInt(70); this.maxHealthPoints = this.healthPoints; this.criticalChance = Math.abs(0.1 * random.nextGaussian()); this.catchRate = (int)(Math.random() * 256); this.exp = 0; this.level = (int)(Math.abs(2 * random.nextGaussian()) + 1); this.strength = random.nextInt(7) + this.level; this.fleeCount = 0; } public Pokemon(String name, int healthPoints, int maxHealthPoints, int strength, double criticalChance, int catchRate, int exp, int level) { this.random = new Random(); this.name = name; this.healthPoints = healthPoints; this.maxHealthPoints = maxHealthPoints; this.criticalChance = criticalChance; this.catchRate = catchRate; this.exp = exp; this.level = level; this.strength = strength; this.fleeCount = 0; } public String toString() { return String.format("Level %d %s HP: (%d/%d) STR: %d CHC: %.0f%%", this.level, this.name, this.healthPoints, this.maxHealthPoints, this.strength, (this.criticalChance*100)); } /** * Returns a string containing all the pokemon's data. */ public String saveString() { return String.format("%s;%d;%d;%d;%f;%d;%d;%d", this.name, this.healthPoints, this.maxHealthPoints, this.strength, this.criticalChance, this.catchRate, this.exp, this.level); } public String getName() { return this.name; } public int getHP() { return this.healthPoints; } public boolean equals(Pokemon target) { return target == this; } /** * Heals a pokemon. * @param amount How many hitpoints to heal. * @return The exact amount of hitpoints healed. */ public int heal(int amount) { if (amount < 0) { amount = this.maxHealthPoints - this.healthPoints; } else { amount = Math.min(this.maxHealthPoints - this.healthPoints, amount); } this.healthPoints += amount; return amount; } /** * Checks if a pokemon has not taken any damage or is fully healed. * @param return True if health is full. False otherwise. */ public boolean isDamaged() { return this.healthPoints < this.maxHealthPoints; } /** * Tries to catch a pokemon. * @param current The list where the pokemon currently belongs. * @param catcher The list to send the pokemon on successfull capture. * @return True on successfull capture. False otherwise. */ public boolean tryCapture(ArrayList current, Trainer catcher, int range) { if (range == 0) { this.capture(current, catcher); System.out.printf("%s was caught.%n", this.name); return true; } if ((int)(Math.random() * (range + 1)) < Math.max((3 * this.maxHealthPoints - 2 * this.healthPoints) * this.catchRate / (3 * this.maxHealthPoints), 1)) { this.capture(current, catcher); System.out.printf("%s was caught.%n", this.name); return true; } else { System.out.printf("%s escaped from the pokeball.%n", this.name); return false; } } /** * Captures a wild pokemon. * @param current The pokemon list the pokemon belongs to. * @param catcher The pokemon list of the trainer. */ private void capture(ArrayList current, Trainer trainer) { trainer.addPokemon(this); for (int i = 0; i < current.size(); i++) { if (current.get(i) == this) { current.remove(i); } } } /** Restores the health of a fainted pokemon. */ public void revive() { this.healthPoints = this.maxHealthPoints; } /** * Checks if the pokemon has any HP left. * @return True if any HP is left. False otherwise. */ public boolean isConscious() { return this.healthPoints > 0; } /** * Damages a pokemon. * @param How many hitpoints are to be deducted. */ public void damage(int damageTaken) { this.healthPoints = Math.max(this.healthPoints -= damageTaken, 0); System.out.printf("%s takes %d damage and is left with %d/%d HP%n", this.name, damageTaken, this.healthPoints, this.maxHealthPoints); } /** * Gives a pokemon exp after each successfull battle. Also handles leveling up. * @target Which pokemon did we beat. */ private void giveEXP(Pokemon target) { int exp = (100 * target.level)/7; this.exp += exp; System.out.printf("%s gained %d exp.%n", this.name, exp); if (this.exp > (4 * Math.pow(this.level, 3)) / 5) { this.level++; this.maxHealthPoints += 5; this.healthPoints = maxHealthPoints; this.strength += 1; System.out.printf("%s is now level %d. Health has been increased and restored. Strength has been increased.%n", this.name, this.level); } } /** * Makes a pokemon attack another pokemon. * @param target The pokemon to take damage. */ public void attack(Pokemon target) { if (this.healthPoints > 0) { System.out.printf("%s attacks %s.%n", this.getName(), target.getName()); double critical = 1; if (Math.random() < this.criticalChance) { System.out.println("Critical hit!"); critical = (2 * this.level +5) / (this.level + 5); } double randomDouble = 0.85 + (1.0 - 0.85) * random.nextDouble(); int moveDamage = (int)(Math.random() * 60 + 40); int damageInflicted = this.level + (int)((((((2 * this.strength) / 5) + 2) * moveDamage * 1.75) / 50 + 2) * critical * randomDouble); target.damage(damageInflicted); if (!target.isConscious()) { System.out.printf("%s is defeated by %s.%n", target.getName(), this.getName()); this.giveEXP(target); this.fleeCount = 0; } } else { System.out.println("No cheating!"); } } /** * The trainer may flee if the battle is too hard. * @param target Who are we trying to flee from * @return True on successfull escape. False otherwise. */ public boolean flee(Pokemon target) { if (random.nextInt(256) < (this.level * 128 / target.level) + (30 * this.fleeCount % 256)) { this.fleeCount = 0; return true; } else { this.fleeCount++; return false; } } }