I started out practicing on implementing the builder pattern and somehow ended it up with this 2 hours later. It isn't really much, but it works and I'm hoping review should bring about a lot of insight.
I'm curious in pinpointing:
- Which part(s) are well executed? I've never done anything 'game' like so I have no idea what's a good idea and what isn't.
- Which part(s) could be considered poorly executed? I wanted to standardize the outputs and decreased repetition as best I could through method calls but I still get the feeling that a few things are redundant.
- General feedback on efficiency of the program. Particularly, little things, I'm wondering if it would make more sense to make Stringbuilder and use append instead of using string concatenation.
The Dragon class:
class Dragon {
int atk, def, hp, hpMax, mp, mpMax, exp, lvl;
String name;
Element element;
Race race = Race.DRAGON;
Dragon(Builder d) {
atk = d.atk; def = d.def; hp = d.hp; hpMax = d.hp;
mp = d.mp; mpMax = d.mp; lvl = d.lvl;
name = d.name; element = d.element;
}
static class Builder {
int atk = 0, def = 0, hp = 1, mp = 0, lvl = 1;
String name;
Element element = Element.NEUTRAL;
Builder(String name){ this.name = name; }
public Builder atk(int val){ atk = val; return this; }
public Builder def(int val){ def = val; return this; }
public Builder hp(int val){ hp = val; return this; }
public Builder mp(int val){ mp = val; return this; }
public Builder element(Element e){ element = e; return this;}
//You can't generate a dragon. A dragon is born!
public Dragon born(){ return new Dragon(this); }
}
public void addExperience(int exp){ this.exp += exp; }
public String getStatus() {
return this.name + " has " + this.atk + " attack " + this.def +
" defense " + this.mp + "/" + this.mpMax + " mana and " +
this.hp + "/" + this.hpMax + " health."
;
}
}
Element enum:
public enum Element {
LIGHT, DARK, FIRE, WATER, AIR, EARTH, NEUTRAL;
@Override
public String toString() {
return super.toString().substring(0, 1).toUpperCase() +
super.toString().substring(1).toLowerCase();
}
}
Race enum:
public enum Race {
DRAGON;
@Override
public String toString() {
return super.toString().substring(0, 1).toUpperCase() +
super.toString().substring(1).toLowerCase();
}
}
I haven't yet really implemented these two yet but I included them for the sake of completion.
Main:
import java.util.Scanner;
public class BattleSim {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("What is your name? ");
String name = input.nextLine();
Dragon player = new Dragon.Builder(name)
.atk(5).def(2).hp(25).mp(7).born();
Dragon challenger = new Dragon.Builder("Glaurung")
.atk(6).hp(15).born();
System.out.println("You are a Dragon.\n" +
"Not the order your underlings around 'big bad' that barely" +
" ever shows up kind" +
"but bonafide sky soaring, loot hoarding, city scorching Dragon."
);
System.out.println("\nWhile you were out being awesome another dragon " +
" stole your princess.\nYour damsel's in distress." +
" You 'gonna take that?"
);
battle(player, challenger);
System.out.println("Thanks for checking this out fellow CRers.");
}
public static int printBattleMenu() {
System.out.print("\nBattle menu\n1: Attack\n2: Defend " +
"\n3: Abilities\n4: Status\n5: Enemy Status\nEnter a choice: "
);
int selection = input.nextInt();
while (selection > 5 || selection < 1) {
System.out.print("Out of range. Enter a choice (1-5): ");
selection = input.nextInt();
}
return selection;
}
public static int printAbilityMenu() {
System.out.print("\nAbility menu\n1: Rage Claw - 2 mp" +
"\n2: Meditate - gain 3 mp\n3: Healing breath - 3 mp" +
"\n4: Back\nEnter a choice: "
);
int selection = input.nextInt();
while (selection > 5 || selection < 1) {
System.out.print("Out of range. Enter a choice (1-4): ");
selection = input.nextInt();
}
return selection;
}
public static void printBattleStatus(Dragon x, Dragon y) {
System.out.println(x.name + " has " + Math.max(0, x.hp) +
" health and the opposing " + y.name + " has " +
Math.max(0, y.hp) + " health remaining."
);
}
public static void battle(Dragon x, Dragon y){
int damageDealt, damageTaken, recoveryValue;
System.out.println("\t\t\tVS. " + y.name);
do {
switch(printBattleMenu()) {
case 1:
damageDealt = Math.max(0, x.atk - y.def);
damageTaken = Math.max(0, y.atk - x.def);
System.out.println(x.name + " deals " + damageDealt +
" damage and takes " + damageTaken + " damage."
);
x.hp -= damageTaken;
y.hp -= damageDealt;
// Print current status
printBattleStatus(x, y);
break;
case 2:
damageTaken = Math.max(0, y.atk - x.def * 2);
System.out.println(x.name + " takes a defensive stance and " +
" takes" + damageTaken + "damage."
);
printBattleStatus(x, y);
break;
case 3:
switch(printAbilityMenu()) {
case 1:
damageTaken = Math.max(0, y.atk - x.def);
if (x.mp < 2) {
System.out.println("Insufficient mana." +
"\nOpposing " + y.name + " took advantage of your" +
" foolishness to attack."
);
} else {
damageDealt = Math.max(0, x.atk * 2 - y.def);
x.mp -= 2;
System.out.println(x.name +
"'s claws are infused with mana!"
);
System.out.println(x.name + " deals " +
damageDealt + " damage and takes " +
damageTaken + " damage."
);
y.hp -= damageDealt;
}
x.hp -= damageTaken;
printBattleStatus(x, y);
break;
case 2:
damageTaken = Math.max(0, y.atk - x.def);
System.out.println(x.name +
" absorbs the mana of the land."
);
x.mp = Math.min(x.mpMax, x.mp + 3);
System.out.println(x.name + " takes " +
damageTaken + " damage."
);
x.hp -= damageTaken;
printBattleStatus(x, y);
break;
case 3:
damageTaken = Math.max(0, y.atk - x.def);
if (x.mp < 3) {
System.out.println("Insufficient mana." +
"\nOpposing " + y.name + " took advantage" +
" of your foolishness to attack."
);
} else {
recoveryValue = (int)Math.floor(x.hpMax * 0.3);
x.hp = Math.min(x.hpMax , x.hp + recoveryValue);
x.mp -= 3;
System.out.println(x.name + " recovers " +
recoveryValue + " health!"
);
}
x.hp -= damageTaken;
System.out.println(x.name + " takes " +
damageTaken + " damage."
);
printBattleStatus(x, y);
break;
case 4: // do nothing
break;
} // End of Ability Switch
break;
case 4:
System.out.println(x.getStatus());
break;
case 5:
System.out.println("Opposing " + y.getStatus());
break;
} // End of Selection Switch
} while(x.hp > 0 && y.hp > 0);
if (x.hp == y.hp){
System.out.println("It is a double K.O.");
} else if (x.hp > y.hp){
System.out.println(x.name + " is the victor!");
} else {
System.out.println(y.name + " has slain you!");
}
// setting values back to full
x.mp = x.mpMax;
x.hp = x.hpMax;
}
}