⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 galance.java

📁 MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight
💻 JAVA
字号:
/* * MegaMek - Copyright (C) 2002,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 java.util.Iterator;import java.util.ArrayList;public class GALance extends GA {    protected ArrayList moves;    protected TestBot tb;    protected Object[] enemy_array;    public GALance(TestBot tb, ArrayList moves, int population, int generations) {        super(moves.size(), population, .7, .05, generations, .5);        System.gc();        System.out.println("Generated move lance with population="+population+" and generations="+generations);        this.tb = tb;        this.moves = moves;        this.enemy_array = tb.getEnemyEntities().toArray();    }    protected void initPopulation() {        //promote max        try {            for (int iGene = 0; iGene < chromosomeDim; iGene++) {                (this.chromosomes[0]).genes[iGene] = 0;            }            for (int i = 1; i < populationDim; i++) {                for (int iGene = 0; iGene < chromosomeDim; iGene++) {                    (this.chromosomes[i]).genes[iGene] =                        Compute.randomInt(((MoveOption[]) (moves.get(iGene))).length);                }                this.chromosomes[i].fitness = getFitness(i);            }        } catch (Exception e) {            System.out.println("Error occured with " + populationDim + " pop " + chromosomeDim + " chromDim"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$            Iterator i = moves.iterator();            while (i.hasNext()) {                System.out.println(i.next());            }        }    }    //now they have a hard-coded hoard metality    protected double getFitness(int iChromIndex) {        Chromosome chrom = this.chromosomes[iChromIndex];        ArrayList possible = new ArrayList();        for (int iGene = 0; iGene < chromosomeDim; iGene++) {            possible.add(new MoveOption(((MoveOption[]) this.moves.get(iGene))[chrom.genes[iGene]]));        }        Object[] move_array = possible.toArray();        for (int e = 0; e < enemy_array.length; e++) { // for each enemy            CEntity enemy = tb.centities.get((Entity) enemy_array[e]);            MoveOption max = null;            for (int m = 0; m < move_array.length; m++) {                if (max == null || ((MoveOption) move_array[m]).getThreat(enemy) > max.getThreat(enemy)) {                    max = (MoveOption) move_array[m];                }            }            for (int m = 1; m < move_array.length; m++) {                MoveOption next = (MoveOption) move_array[m];                if (next.getThreat(enemy) > 0) {                    if (next.getThreat(enemy) < .25 * max.getThreat(enemy)) {                        next.setThreat(enemy, 0);                    } else {                        next.setThreat(                            enemy,                            Math.pow(next.getThreat(enemy) / max.getThreat(enemy), 2) * next.getThreat(enemy));                    }                }            }        }        //total damage delt, and rescaling of threat        double damages[] = new double[enemy_array.length];        for (int m = 0; m < move_array.length; m++) {            MoveOption next = (MoveOption) move_array[m];            next.threat = 0;            for (int e = 0; e < enemy_array.length; e++) {                CEntity enemy = tb.centities.get((Entity) enemy_array[e]);                next.threat += next.getThreat(enemy);                damages[e] = (next.getMinDamage(enemy) + next.getDamage(enemy)) / 2;            }        }        //sacrificial lamb check        double result = 0;        for (int m = 0; m < move_array.length; m++) {            MoveOption next = (MoveOption) move_array[m];            if (((MoveOption[]) moves.get(m)).length > 1) {                MoveOption min = ((MoveOption[]) moves.get(m))[0];                if (min.damage > 2 * next.damage && min.getUtility() < .5 * next.getUtility()) {                    result += next.getCEntity().bv; //it is being endangered                                                    // in the future                    if (m > 0)                        chrom.genes[m]--; //go so far as to mutate the                                                // gene                }            }        }        //int difference = this.tb.NumEnemies - this.tb.NumFriends;        double distance_mod = 0;        //if outnumbered and loosing, clump together.        try {            int target_distance = 4;            for (int m = 0; m < move_array.length; m++) {                MoveOption next = (MoveOption) move_array[m];                next.getUtility();                for (int j = 0; j < move_array.length; j++) {                    MoveOption other = (MoveOption) move_array[j];                    if (m != j) {                        int distance = other.getFinalCoords().distance(next.getFinalCoords());                        if (distance > target_distance) {                            distance_mod += Math.pow(distance - target_distance, 2);                        } else if (distance <= 3) {                            boolean swarm = false;                            CEntity target = null;                            for (int e = 0; e < enemy_array.length; e++) {                                CEntity cen = tb.centities.get((Entity) this.enemy_array[e]);                                if (!cen.canMove()) {                                    if ((next.getFinalCoords() != null)                                            && (other.getFinalCoords() != null)                                            && (cen.current.getFinalCoords() != null)                                            && ((cen.current.getFinalCoords().distance(next.getFinalCoords()) == 1                                            && cen.current.getFinalCoords().distance(other.getFinalCoords()) == 1)                                            || (cen.current.getFinalCoords().distance(next.getFinalCoords()) <= 3                                                && cen.current.getFinalCoords().distance(other.getFinalCoords()) <= 3                                                && cen.current.getFinalProne())                                            && !(next.inDanger || next.getFinalProne()))) {                                        swarm = true;                                        target = cen;                                    }                                }                            }                            if (swarm) {                                if (target.entity.isProne()) {                                    distance_mod -= target.bv / 100;                                }                                distance_mod -= target.bv / 50;                                next.setDamage(target, next.getDamage(target)*1.2);                            }                        }                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        double max = 0;        //bonuses for endangering or dooming opponent mechs        for (int e = 0; e < enemy_array.length; e++) {            CEntity cen = tb.centities.get((Entity) this.enemy_array[e]);            if (damages[e] > cen.avg_armor) {                if (damages[e] > 4 * cen.avg_armor) {                    max += cen.bv / 5; //likely to die                } else {                    max += cen.bv / 50; //in danger                }            } else if (damages[e] > 40) {                max += (1 - cen.base_psr_odds) * cen.entity.getWeight();            }        }        //if noone is in danger at least give a bonus for clustering        if (max == 0) {            for (int e = 0; e < enemy_array.length; e++) {                if (damages[e] > max) {                    max = damages[e];                }            }        }        distance_mod /= move_array.length * move_array.length;        for (int m = 0; m < move_array.length; m++) {            MoveOption next = (MoveOption) move_array[m];            if (next.inDanger) {                if (next.doomed) {                    if (next.getCEntity().last != null && next.getCEntity().last.doomed) {                        result -= next.damage - .5 * next.getUtility(); //should                                                                        // be                                                                        // dead                    } else if (next.getCEntity().last != null && !next.getCEntity().last.doomed) {                        result += next.getUtility() + 2 * next.damage; //don't                                                                       // like                                                                       // this                                                                       // case                    } else {                        result += next.getUtility();                    }                } else {                    if (next.getCEntity().last != null && !next.getCEntity().last.inDanger) {                        result += next.getUtility() + next.damage; //not so                                                                   // good                                                                   // either                    } else {                        result += next.getUtility();                    }                }            } else {                result += next.getUtility();            }        }        return -result + (max - distance_mod);    }    public MoveOption getResult() {        Chromosome r = this.chromosomes[best];        ArrayList possible = new ArrayList();        for (int iGene = 0; iGene < chromosomeDim; iGene++) {            possible.add(new MoveOption(((MoveOption[]) this.moves.get(iGene))[r.genes[iGene]]));        }        Object[] move_array = possible.toArray();        MoveOption result = null;        for (int m = 0; m < move_array.length; m++) {            MoveOption next = (MoveOption) move_array[m];            CEntity cen = tb.centities.get(next.getEntity());            if (!cen.moved && (result == null || (next.getUtility() < result.getUtility()))) {                result = next;            }        }        return result;    }    protected void doRandomMutation(int iChromIndex) {        Chromosome c1 = this.chromosomes[iChromIndex];        // I don't think we need to mutate an empty chromosome        if (c1.genes.length < 1) {            return;        }        int r1 = (c1.genes.length > 2) ? Compute.randomInt(c1.genes.length - 1) : 0;        if (r1 % 2 == 1) {            c1.genes[r1] = Compute.randomInt(((MoveOption[]) this.moves.get(r1)).length);            return;        }        for (int i = 1; i < c1.genes.length; i++) {            int iGene = (i + r1 - 1) % (c1.genes.length - 1);            if (((MoveOption[]) this.moves.get(iGene)).length > 1) {                c1.genes[iGene] = Compute.randomInt(((MoveOption[]) this.moves.get(iGene)).length);                return;            }        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -