📄 botclient.java
字号:
} } outer_loop: for (int x = 0; x < 6; x++) { highest_hex = valid_array[valid_arr_index]; highest_hex = highest_hex.translated(x); Enumeration adj_ents = game.getEntities(highest_hex); while (adj_ents.hasMoreElements()) { test_ent = (Entity) adj_ents.nextElement(); if (deployed_ent.getOwner() == test_ent.getOwner() && !deployed_ent.equals(test_ent)) { if (test_ent instanceof Infantry){ valid_array[valid_arr_index].fitness += 1; break outer_loop; } } } } // Not sure why bot tries to deploy infantry in water, it SHOULD be caught by the isHexProhibited method when // selecting hexes, but sometimes it has a mind of its own so... if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.WATER)){ valid_array[valid_arr_index].fitness -= 10; } } // VTOL *PLACEHOLDER* // Currently, VTOLs are deployed as tanks, because they're a sub-class. // This isn't correct in the long run, and eventually should be fixed. //FIXME if(deployed_ent instanceof Tank){ // Tracked vehicle // -> Trees increase fitness if(deployed_ent.getMovementMode() == IEntityMovementMode.TRACKED){ 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; } } // Wheeled vehicle // -> Not sure what any benefits wheeled vehicles can get; for now, just elevation and damage taken/given // Hover vehicle // -> Water in hex increases fitness, hover vehicles have an advantage in water areas if(deployed_ent.getMovementMode() == IEntityMovementMode.HOVER){ if (game.getBoard().getHex(valid_array[valid_arr_index].x, valid_array[valid_arr_index].y).containsTerrain(Terrains.WATER)){ valid_array[valid_arr_index].fitness += 2; } } } // ProtoMech // -> // -> Trees increase fitness by +2 (minor) if(deployed_ent instanceof Protomech){ 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; } } // Record the highest fitness factor if (valid_array[valid_arr_index].fitness > best_fitness){ best_fitness = valid_array[valid_arr_index].fitness; } } // Now sort the valid array. // We're just going to trust Java to not suck at this. Arrays.sort(valid_array, new FitnessComparator()); return valid_array; } class FitnessComparator implements Comparator { public int compare(Object o1, Object o2) { Coords d1 = (Coords)o1; Coords d2 = (Coords)o2; return -1*Double.compare(d1.fitness, d2.fitness); } } // Missile hits table // Some of these are interpolated for odd weapons sizes found in Protos and new BAs private static float[] expectedHitsByRackSize = { 0.0f, 1.0f, 1.58f, 2.0f, 2.63f, 3.17f, 4.0f, 4.49f, 4.98f, 5.47f, 6.31f, 7.23f, 8.14f, 8.59f, 9.04f, 9.5f, 0.0f, 0.0f, 0.0f, 0.0f, 12.7f }; /** * Determines the expected damage of a weapon attack, based on to-hit, salvo sizes, etc. * This has been copied almost wholesale from Compute.getExpectedDamage; the logfile print commands were * removed due to excessive data generated */ private static float getDeployDamage(IGame g, WeaponAttackAction waa) { Entity attacker = g.getEntity(waa.getEntityId()); Mounted weapon = attacker.getEquipment(waa.getWeaponId()); ToHitData hitData = waa.toHit(g); if (hitData.getValue() == ToHitData.IMPOSSIBLE || hitData.getValue() == ToHitData.AUTOMATIC_FAIL) { return 0.0f; } float fChance = 0.0f; if (hitData.getValue() == ToHitData.AUTOMATIC_SUCCESS) { fChance = 1.0f; } else { fChance = (float)Compute.oddsAbove(hitData.getValue()) / 100.0f; } // TODO : update for BattleArmor. float fDamage = 0.0f; WeaponType wt = (WeaponType)weapon.getType(); if (wt.getDamage() == WeaponType.DAMAGE_MISSILE) { if (weapon.getLinked() == null) return 0.0f; AmmoType at = (AmmoType)weapon.getLinked().getType(); float fHits = 0.0f; if ((wt.getAmmoType() == AmmoType.T_SRM_STREAK) || (wt.getAmmoType() == AmmoType.T_MRM_STREAK) || (wt.getAmmoType() == AmmoType.T_LRM_STREAK)) { fHits = wt.getRackSize(); } else if (wt.getRackSize() == 40 || wt.getRackSize() == 30) { fHits = 2.0f * expectedHitsByRackSize[wt.getRackSize() / 2]; } else { fHits = expectedHitsByRackSize[wt.getRackSize()]; } // adjust for previous AMS ArrayList vCounters = waa.getCounterEquipment(); if (vCounters != null) { for (int x = 0; x < vCounters.size(); x++) { Mounted counter = (Mounted)vCounters.get(x); if (counter.getType() instanceof WeaponType && counter.getType().hasFlag(WeaponType.F_AMS)) { float fAMS = 3.5f * ((WeaponType)counter.getType()).getDamage(); fHits = Math.max(0.0f, fHits - fAMS); } } } // damage is expected missiles * damage per missile fDamage = fHits * at.getDamagePerShot(); } else { fDamage = wt.getDamage(); } fDamage *= fChance; return fDamage; } /** * If the unit has stealth armor, turning it off is probably a good * idea if most of the enemy force is at 'short' range or if in danger * of overheating */ private void toggleStealth() { int total_bv, known_bv, known_range, known_count, trigger_range; int new_stealth = 1; Enumeration all_units; Entity test_ent; for (Enumeration i=game.getEntities(); i.hasMoreElements();){ Entity check_ent = (Entity) i.nextElement(); if ((check_ent.getOwnerId() == this.local_pn) && (check_ent instanceof Mech)){ if (((Mech)check_ent).hasStealth()){ for ( Mounted mEquip: check_ent.getMisc()) { MiscType mtype = (MiscType) mEquip.getType(); if ( Mech.STEALTH.equals(mtype.getInternalName()) ) { // If the Mech is in danger of shutting down (14+ heat), consider shutting // off the armor trigger_range = 13 + Compute.randomInt(7); if (check_ent.heat > trigger_range) { new_stealth = 0; } else { // Mech is not in danger of shutting down soon; if most of the // enemy is right next to the Mech deactivate armor to free up // heatsinks for weapons fire total_bv = 0; known_bv = 0; known_range = 0; known_count = 0; trigger_range = 5; for (all_units = game.getEntities(); all_units.hasMoreElements();){ test_ent = (Entity) all_units.nextElement(); if (check_ent.isEnemyOf(test_ent)) { total_bv += test_ent.calculateBattleValue(); if (test_ent.isVisibleToEnemy()){ known_count++; known_bv += test_ent.calculateBattleValue(); known_range += Compute.effectiveDistance(game, check_ent, test_ent); } } } // If no or few enemy units are visible, they're hiding; // Default to stealth armor on in this case if ((known_count == 0) || (known_bv < (total_bv/2))){ new_stealth = 1; } else { if (known_count != 0){ if ((known_range/known_count) <= (5 + Compute.randomInt(5))){ new_stealth = 0; } else { new_stealth = 1; } } } } mEquip.setMode(new_stealth); this.sendModeChange(check_ent.getId(), check_ent.getEquipmentNum(mEquip), new_stealth); break; } } } } } } public String getRandomBotMessage(){ String message = ""; try { String scrapFile = "./mmconf/botmessages.txt"; FileInputStream fis = new FileInputStream(scrapFile); BufferedReader dis = new BufferedReader(new InputStreamReader(fis)); while ( dis.ready() ){ message = dis.readLine(); if ( Compute.randomInt(10) == 1) break; } }//File not found don't do anything just return a null and allow the bot to remain silent catch ( FileNotFoundException fnfe){ //no chat message found continue on. return null; }//CYA exception catch(Exception ex){ System.err.println("Error while reading ./mmconf/botmessages.txt."); ex.printStackTrace(); return null; } return message; } public void retrieveServerInfo() { super.retrieveServerInfo(); initialize(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -