📄 gaattack.java
字号:
/* * MegaMek - Copyright (C) 2000-2003 Ben Mazur (bmazur@sev.org) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */package megamek.client.bot;import megamek.client.bot.ga.Chromosome;import megamek.client.bot.ga.GA;import megamek.common.Compute;import megamek.common.Entity;import megamek.common.IGame;import megamek.common.Mech;import megamek.common.Terrains;import megamek.common.ToHitData;import java.util.ArrayList;import java.util.Iterator;/** * Need to test the function that moves all firing to a single target */public class GAAttack extends GA { protected ArrayList attack; protected CEntity attacker; protected IGame game; protected CEntity.Table targets; protected ArrayList target_array = null; protected ArrayList valid_target_indexes = null; protected boolean overheat_eligible = false; protected int firing_arc = 0; double[] damages = null; public GAAttack(TestBot tb, CEntity attacker, ArrayList attack, int population, int generations, boolean isEnemy) { super(attack.size() + 1, population, .7, .05, generations, .4); this.attack = attack; this.attacker = attacker; this.game = tb.game; this.target_array = new ArrayList(game.getEntitiesVector()); ArrayList temp = new ArrayList(); for (int i = 0; i < target_array.size(); i++) { Entity entity = (Entity) target_array.get(i); if (entity.isEnemyOf(attacker.entity) && entity.isDeployed()) { temp.add(new Integer(i)); } } targets = new CEntity.Table(tb); this.valid_target_indexes = temp; if (attacker.tsm_offset){ this.overheat_eligible = true; } if (isEnemy || (attacker.last != null && (!attacker.last.inDanger || attacker.last.doomed))) { this.overheat_eligible = true; } } public int[] getResultChromosome() { return ((chromosomes[populationDim - 1]).genes); } public double getDamageUtility(CEntity to) { if (damages == null) damages = this.getDamageUtilities(); for (int k = 0; k < this.target_array.size(); k++) { Entity enemy = (Entity) this.target_array.get(k); if (enemy.getId() == to.entity.getId()) { return damages[k]; } } return 0; } public double[] getDamageUtilities() { int iChromIndex = populationDim - 1; targets.clear(); //could use ArrayList and not hashtable double[] result = new double[this.target_array.size()]; Chromosome chromArrayList = this.chromosomes[iChromIndex]; //TODO should account for high heat? int heat_total = 0; if (chromArrayList.genes[chromosomeDim - 1] >= this.target_array.size()) { chromArrayList.genes[chromosomeDim - 1] = ((Integer) this.valid_target_indexes.get(0)).intValue(); } Entity target = (Entity) this.target_array.get(chromArrayList.genes[chromosomeDim - 1]); for (int iGene = 0; iGene < chromosomeDim - 1; iGene++) { AttackOption a = (AttackOption) (((ArrayList) (attack.get(iGene))).get(chromArrayList.genes[iGene])); if (a.target != null) { //if not the no fire option targets.put(a.target); double mod = 1; if (a.target.entity.getId() == target.getId()) { a.target.possible_damage[a.toHit.getSideTable()] += mod * a.primary_expected; } else { a.target.possible_damage[a.toHit.getSideTable()] += mod * a.expected; } heat_total += a.heat; } } for (int k = 0; k < this.target_array.size(); k++) { Entity en = (Entity) this.target_array.get(k); CEntity enemy = null; result[k] = 0; if ((enemy = (CEntity) this.targets.get(new Integer(en.getId()))) != null) { result[k] = getThreadUtility(enemy); enemy.resetPossibleDamage(); } } return result; } private double getThreadUtility(CEntity enemy) { if (enemy.possible_damage[ToHitData.SIDE_FRONT] > 0) { return enemy.getThreatUtility(enemy.possible_damage[ToHitData.SIDE_FRONT], ToHitData.SIDE_FRONT); } else if (enemy.possible_damage[ToHitData.SIDE_REAR] > 0) { return enemy.getThreatUtility(enemy.possible_damage[ToHitData.SIDE_REAR], ToHitData.SIDE_REAR); } else if (enemy.possible_damage[ToHitData.SIDE_LEFT] > 0) { return enemy.getThreatUtility(enemy.possible_damage[ToHitData.SIDE_LEFT], ToHitData.SIDE_LEFT); } else if (enemy.possible_damage[ToHitData.SIDE_RIGHT] > 0) { return enemy.getThreatUtility(enemy.possible_damage[ToHitData.SIDE_RIGHT], ToHitData.SIDE_RIGHT); } return 0; } protected double getFitness(int iChromIndex) { return this.getFitness(this.chromosomes[iChromIndex]); } protected double getFitness(Chromosome chromArrayList) { targets.clear(); //could use ArrayList and not hashtable int heat_total = 0; Entity target = null; try { target = (Entity) this.target_array.get(chromArrayList.genes[chromosomeDim - 1]); } catch (Exception e) { System.out.println(chromosomeDim + " " + chromArrayList.genes.length); //$NON-NLS-1$ System.out.println(this.target_array.size()); target = (Entity) this.target_array.get(((Integer) this.valid_target_indexes.get(0)).intValue()); } for (int iGene = 0; iGene < chromosomeDim - 1; iGene++) { final int[] genes = chromArrayList.genes; AttackOption a = (AttackOption) (((ArrayList) (attack.get(iGene))).get(genes[iGene])); if (a.target != null) { //if not the no fire option targets.put(a.target); double mod = 1; if (a.primary_odds <= 0) { mod = 0; // If there's no chance to hit at all... } else if (a.ammoLeft != -1) { if (attacker.overall_armor_percent < .5) { mod = 1.5; //get rid of it } else if (a.ammoLeft < 12 && attacker.overall_armor_percent > .75) { if (a.primary_odds < .1) { mod = 0; } else if (a.ammoLeft < 6 && a.primary_odds < .25) { mod = 0; } else { mod = a.primary_odds; //low percentage shots will // be frowned upon } } } if (a.target.entity.getId() == target.getId()) { a.target.possible_damage[a.toHit.getSideTable()] += mod * a.primary_expected; } else { a.target.possible_damage[a.toHit.getSideTable()] += mod * a.expected; } heat_total += a.heat; } } double total_utility = 0; Iterator j = targets.values().iterator(); while (j.hasNext()) { CEntity enemy = (CEntity) j.next(); total_utility+=getThreadUtility(enemy); enemy.resetPossibleDamage(); } //should be moved
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -