I'm developing a RPG game and being blocked by the settings of HP(hit points/health points/health power), attack and defense for the characters - Assassin, Tank and Warrior
I'd like to figure out the values so that the Assassin is guaranteed to defeat the Warrior, meanwhile, the Warrior is guaranteed to defeat the Tank whereas the Tank is guaranteed to defeat the Assassin.
So, I wrote a lab to solve this puzzle.
Here is part of Character.java
, the rest of it are just auto generated setters and getters.
private int maxHp, hp, attack, defense, level;
private int place, xp, gold;
private String name;
public void setHp(int hp) {
if (hp>maxHp){
this.hp = maxHp;
} else {
if(hp<0){
this.hp = 0;
} else {
this.hp = hp;
}
}
}
public Character(String name, int maxHp, int attack, int defense){
this(name, maxHp, attack, defense, 0, 0, 1);
}
public Character(String name, int maxHp, int attack, int defense, int xp, int gold, int level) {
// super(); // Is it necessary to call super() here?
this.name = name;
this.maxHp = maxHp;
this.hp = maxHp;
this.attack = attack;
this.defense = defense;
this.xp = xp;
this.gold = gold;
this.level = level;
}
public String toString(){
return name + "'s maxHP: " + maxHp + " Attack: " + attack + " Defense: " + defense;
}
The Util
class is just a shorthand for System.out.println()
public class Util {
public static void pln(){
System.out.println();
}
public static void pln(Object obj) {
System.out.println(obj);
}
public static void pln(int value) {
System.out.println(value);
}
}
LabMain does the calculation which contains a multi-layer loop.
class LabMain {
final static int MINHP = 1;
final static int MAXHP = 100;
final static int MINATTACK = 1;
final static int MINDEFENSE = 0;
public static boolean isBattleFinished(Character player, Character opponent,
int dmgDealt, int dmgTook) {
// the player will never win
// as they cannot deal any damage to their opponent
if (dmgDealt <= 0) {
player.setHp(0);
return true;
}
if (dmgTook < 0)
dmgTook = 0;
opponent.setHp(opponent.getHp() - dmgDealt);
player.setHp(player.getHp() - dmgTook);
if (player.getHp() <= 0) {
return true;
} else if (opponent.getHp() <= 0) {
return true;
}
return false;
}
public static int didTheyWin(Character player, Character opponent){
int dmgDealt = player.getAttack() - opponent.getDefense();
int dmgTook = opponent.getAttack() - player.getDefense();
int round = 0;
boolean isFinished = true;
do {
round++;
isFinished = isBattleFinished(player, opponent, dmgDealt, dmgTook);
} while (round<MAXHP && !isFinished);
if (player.getHp() > 0) {
return round;
}
return 0;
}
static void lab() {
for(int assassinMaxHP = MINHP; assassinMaxHP < MAXHP; assassinMaxHP+=MINHP){
Util.pln("assassinMaxHP: " + assassinMaxHP);
for(int assassinAttack = MINATTACK; assassinAttack < MAXHP; assassinAttack+=MINHP){
for(int assassinDefense = MINDEFENSE; assassinDefense < MAXHP; assassinDefense+=MINHP){
Util.pln("assassinDefense: " + assassinDefense);
for(int warriorMaxHP = MINHP; warriorMaxHP < MAXHP; warriorMaxHP+=MINHP){
Util.pln("warriorMaxHP: " + warriorMaxHP);
for(int warriorAttack = MINATTACK; warriorAttack < MAXHP; warriorAttack+=MINHP){
Util.pln( "assassinAttack: " + assassinAttack +
" assassinDefense:" + assassinDefense +
" warriorMaxHP: " + warriorMaxHP +
" warriorAttack: " + warriorAttack);
for(int warriorDefense = MINDEFENSE; warriorDefense < MAXHP; warriorDefense+=MINHP){
for(int tankMaxHP = MINHP; tankMaxHP < MAXHP; tankMaxHP+=MINHP){
for(int tankAttack = MINATTACK; tankAttack < MAXHP; tankAttack+=MINHP){
for(int tankDefense = MINDEFENSE; tankDefense < MAXHP; tankDefense+=MINHP){
Character assassin1 = new Character("A", assassinMaxHP, assassinAttack, assassinDefense);
Character warrior1 = new Character("W", warriorMaxHP, warriorAttack, warriorDefense);
if(didTheyWin(assassin1, warrior1)>0){
Character warrior2 = new Character("W", warriorMaxHP, warriorAttack, warriorDefense);
Character tank2 = new Character("T", tankMaxHP, tankAttack, tankDefense);
if(didTheyWin(warrior2, tank2)>0){
Character tank3 = new Character("T", tankMaxHP, tankAttack, tankDefense);
Character assassin3 = new Character("A", assassinMaxHP, assassinAttack, assassinDefense);
if(didTheyWin(tank3, assassin3)>0){
Util.pln("- - -");
Util.pln(assassin1);
Util.pln(warrior1);
Util.pln(tank2);
Util.pln("- - -");
System.exit(0);
}
}
}
}
}
}
}
}
}
}
}
}
}
public static void main(String[] args) {
lab();
}
}
I put the full code on https://github.com/albert10jp/javamud
Here is the first finding
A's maxHP: 1 Attack: 1 Defense: 1
W's maxHP: 5 Attack: 1 Defense: 0
T's maxHP: 2 Attack: 2 Defense: 0
Although W is more like the Tank whereas T is more like the Warrior :)
Please ignore the bunch of Util.pln
inside lab()
temporarily which is just an indicator to tell me my code is not in an infinite loop and I'm woking on improving it.
Questions:
1.Is there a more elegant way that I don't have to do so many layers of loops?
2.Is it necessary to call super()
in the constructor of Character
?
Any other comments and suggestions are also appreciated.