📄 botclient.java
字号:
if (game.getBoard().isLegalDeployment(c, this.getLocalPlayer()) && game.getFirstEntity(c) == null) { // Verify that the unit can be placed in this hex if (!deploy_me.isHexProhibited(game.getBoard().getHex(c.x, c.y))) { return c; } } // check the rest of the list. for (int x = 0; x < 6; x++) { Coords c2 = c.translated(x); if (game.getBoard().isLegalDeployment(c2, this.getLocalPlayer()) && game.getFirstEntity(c2) == null) { if (!deploy_me.isHexProhibited(game.getBoard().getHex(c2.x, c2.y))) { return c2; } } } // recurse in a random direction return getCoordsAround(deploy_me, c.translated(Compute.randomInt(6)));*/ } // New bot deploy algorithm // Screens out invalid hexes then rates them // Highest rating wins out; if this applies to multiple hexes then randomly select among them protected Coords getStartingCoords() { Coords[] calc = getStartingCoordsArray(); if (calc != null){ if (calc.length > 0){ return calc[0]; } } return null; } protected Coords[] getStartingCoordsArray() { int test_x, test_y, highest_elev, lowest_elev; int counter, valid_arr_index, arr_x_index; int weapon_count; double av_range, best_fitness, ideal_elev; //double[] fitness; double adjusted_damage, max_damage, total_damage; Coords highest_hex = new Coords(); Coords test_hex = new Coords(); Coords[] valid_array; Entity test_ent, deployed_ent; Vector 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, this.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.getAmmoType() == AmmoType.T_ATM) && atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE){ av_range -= 6; } if ((atype.getAmmoType() == AmmoType.T_ATM) && atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE){ av_range += 12.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 i = valid_attackers.elements(); i.hasMoreElements();){ test_ent = (Entity)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 j = valid_attackers.elements(); j.hasMoreElements();){ test_ent = (Entity)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; } } } total_damage += max_damage; } valid_array[valid_arr_index].fitness += (total_damage/10); // Mech if(deployed_ent instanceof Mech){ // -> Trees are good // -> Water isn't that great below depth 1 -> this saves actual ground space for infantry/vehicles (minor) if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.WOODS)){ valid_array[valid_arr_index].fitness += 1; } if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.WATER)){ if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).depth() > 1){ valid_array[valid_arr_index].fitness -= game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).depth(); } } } // Infantry if(deployed_ent instanceof Infantry) { // -> Trees and buildings make good cover, esp for conventional infantry // rough is nice, to // -> Massed infantry is more effective, so try to cluster them if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.ROUGH)){ valid_array[valid_arr_index].fitness += 1.5; } if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.WOODS)){ valid_array[valid_arr_index].fitness += 2; } if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.BUILDING)){ valid_array[valid_arr_index].fitness += 4; } highest_hex = valid_array[valid_arr_index]; Enumeration ent_list = game.getEntities(highest_hex); while (ent_list.hasMoreElements()) { test_ent = (Entity) ent_list.nextElement(); if (deployed_ent.getOwner() == test_ent.getOwner() && !deployed_ent.equals(test_ent)) { if (test_ent instanceof Infantry){ valid_array[valid_arr_index].fitness += 2; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -