I'm making a program using java, and the particular issue I ran into was in the battle method, where the program runs into an error after all the enemies are defeated. I tried to alter it a couple time already, but unable to come up with a proper solution. The terminal states that the error is in the calculation of
**dmg = (skill[i][0] * charList.get(i).getSTR()) / enemyList.get(0).getDEF();**
I would apricate any ideas or suggestions anyone can provide.
Below is the method of my java code I'm having trouble with.
public static void battle(ArrayList<Characters> charList, String[] name, String[][] skillname, int[][] MPCost, double[][] skill,double[][] HPnMP, int enemynum, double[] enemyStats){
Scanner scanN = new Scanner (System.in);
DecimalFormat df = new DecimalFormat("0.0");
ArrayList<Enemies> enemyList = new ArrayList<>();
int battlechoice;
double dmg;
double EnemyHP;
for(int j = 0; j < enemynum; j++){
enemyList.add(new Enemies(enemyStats[0], enemyStats[1], enemyStats[2], enemyStats[3]));
}
System.out.println("Battle Start:");
while(!enemyList.isEmpty()){
for(int i = 0; i < charList.size(); i++){//for the characters turn so that they all go and then the enemies can go
if(HPnMP[i][0] <= 0) {
System.out.println(name[i] + " has been defeated!");
continue; // Skip turn for defeated character, and I found it on the following site: https://www.w3schools.com/java/java_break.asp
}
System.out.println("The current characters status is below. ");
DragonForce(charList, name, HPnMP, i);
System.out.println("Character: " + name[i]);
System.out.println("HP: " + df.format(HPnMP[i][0]) + "/" + charList.get(i).getHP());
System.out.println("MP: " + df.format(HPnMP[i][1]) + "/" + charList.get(i).getMP());
System.out.println("STR: " + charList.get(i).getSTR());
System.out.println("DEF: " + charList.get(i).getDEF());
System.out.println("1) Do a basic attack");
System.out.println("2) Use a skill");
System.out.println("3) Rest (recovers mana)");
battlechoice = scanN.nextInt();
switch(battlechoice){//switch used instead of for loop because its easier when its using int values and needs differing ouputs for each of them
case 1://this is a basic attack choice, simply dealing damage based on the strength value of the character and prints a corresponding message
dmg = charList.get(i).getSTR() - enemyList.get(0).getDEF();
EnemyHP = enemyList.get(0).getHP() - dmg;
if (dmg < 0) {
dmg = 0;
}
if(EnemyHP<=0){
enemyList.remove(0);
System.out.println("One enemy defeated!");
}
else{
System.out.println(name[i] + " dealt " + df.format(dmg) + " damage. The enemy has " +df.format(EnemyHP) + " HP left.");
enemyList.get(0).setHP(EnemyHP);
}
break;
case 2:
System.out.println("Select skill:");
System.out.println("1. " + skillname[i][0]);
System.out.println("2. " + skillname[i][1]);
int choice = scanN.nextInt();
if(choice == 1){
double MP = HPnMP[i][1] - MPCost[i][0];
if(MP >= 0){//if statement checks if there is enough mp to use the skill
HPnMP[i][1] = MP;//changes their mp value so they lost the amount used for their skill
dmg = (skill[i][0] * charList.get(i).getSTR()) / enemyList.get(0).getDEF();
if (dmg < 0) {
dmg = 0;
}
EnemyHP = enemyList.get(0).getHP() - dmg;//the index of 0 is used for the enemy so that there is always an enemy there, instead of putting in an index where there is no enemy object
CharHeal(charList, skill, HPnMP, i);//calls a method to heal a character if Wendy's healing gets used
if(EnemyHP<=0){//detects if an enemy had been killed
enemyList.remove(0);
System.out.println("One enemy defeated!");
}
else{//if an enemy is still alive, it displays an output of their current state
System.out.println(name[i] + " dealt " + df.format(dmg) + " damage. The enemy has " + df.format(EnemyHP) + " HP left.");
enemyList.get(0).setHP(EnemyHP);
}
}
else{//if they ran out of mana to use their skill
System.out.println(name[i] + " ran out of mana to use their skill.");
}
}
else{
double MP = HPnMP[i][1] - MPCost[i][1];
if(MP >= 0){//if statement checks if there is enough mp to use the skill
HPnMP[i][1] = MP;//changes their mp value so they lost the amount used for their skill
dmg = (skill[i][1] * charList.get(i).getSTR()) / enemyList.get(0).getDEF();
if(dmg<0){//in the case the def of the enemy is higher than the characters attack
dmg = 0;
}
EnemyHP = enemyList.get(0).getHP() - dmg;//the index of 0 is used for the enemy so that there is always an enemy there, instead of putting in an index where there is no enemy object
if(EnemyHP<=0){//detects if an enemy had been killed
enemyList.remove(0);
System.out.println("One enemy defeated!");
}
else{//if an enemy is still alive, it displays an output of their current state
System.out.println(name[i] + " dealt " + df.format(dmg) + " damage. The enemy has " + df.format(EnemyHP) + " HP left.");
enemyList.get(0).setHP(EnemyHP);
}
}
else{//if they ran out of mana to use their skill
System.out.println(name[i] + " ran out of mana to use their skill.");
}
}
break;
case 3://recovers the characters mana
HPnMP[i][1] = (charList.get(i).getMP() * 0.2) + HPnMP[i][1];
if(HPnMP[i][1] > charList.get(i).getMP()){
HPnMP[i][1] = charList.get(i).getMP();
}
System.out.println(name[i] + " has rested and as a result, their MP has increased to " + df.format(HPnMP[i][1]));
break;
default:
System.out.println("Not a valid option. The turn will be skipped.");
}
}
for (int i = 0; i < enemyList.size(); i++) {//the enemy's turn and the damage they deal
int charnum = (int)Math.floor(Math.random() * (charList.size() - 1 + 0) + 0);//randomly selects a character for the attack to target
dmg = enemyList.get(i).getSTR() - charList.get(charnum).getDEF();
if(dmg<0){
dmg = 0;
}
HPnMP[charnum][0] = charList.get(charnum).getHP() - dmg;
if(HPnMP[charnum][0]<= 0){
System.out.println(name[charnum] + " has been knocked out!");
}
else{
System.out.println("The enemy has dealt " + df.format(dmg) + " to " + name[charnum]);
System.out.println(name[charnum] + " now has " + df.format(HPnMP[charnum][0]) + " HP left.");
}
}
}
}
The problem arises if you have more than one player and the first player defeats all enemies. The loop over all the players still continues, but for the second player there is no enemy left which results in an exception when trying to access enemyList.get(0)
.
You need to change the loop over the players from
for(int i = 0; i < charList.size(); i++) {
//...
}
to
for(int i = 0; i < charList.size() && !enemyList.isEmpty(); i++) {
//...
}
so that it terminates if there are no enemies left.