📄 testbot.java
字号:
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.range_damages[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.range_damages[CEntity.RANGE_SHORT] < 4 && current_range > 10)) { temp_adjustment += ((enemy.range > CEntity.RANGE_SHORT) ? .5 : 1) * (Math.max(1 + self.range_damages[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.range_damages[CEntity.RANGE_MEDIUM]) * Math.abs(range - .5 * Math.max(self.jumpMP, .8 * self.runMP)); } else if (option.damage < .25 * self.range_damages[CEntity.RANGE_LONG]) { temp_adjustment += ((range < 10) ? .25 : 1) * (Math.max(1 + self.range_damages[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()) != ToHitData.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; if(debug) 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... IHex h = game.getBoard().getHex(option.getFinalCoords()); if (h.containsTerrain(Terrains.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.getBoard().getHex(option.getFinalCoords()).getElevation() - game.getBoard().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.range_damages[self.range] && adjustment < self.range_damages[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 / self.bv) / enemy_array.size(); } } if (option.damage < .25 * (1 + self.range_damages[self.range])) { option.self_threat += 2 * adjustment; } else if (option.damage < .5 * (1 + self.range_damages[self.range])) { option.self_threat += adjustment; } if(debug) option.tv.add(option.self_threat + " Initial Damage Adjustment " + "\n"); } return move_array; } //pass should contains 30 ~ 60 /** * ******************************************************************** * fourth pass, speculation on top moves use averaging to filter * ******************************************************************** */ private MoveOption[] fourthPass(CEntity self, ArrayList enemy_array) { MoveOption[] move_array = self.pass.values().toArray(new MoveOption[0]); self.pass.clear(); 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.pass.values().toArray(); ArrayList to_check = new ArrayList(); //check some enemy moves for (int j = 0; j < move_array.length; j++) { MoveOption option = null; to_check.clear(); option = move_array[j]; option.setState(); //check for damning hexes specifically //could also look at intervening defensive ArrayList coord = new ArrayList(); 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 : ToHitData.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; if(debug) { 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 return move_array; } //pass should now be 20 ~ 40 /** * ******************************************************************** * fifth pass, final damage and threat approximation --prevents moves * that from the previous pass would cause the mech to die * ******************************************************************** */ private MoveOption[] fifthPass(CEntity self, ArrayList enemy_array) { MoveOption[] move_array = self.pass.values().toArray(new MoveOption[0]); self.pass.clear(); if (self.engaged) { for (int j = 0; j < move_array.length; j++) { MoveOption option = 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); if(debug)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -