Vector<Entity> valid_attackers;
deployed_ent = getEntity(game.getFirstDeployableEntityNum());
WeaponAttackAction test_attack;
// Create array of hexes in the deployment zone that can be deployed to
// Check for prohibited terrain, stacking limits
switch (getLocalPlayer().getStartingPos()) {
case 1:
case 3:
case 5:
case 7:
valid_array = new Coords[(3 * game.getBoard().getWidth())
+ (3 * game.getBoard().getHeight()) - 9];
// fitness = new
// double[(3*game.getBoard().getWidth())+(3*game.getBoard().getHeight())-9];
break;
case 2:
case 6:
valid_array = new Coords[game.getBoard().getWidth() * 3];
// fitness = new double[game.getBoard().getWidth()*3];
break;
case 4:
case 8:
valid_array = new Coords[game.getBoard().getHeight() * 3];
// fitness = new double[game.getBoard().getHeight()*3];
break;
case 0:
default:
valid_array = new Coords[game.getBoard().getWidth()
* game.getBoard().getHeight()];
// fitness = new
// double[game.getBoard().getWidth()*game.getBoard().getHeight()];
break;
}
counter = 0;
for (test_x = 0; test_x <= game.getBoard().getWidth(); test_x++) {
for (test_y = 0; test_y <= game.getBoard().getHeight(); test_y++) {
test_hex.x = test_x;
test_hex.y = test_y;
if (game.getBoard().isLegalDeployment(test_hex,
getLocalPlayer())) {
if (!deployed_ent.isHexProhibited(game.getBoard().getHex(
test_hex.x, test_hex.y))) {
valid_array[counter] = new Coords(test_hex);
counter++;
}
}
}
}
// Randomize hexes so hexes are not in order
// This is to prevent clumping at the upper-left corner on very flat
// maps
for (valid_arr_index = 0; valid_arr_index < counter; valid_arr_index++) {
arr_x_index = Compute.randomInt(counter);
if (arr_x_index < 0) {
arr_x_index = 0;
}
test_hex = valid_array[valid_arr_index];
valid_array[valid_arr_index] = valid_array[arr_x_index];
valid_array[arr_x_index] = test_hex;
}
// copy valid hexes into a new array of the correct size,
// so we don't return an array that contains null Coords
Coords[] valid_new = new Coords[counter];
for (int i = 0; i < counter; i++) {
valid_new[i] = valid_array[i];
}
valid_array = valid_new;
// Now get minimum and maximum elevation levels for these hexes
highest_elev = -100;
lowest_elev = 100;
for (valid_arr_index = 0; valid_arr_index < counter; valid_arr_index++) {
if (game.getBoard().getHex(valid_array[valid_arr_index].x,
valid_array[valid_arr_index].y).getElevation() > highest_elev) {
highest_elev = game.getBoard().getHex(
valid_array[valid_arr_index].x,
valid_array[valid_arr_index].y).getElevation();
}
if (game.getBoard().getHex(valid_array[valid_arr_index].x,
valid_array[valid_arr_index].y).getElevation() < lowest_elev) {
lowest_elev = game.getBoard().getHex(
valid_array[valid_arr_index].x,
valid_array[valid_arr_index].y).getElevation();
}
}
// Calculate average range of all weapons
// Do not include ATMs, but DO include each bin of ATM ammo
// Increase average range if the unit has an active c3 link
av_range = 0.0;
weapon_count = 0;
for (Mounted mounted : deployed_ent.getWeaponList()) {
WeaponType wtype = (WeaponType) mounted.getType();
if ((wtype.getName() != "ATM 3") && (wtype.getName() != "ATM 6")
&& (wtype.getName() != "ATM 9")
&& (wtype.getName() != "ATM 12")) {
if (deployed_ent.getC3Master() != null) {
av_range += wtype.getLongRange() * 1.25;
} else {
av_range += wtype.getLongRange();
}
weapon_count++;
}
}
for (Mounted mounted : deployed_ent.getAmmo()) {
AmmoType atype = (AmmoType) mounted.getType();
if (atype.getAmmoType() == AmmoType.T_ATM) {
weapon_count++;
av_range += 15.0;
if (atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE) {
av_range -= 6;
}
if (atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE) {
av_range += 12.0;
}
} else if (atype.getAmmoType() == AmmoType.T_MML) {
weapon_count++;
if (atype.hasFlag(AmmoType.F_MML_LRM)) {
av_range = 9.0;
} else {
av_range = 21.0;
}
}
}
av_range = av_range / weapon_count;
// Calculate ideal elevation as a factor of average range of 18 being
// highest elevation
ideal_elev = lowest_elev
+ ((av_range / 18) * (highest_elev - lowest_elev));
if (ideal_elev > highest_elev) {
ideal_elev = highest_elev;
}
best_fitness = -100.0;
for (valid_arr_index = 0; valid_arr_index < counter; valid_arr_index++) {
// Calculate the fitness factor for each hex and save it to the
// array
// -> Absolute difference between hex elevation and ideal elevation
// decreases fitness
valid_array[valid_arr_index].fitness = -1
* (Math.abs(ideal_elev
- game.getBoard().getHex(
valid_array[valid_arr_index].x,
valid_array[valid_arr_index].y)
.getElevation()));
// -> Approximate total damage taken in the current position; this
// keeps units from deploying into x-fires
total_damage = 0.0;
deployed_ent.setPosition(valid_array[valid_arr_index]);
valid_attackers = game.getValidTargets(deployed_ent);
for (Enumeration<Entity> i = valid_attackers.elements(); i
.hasMoreElements();) {
test_ent = i.nextElement();
if (test_ent.isDeployed() == true && !test_ent.isOffBoard()) {
for (Mounted mounted : test_ent.getWeaponList()) {
test_attack = new WeaponAttackAction(test_ent.getId(),
deployed_ent.getId(), test_ent
.getEquipmentNum(mounted));
adjusted_damage = getDeployDamage(game, test_attack);
total_damage += adjusted_damage;
}
}
}
valid_array[valid_arr_index].fitness -= (total_damage / 10);
// -> Find the best target for each weapon and approximate the
// damage; maybe we can kill stuff without moving!
// -> Conventional infantry ALWAYS come out on the short end of the
// stick in damage given/taken... solutions?
total_damage = 0.0;
for (Mounted mounted : deployed_ent.getWeaponList()) {
max_damage = 0.0;
for (Enumeration<Entity> j = valid_attackers.elements(); j
.hasMoreElements();) {
test_ent = j.nextElement();
if (test_ent.isDeployed() == true && !test_ent.isOffBoard()) {
test_attack = new WeaponAttackAction(deployed_ent
.getId(), test_ent.getId(), deployed_ent
.getEquipmentNum(mounted));
adjusted_damage = getDeployDamage(game, test_attack);
if (adjusted_damage > max_damage) {
max_damage = adjusted_damage;