Object[] enemy_move_array = enemy.getAllMoves().values().toArray();
Object[] enemy_move_array = enemy.pass.values().toArray();
    public MoveOption[] calculateMove(Entity entity) {        java.util.Vector enemy_array = game.getValidTargets(entity);        java.util.Vector entities = game.getEntitiesVector();        CEntity self = centities.get(entity);        Object[] move_array;        int friends = entities.size() - enemy_array.size();        /***********************************************************************		 * Second pass, combination moves/firing based only on the present		 * case, since only one mech moves at a time		 **********************************************************************/        move_array = self.pass.values().toArray();        self.pass.clear();        for (int j = 0; j < move_array.length && friends > 2; j++) {            MoveOption option = (MoveOption) move_array[j];            for (int e = 0; e < enemy_array.size(); e++) {                Entity en = (Entity) enemy_array.get(e);                CEntity enemy = centities.get(en);                for (java.util.Iterator f = entities.iterator(); f.hasNext();) {                    Entity other = (Entity) f.next();                    if (other.isEnemyOf(self.entity)) {                        continue;                    }                    MoveOption foption = centities.get(other).current;                    double threat_divisor = 1;                    MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);                    if (foption.getDamageInfo(enemy, false) != null) {                        option.damage += (enemy.canMove() ? .1 : .2) * di.damage;                        threat_divisor += foption.getCEntity().canMove() ? .4 : .6;                    }                    option.threat -= di.threat;                    di.threat /= threat_divisor;                    option.threat += di.threat;                }            }        }        //top balanced        filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 50);        //top damage        filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 50);        /***********************************************************************		 * third pass, (not so bad) oppurtunistic planner gives preference to		 * good ranges/defensive positions based upon the mech characterization		 **********************************************************************/        move_array = self.pass.values().toArray();        self.pass.clear();        for (int j = 0; j < move_array.length; j++) {            MoveOption option = (MoveOption) move_array[j];            option.setState();            double adjustment = 0;            double temp_adjustment = 0;            for (int e = 0; e < enemy_array.size(); e++) { // for each enemy                Entity en = (Entity) enemy_array.get(e);                CEntity enemy = centities.get(en);                int current_range = self.current.getFinalCoords().distance(enemy.current.getFinalCoords());                int range = option.getFinalCoords().distance(enemy.current.getFinalCoords());                if (range > self.long_range) {                    temp_adjustment += (!(range < enemy.long_range) ? .5 : 1)                        * (1 + self.RangeDamages[self.Range])                        * (Math.max(range - self.long_range - .5 * Math.max(self.jumpMP, .8 * self.runMP), 0));                }                if ((self.Range == CEntity.RANGE_SHORT && (current_range > 5 || range > 9))                    || (self.RangeDamages[CEntity.RANGE_SHORT] < 4 && current_range > 10)) {                    temp_adjustment += ((enemy.Range > CEntity.RANGE_SHORT) ? .5 : 1)                        * (Math.max(1 + self.RangeDamages[CEntity.RANGE_SHORT], 5))                        * Math.max(range - .5 * Math.max(self.jumpMP, .8 * self.runMP), 0);                } else if (self.Range == CEntity.RANGE_MEDIUM) {                    temp_adjustment += ((current_range < 6 || current_range > 12) ? 1 : .25)                        * ((enemy.Range > CEntity.RANGE_SHORT) ? .5 : 1)                        * (1 + self.RangeDamages[CEntity.RANGE_MEDIUM])                        * Math.abs(range - .5 * Math.max(self.jumpMP, .8 * self.runMP));                } else if (option.damage < .25 * self.RangeDamages[CEntity.RANGE_LONG]) {                    temp_adjustment += ((range < 10) ? .25 : 1)                        * (Math.max(1 + self.RangeDamages[CEntity.RANGE_LONG], 3))                        * (1 / (1 + option.threat));                }                adjustment += Math.sqrt(temp_adjustment * enemy.bv / self.bv);                //I would always like to face the opponent                if (!(enemy.getEntity().isProne() || enemy.getEntity().isImmobile())                    && CEntity.getThreatHitArc(                        option.getFinalCoords(),                        option.getFinalFacing(),                        enemy.getEntity().getPosition())                        != CEntity.SIDE_FRONT) {                    int fa =                        CEntity.getFiringAngle(                            option.getFinalCoords(),                            option.getFinalFacing(),                            enemy.getEntity().getPosition());                    if (fa > 90 && fa < 270) {                        int distance = option.getFinalCoords().distance(enemy.current.getFinalCoords());                        double mod = 1;                        if (fa > 130 && fa < 240)                            mod = 2;                        //big formula that says don't do it                        mod *= ((Math.max(self.jumpMP, .8 * self.runMP) < 5) ? 2 : 1)                            * ((double) self.bv / (double) 50)                            * Math.sqrt(((double) self.bv) / enemy.bv)                            / ((double) distance / 6 + 1);                        option.self_threat += mod;                        option.tv.add(mod + " " + fa + " Back to enemy\n");                    }                }            }            adjustment *= self.overall_armor_percent * self.strategy.attack / enemy_array.size();            //fix for hiding in level 2 water            //To a greedy bot, it always seems nice to stay in here...            Hex h = game.board.getHex(option.getFinalCoords());            if (h.contains(Terrain.WATER)                && h.surface() > (self.getEntity().getElevation() + ((option.getFinalProne()) ? 0 : 1))) {                double mod = (self.getEntity().heat + option.getMovementheatBuildup() <= 7) ? 100 : 30;                adjustment += self.bv / mod;            }            //add them in now, then re-add them later            if (self.Range > CEntity.RANGE_SHORT) {                int ele_dif =                    game.board.getHex(option.getFinalCoords()).getElevation()                        - game.board.getHex(self.current.getFinalCoords()).getElevation();                adjustment -= (Math.max(ele_dif, 0) + 1)                    * ((double) Compute.getTargetTerrainModifier(game, option.getEntity()).getValue() + 1);            }            //close the range if nothing else and healthy            if (option.damage < .25 * self.RangeDamages[self.Range] && adjustment < self.RangeDamages[self.Range]) {                for (int e = 0; e < enemy_array.size(); e++) {                    Entity en = (Entity) enemy_array.get(e);                    CEntity enemy = centities.get(en);                    int range = option.getFinalCoords().distance(enemy.current.getFinalCoords());                    if (range > 5)                        adjustment += Math.pow(self.overall_armor_percent, 2)                            * Math.sqrt((double) (range - 4) * enemy.bv / (double) self.bv)                            / enemy_array.size();                }            }            if (option.damage < .25 * (1 + self.RangeDamages[self.Range])) {                option.self_threat += 2 * adjustment;            } else if (option.damage < .5 * (1 + self.RangeDamages[self.Range])) {                option.self_threat += adjustment;            }            option.tv.add(option.self_threat + " Initial Damage Adjustment " + "\n");        }        //top balanced        filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 30);        //top damage        filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 30);        //reduce self threat, and add bonus for terrain        for (Iterator i = self.pass.values().iterator(); i.hasNext();) {            MoveOption option = (MoveOption) i.next();            option.setState();            option.self_damage *= .5;            option.self_threat *= .5;            //TODO: should scale to the unit bv            double terrain = 2 * ((double) Compute.getTargetTerrainModifier(game, option.getEntity()).getValue());            option.tv.add(terrain + " Terrain Adjusment " + "\n");            option.self_threat -= terrain;        }        move_array = self.pass.values().toArray();        self.pass.clear();        //pass should contains 30 ~ 60        /***********************************************************************		 * fourth pass, speculation on top moves use averaging to filter		 **********************************************************************/        for (int e = 0; e < enemy_array.size(); e++) { // for each enemy            Entity en = (Entity) enemy_array.get(e);            CEntity enemy = centities.get(en);            //engage in speculation on "best choices" when you loose iniative            if (enemy.canMove()) {                Object[] enemy_move_array = enemy.getAllMoves().values().toArray();                Vector to_check = new Vector();                //check some enemy moves                for (int j = 0; j < move_array.length; j++) {                    MoveOption option = null;                    to_check.clear();                    option = (MoveOption) move_array[j];                    option.setState();                    //check for damning hexes specifically                    //could also look at intervening defensive                    Vector coord = new Vector();                    Coords back = option.getFinalCoords().translated((option.getFinalFacing() + 3) % 6);                    coord.add(back);                    coord.add(back.translated((option.getFinalFacing() + 2) % 6));                    coord.add(back.translated((option.getFinalFacing() + 4) % 6));                    coord.add(option.getFinalCoords().translated((option.getFinalFacing())));                    coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 1) % 6));                    coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 2) % 6));                    coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 4) % 6));                    coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 5) % 6));                    Iterator ci = coord.iterator();                    while (ci.hasNext()) {                        Coords test = (Coords) ci.next();                        List c = enemy.findMoves(test);                        if (c.size() != 0)                            to_check.addAll(c);                    }                    int range = option.getFinalCoords().distance(enemy.current.getFinalCoords());                    int compare = 0;                    if ((enemy.long_range) > range - Math.max(enemy.jumpMP, enemy.runMP)) {                        compare = 30;                    } else if (enemy.long_range > range) {                        compare = 10;                    }                    double mod = this.enemies_moved / this.getEnemyEntities().size();                    compare *= (1 + mod);                    for (int k = 0; k <= compare && k < enemy_move_array.length; k++) {                        if (enemy_move_array.length < compare) {                            to_check.add(enemy_move_array[k]);                        } else {                            int value = Compute.randomInt(enemy_move_array.length);                            if (value % 2 == 1) {                                to_check.add(enemy_move_array[value]);                            } else {                                to_check.add(enemy_move_array[k]);                            }                        }                    }                    Iterator eo = to_check.iterator();                    while (eo.hasNext()) {                        MoveOption enemy_option = (MoveOption) eo.next();                        double max_threat = 0;                        double max_damage = 0;                        enemy_option.setState();                        int enemy_hit_arc =                            CEntity.getThreatHitArc(                                enemy_option.getFinalCoords(),                                enemy_option.getFinalFacing(),                                option.getFinalCoords());                        int self_hit_arc =                            CEntity.getThreatHitArc(                                enemy_option.getFinalCoords(),                                enemy_option.getFinalFacing(),                                option.getFinalCoords());                        if (enemy_option.isJumping()) {                            enemy_hit_arc = Compute.ARC_FORWARD;                        }                        int[] modifiers = option.getModifiers(enemy_option.getEntity());                        if (modifiers[1] != ToHitData.IMPOSSIBLE) {                            self.engaged = true;                            if (!enemy_option.isJumping()) {                                max_threat =                                    option.getMaxModifiedDamage(                                        enemy_option,                                        modifiers[1],                                        modifiers[MoveOption.DEFENCE_PC]);                            } else {                                max_threat =                                    .8                                        * enemy.getModifiedDamage(                                            (modifiers[MoveOption.DEFENCE_PC] == 1) ? CEntity.TT : CEntity.SIDE_FRONT,                                            enemy_option.getFinalCoords().distance(option.getFinalCoords()),                                            modifiers[1]);                            }                            max_threat = self.getThreatUtility(max_threat, self_hit_arc);                        }                        if (modifiers[0] != ToHitData.IMPOSSIBLE) {                            self.engaged = true;                            max_damage =                                enemy_option.getMaxModifiedDamage(                                    option,                                    modifiers[0],                                    modifiers[MoveOption.ATTACK_PC]);                            max_damage = enemy.getThreatUtility(max_damage, enemy_hit_arc);                            if (option.isPhysical) {                                if (centities.get(option.getPhysicalTargetId()).getEntity().getId()                                    == enemy.getEntity().getId()) {                                    max_damage = option.getDamage(enemy);                                } else {                                    max_damage = 0;                                }                            }                        }                        MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);                        di.max_threat = Math.max(max_threat, di.max_threat);                        di.min_damage = Math.min(di.min_damage, max_damage);                        if (max_threat - max_damage > di.threat - di.damage) {                            di.threat = max_threat;                            di.damage = max_damage;                            option.tv.add(max_threat + " Spec Threat " + e + "\n");                            option.tv.add(max_damage + " Spec Damage " + e + "\n");                        }                    }                    //update estimates                    option.damage = 0;                    option.threat = 0;                    for (Iterator i = option.damageInfos.keySet().iterator(); i.hasNext();) {                        //my damage is the average of expected and min                        CEntity cen = (CEntity)i.next();                        //rescale                        MoveOption.DamageInfo di = option.getDamageInfo(cen, true);                        di.min_damage /= cen.strategy.target;                        di.damage /= cen.strategy.target;                        option.damage += (di.min_damage + di.damage) / 2;                        //my threat is average of absolute worst, and expected                        option.threat = Math.max(option.threat, di.max_threat + di.threat) / 2;                        di.threat = (di.max_threat + 2 * di.threat) / 3;                    }                }                //restore enemy                enemy.current.setState();            }            self.current.setState();        } //--end move speculation        //top balanced        filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 20);        //top damage        filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 20);        //reduce transient damage estimates        for (Iterator i = self.pass.values().iterator(); i.hasNext();) {            MoveOption option = (MoveOption) i.next();            option.self_threat *= .5;            option.self_damage *= .5;        }        move_array = self.pass.values().toArray();        self.pass.clear();        //pass should now be 20 ~ 40        /***********************************************************************		 * fourth pass, final damage and threat approximation --prevents moves		 * that from the previous pass would cause the mech to die		 **********************************************************************/        if (self.engaged) {            for (int j = 0; j < move_array.length; j++) {                MoveOption option = (MoveOption) move_array[j];                option.setState();                GAAttack temp = this.bestAttack(option);                if (temp != null) {                    option.damage = (option.damage + temp.getFittestChromosomesFitness()) / 2;                } else {                    option.damage /= 2;                }                for (int e = 0; e < enemy_array.size(); e++) { // for each                    // enemy                    Entity en = (Entity) enemy_array.get(e);                    CEntity enemy = centities.get(en);                    if (!enemy.canMove()) {                        option.setThreat(enemy, (option.getThreat(enemy) + this.attackUtility(enemy.current, self)) / 2);                        option.tv.add(option.getThreat(enemy) + " Revised Threat " + e + " \n");                        if (!option.isPhysical) {                            if (temp != null) {                                option.setDamage(enemy, (option.getDamage(enemy) + temp.getDamageUtility(enemy)) / 2);                            } else {                                //probably zero, but just in case                                option.setDamage(enemy, option.getMinDamage(enemy));                            }							option.tv.add(option.getDamage(enemy) + " Revised Damage " + e + " \n");                            //this needs to be reworked                            if (option.getFinalCoords().distance(enemy.current.getFinalCoords()) == 1) {                                PhysicalOption p =                                    pcalc.getBestPhysicalAttack(option.getEntity(), enemy.getEntity(), game);                                if (p != null) {                                    option.setDamage(enemy, option.getDamage(enemy) + p.expectedDmg);                                    option.tv.add(p.expectedDmg + " Physical Damage " + e + " \n");                                }                                p = pcalc.getBestPhysicalAttack(enemy.getEntity(), option.getEntity(), game);                                if (p != null) {                                    option.setThreat(enemy, option.getThreat(enemy) + .5 * p.expectedDmg);                                    option.tv.add(.5 * p.expectedDmg + " Physical Threat " + e + " \n");                                }                            }                        }                    } else if (!option.isPhysical) { //enemy can move (not                        if (temp != null) {                            option.setDamage(enemy, (2 * option.getDamage(enemy) + temp.getDamageUtility(enemy)) / 3);                        } else {                            option.setDamage(enemy, option.getMinDamage(enemy));                        }                    } else {                        //get a more accurate estimate                        option.setDamage(enemy, option.getDamage(enemy) / Math.sqrt((double) enemy.bv / (double) self.bv));                        option.damage = option.getDamage(enemy);                    }                }                option.threat = 0;                for (Iterator i = option.damageInfos.values().iterator(); i.hasNext();) {                    option.threat += ((MoveOption.DamageInfo)i.next()).threat;                }                option.tv.add(option.threat + " Revised Threat Utility\n");                option.tv.add(option.damage + " Revised Damage Utility\n");            }        }        Arrays.sort(move_array, new MoveOption.WeightedComparator(1, 1));        self.current.setState();        /***********************************************************************		 * Return top twenty moves to the lance algorithm		 **********************************************************************/        MoveOption[] result = new MoveOption[Math.min(move_array.length, 20)];        int offset = 0;        for (int i = 0; i < Math.min(move_array.length, 20); i++) {            MoveOption next = (MoveOption) move_array[i];            if (next.isPhysical && self.RangeDamages[CEntity.RANGE_SHORT] > 5 && next.doomed) {                if (offset + 20 < move_array.length) {                    next = (MoveOption) move_array[offset + 20];                    offset++;                }            }            result[i] = next;        }        return result;    }