if (next.Doomed) { if (next.centity.entity.getWeight() <= 30) { result += .5*next.getUtility() - next.damage;
if (next.inDanger) { if (next.Doomed) { if (next.centity.last != null && next.centity.last.Doomed) { result -= next.damage - .5*next.getUtility(); } else if (next.centity.last != null && !next.centity.last.Doomed) { result += next.getUtility() + 2*next.damage; } else { result += next.getUtility(); }
  protected double getFitness(int iChromIndex) {    ChromVector chromVector = (ChromVector)this.chromosomes[iChromIndex];    Vector possible = new Vector();    for (int iGene=0; iGene < chromosomeDim; iGene++) {      possible.add(new EntityState(((EntityState[])this.moves.elementAt(iGene))[chromVector.genes[iGene]]));    }    Object[] move_array = possible.toArray();    for (int e = 0; e < enemy_array.length; e++) { // for each enemy      EntityState max = (EntityState)move_array[0];      int targets = 0;      for(int m = 1; m < move_array.length; m++) {        if (((EntityState)move_array[m]).threats[e] > max.threats[e]) {          max = (EntityState)move_array[m];        }      }      for(int m = 1; m < move_array.length; m++) {        EntityState next = (EntityState)move_array[m];        if (next.threats[e] > 0) {          if (next.threats[e] < .25*max.threats[e]) {            next.threats[e] = 0;          } else {            next.threats[e] = Math.pow(next.threats[e]/max.threats[e],2)*next.threats[e];          }        }      }    }    //total damage delt, and rescaling of threat    double damages[] = new double[enemy_array.length];    for(int m = 0; m < move_array.length; m++) {      EntityState next = (EntityState)move_array[m];      next.threat = 0;      for (int e = 0; e < enemy_array.length; e++) {        next.threat += next.threats[e];        damages[e] = (next.min_damages[e] + next.damages[e])/2;      }    }    //sacrificial lamb check    double result = 0;    for(int m = 0; m < move_array.length; m++) {      EntityState next = (EntityState)move_array[m];      if (((EntityState[])moves.elementAt(m)).length > 1) {        EntityState min = (EntityState)((EntityState[])moves.elementAt(m))[0];        if (min.damage > 2*next.damage && min.getUtility() < .5*next.getUtility()) {          result += next.centity.bv; //it is being endangered in the future          if (m > 0) chromVector.genes[m]--; //go so far as to mutate the gene        }      }    }    int difference = this.tb.NumEnemies - this.tb.NumFriends;    double distance_mod = 0;    //if outnumbered and loosing, clump together.    try {      int target_distance = Math.max(8 - difference, 1);      for(int m = 0; m < move_array.length; m++) {        EntityState next = (EntityState)move_array[m];        next.getUtility();        for(int j = 0; j < move_array.length; j++) {          EntityState other = (EntityState)move_array[j];          if (m != j) {            int distance = other.curPos.distance(next.curPos);            if (distance > target_distance) {              distance_mod += Math.pow(distance - target_distance, 2);            } else if (distance <= 3) {              boolean swarm = false;              CEntity target = null;              int target_index = 0;              for (int e = 0; e < enemy_array.length; e++) {                CEntity cen = tb.enemies.get((Entity)this.enemy_array[e]);                if (!cen.canMove()) {                  if ((cen.old.curPos.distance(next.curPos) == 1 && cen.old.curPos.distance(other.curPos) == 1)                    || (cen.old.curPos.distance(next.curPos) <= 3 && cen.old.curPos.distance(other.curPos) <= 3 && cen.old.isProne)  && !(next.inDanger || next.isProne)) {                    swarm = true;                    target = cen;                    target_index = e;                  }                }              }              if (swarm) {                if (target.entity.isProne()) {                  distance_mod -= target.bv/100;                }                distance_mod -= target.bv/50;                next.damages[target_index] *= 1.2;              }            }          }        }      }    } catch (Exception e) {      e.printStackTrace();    }    int max_e = 0;    double max = 0;    //bonuses for endangering or dooming opponent mechs    for (int e = 0; e < enemy_array.length; e++) {      CEntity cen = tb.enemies.get((Entity)this.enemy_array[e]);      if (damages[e] > cen.avg_armor) {        if (damages[e] > 4*cen.avg_armor) {          max += cen.bv/5; //likely to die        } else {          max += cen.bv/50; //in danger        }      } else if (damages[e] > 40) {        max += (1 - cen.base_psr_odds)*cen.entity.getWeight();      }    }    //if noone is in danger at least give a bonus for clustering    if (max == 0) {      for (int e = 0; e < enemy_array.length; e++) {        if (damages[e] > max) {          max = damages[e];        }      }    }    distance_mod /= move_array.length*move_array.length;    //less of a pull as you make moves    distance_mod *= this.tb.my_mechs_moved/this.tb.NumFriends;        for(int m = 0; m < move_array.length; m++) {      EntityState next = (EntityState)move_array[m];      if (next.Doomed) {        if (next.centity.entity.getWeight() <= 30) {          result += .5*next.getUtility() - next.damage;        } else {          result += next.getUtility();        }      } else {        result += next.getUtility();      }    }    return -result + (max - distance_mod);  }