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

📄 boardutilities.java

📁 MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        int count = minHexes;        if ((maxHexes - minHexes) > 0) {            count += Compute.randomInt(maxHexes-minHexes);        }        IHex field;                HashSet alreadyUsed = new HashSet();        HashSet unUsed = new HashSet();        field = board.getHex(p.x, p.y);        if (!field.containsTerrain(terrainType)) {            unUsed.add(field);        } else {            findAllUnused(board, terrainType, alreadyUsed,                    unUsed, field, reverseHex);        }        ITerrainFactory f = Terrains.getTerrainFactory();                for (int i = 0; i < count; i++) {            if (unUsed.isEmpty()) {                return;            }            int which = Compute.randomInt(unUsed.size());            Iterator iter = unUsed.iterator();            for (int n = 0; n < (which - 1); n++)                iter.next();            field = (IHex)iter.next();            if (exclusive) {                field.removeAllTerrains();            }            int tempInt = (Compute.randomInt(100) < probMore)? 2 : 1;            ITerrain tempTerrain = f.createTerrain(terrainType, tempInt);            field.addTerrain(tempTerrain);            unUsed.remove(field);            findAllUnused(board, terrainType, alreadyUsed, unUsed, field, reverseHex);        }                if (terrainType == Terrains.WATER) {            /* if next to an Water Hex is an lower lvl lower the hex.             First we search for lowest Hex next to the lake */            int min = Integer.MAX_VALUE;            Iterator iter = unUsed.iterator();            while (iter.hasNext()) {                field = (IHex)iter.next();                if (field.getElevation() < min) {                    min = field.getElevation();                }            }            iter = alreadyUsed.iterator();            while (iter.hasNext()) {                field = (IHex)iter.next();                field.setElevation(min);            }                    }    }    /**     * Searching starting from one Hex, all Terrains not matching     * terrainType, next to one of terrainType.     * @param terrainType The terrainType which the searching hexes     * should not have.     * @param alreadyUsed The hexes which should not looked at     * (because they are already supposed to visited in some way)      * @param unUsed In this set the resulting hexes are stored. They     * are stored in addition to all previously stored.     * @param searchFrom The Hex where to start     */    private static void findAllUnused(IBoard board, int terrainType, HashSet alreadyUsed,            HashSet unUsed, IHex searchFrom, HashMap reverseHex) {        IHex field;        HashSet notYetUsed = new HashSet();                notYetUsed.add(searchFrom);        do {            Iterator iter = notYetUsed.iterator();            field = (IHex)iter.next();            if (field == null) {                continue;            }            for (int dir = 0; dir < 6; dir++) {                Point loc = (Point) reverseHex.get(field);                IHex newHex = board.getHexInDir(loc.x, loc.y, dir);                if ((newHex != null) &&                         (!alreadyUsed.contains(newHex)) &&                        (!notYetUsed.contains(newHex)) &&                        (!unUsed.contains(newHex))) {                    ((newHex.containsTerrain(terrainType)) ? notYetUsed : unUsed ).add(newHex);                }            }            notYetUsed.remove(field);            alreadyUsed.add(field);        } while (!notYetUsed.isEmpty());    }        /**      * add a crater to the board     */    public static void addCraters(IBoard board, int minRadius, int maxRadius,int minCraters, int maxCraters) {        int numberCraters = minCraters;        if (maxCraters > minCraters) {            numberCraters += Compute.randomInt(maxCraters - minCraters);        }        for (int i = 0; i < numberCraters; i++) {            int width = board.getWidth();            int height = board.getHeight();            Point center = new Point(Compute.randomInt(width), Compute.randomInt(height));                        int radius = Compute.randomInt(maxRadius - minRadius + 1) + minRadius;            int maxLevel = 3;            if (radius < 3) {                 maxLevel = 1;            }            if ((radius >= 3) && (radius <= 8)) {                maxLevel = 2;            }            if (radius > 14) {                maxLevel = 4;            }            int maxHeight = Compute.randomInt(maxLevel) + 1;            /* generate CraterProfile */            int cratHeight[] = new int[radius];            for (int x = 0; x < radius; x++) {                cratHeight[x] = craterProfile((double)x / (double)radius, maxHeight);            }            /* btw, I am interested if someone actually reads             this comments, so send me and email to f.stock@tu-bs.de, if             you do ;-) */            /* now recalculate every hex */            for (int h = 0; h < height; h++) {                for (int w = 0; w < width; w++) {                    int distance = (int)distance(center, new Point(w,h));                    if (distance < radius) {                        IHex field = board.getHex(w, h);                        field.setElevation(//field.getElevation() +                                cratHeight[distance]);                    }                 }               }             }    }        /**     * The profile of a crater: interior is exp-function, exterior cos function.     * @param x The x value of the function. range 0..1.      *        0=center of crater. 1=border of outer wall.     *  @param scale Apply this scale before returning the result     *         (recommend instead of afterwards scale, cause this way the intern     *         floating values are scaled, instead of int result).     *  @return The height of the crater at the position x from     *          center. Unscaled, the results are between -0.5 and 1 (that     *          means, if no scale is applied -1, 0 or 1).     */    public static int craterProfile(double x, int scale) {        double result = 0;                result = (x < 0.75) ?                 ((Math.exp(x * 5.0 / 0.75 - 3) - 0.04979) * 1.5 / 7.33926) - 0.5 :                     ((Math.cos((x-0.75)*4.0)+1.0) / 2.0);                return (int)(result * scale);    }        /**     * calculate the distance between two points     */    private static double distance(Point p1, Point p2) {        double x = p1.x - p2.x;        double y = p1.y - p2.y;        return Math.sqrt(x*x + y*y);    }        /**      * Adds an River to the map (if the map is at least 5x5 hexes     * big). The river has an width of 1-3 hexes (everything else is     * no more a river). The river goes from one border to another.     * Nor Params, no results.     */    public static void addRiver(IBoard board, HashMap reverseHex) {        int minElevation = Integer.MAX_VALUE;        HashSet riverHexes = new HashSet();        IHex field;        Point p = null;        int direction = 0;        int nextLeft = 0;        int nextRight = 0;                int width = board.getWidth();        int height = board.getHeight();                /* if map is smaller than 5x5 no real space for an river */        if ((width < 5) || (height < 5)) {            return;        }        /* First select start and the direction */        switch (Compute.randomInt(4)) {        case 0:            p = new Point(0, Compute.randomInt(5) - 2 + height / 2);            direction = Compute.randomInt(2) + 1;            nextLeft = direction - 1;            nextRight = direction + 1;            break;        case 1:            p = new Point(width - 1, Compute.randomInt(5) - 2 + height / 2);            direction = Compute.randomInt(2) + 4;            nextLeft = direction - 1;            nextRight = (direction + 1) % 6;            break;        case 2:        case 3:            p = new Point(Compute.randomInt(5) - 2 + width / 2, 0);            direction = 2;            nextRight = 3;            nextLeft = 4;            break;        } // switch        /* place the river */        field = board.getHex(p.x, p.y);        ITerrainFactory f = Terrains.getTerrainFactory();                do {            /* first the hex itself */            field.removeAllTerrains();            field.addTerrain(f.createTerrain(Terrains.WATER, 1));            riverHexes.add(field);            p = (Point)reverseHex.get(field);            /* then maybe the left and right neighbours */            riverHexes.addAll(extendRiverToSide(board, p, Compute.randomInt(3),                     nextLeft, reverseHex));            riverHexes.addAll(extendRiverToSide(board, p, Compute.randomInt(3),                    nextRight, reverseHex));            switch (Compute.randomInt(4)) {            case 0:                 field = board.getHexInDir(p.x, p.y, (direction + 5) % 6);                break;            case 1:                 field = board.getHexInDir(p.x, p.y, (direction + 1) % 6);                break;            default:                field = board.getHexInDir(p.x, p.y, direction);            break;            }                    } while (field != null);                 /* search the elevation for the river */        HashSet tmpRiverHexes = (HashSet)riverHexes.clone();        while (!tmpRiverHexes.isEmpty()) {            Iterator iter = tmpRiverHexes.iterator();            field = (IHex)iter.next();            if (field.getElevation() < minElevation) {                minElevation = field.getElevation();            }            tmpRiverHexes.remove(field);            Point thisHex = (Point)reverseHex.get(field);            /* and now the six neighbours */            for (int i = 0; i < 6; i++) {                field = board.getHexInDir(thisHex.x, thisHex.y, i);                if ((field != null) && (field.getElevation() < minElevation)) {                    minElevation = field.getElevation();                }                tmpRiverHexes.remove(field);            }        }                /* now adjust the elevation to same height */        Iterator iter = riverHexes.iterator();        while (iter.hasNext()) {            field = (IHex)iter.next();            field.setElevation(minElevation);        }                return;    }        /**      * Extends a river hex to left and right sides.     * @param hexloc The location of the river hex,     * from which it should get started.     * @param width The width to wich the river should extend in     * the direction. So the actual width of the river is     * 2*width+1.      * @param direction Direction too which the riverhexes should be     * extended.      * @return Hashset with the hexes from the side.     */    private static HashSet extendRiverToSide(IBoard board, Point hexloc, int width, int direction, HashMap reverseHex) {        Point current = new Point(hexloc);        HashSet result = new HashSet();        IHex hex;                hex = board.getHexInDir(current.x, current.y, direction);        while ((hex != null) && (width-- > 0)) {            hex.removeAllTerrains();            hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.WATER, 1));            result.add(hex);                    current = (Point)reverseHex.get(hex);            hex = board.getHexInDir(current.x, current.y, direction);        }                return result;    }            /** Flood negative hex levels      *  Shoreline / salt marshes effect     *  Works best with more elevation     */        protected static void PostProcessFlood(IHex[] hexSet, int modifier) {        int n;        IHex field;        ITerrainFactory f = Terrains.getTerrainFactory();        for (n=0;n<hexSet.length;n++) {            field = hexSet[n];            int elev = field.getElevation() - modifier;            if(elev == 0 &&               !(field.containsTerrain(Terrains.WATER)) &&               !(field.containsTerrain(Terrains.PAVEMENT))) {                field.addTerrain(f.createTerrain(Terrains.SWAMP,1));            } else if(elev < 0) {                if(elev < -4) elev=-4;                field.removeAllTerrains();                field.addTerrain(f.createTerrain(Terrains.WATER,-elev));                field.setElevation(modifier);            }        }                    }        /**      * Converts water hexes to ice hexes.     * Works best with snow&ice theme.     */    protected static void PostProcessDeepFreeze(IHex[] hexSet, int modifier) {        int n;        IHex field;        ITerrainFactory f = Terrains.getTerrainFactory();        for (n=0;n<hexSet.length;n++) {            field = hexSet[n];            if(field.containsTerrain(Terrains.WATER)) {                int level = field.terrainLevel(Terrains.WATER);                if(modifier != 0) {                    level -= modifier;                                    field.removeTerrain(Terrains.WATER);                    if(level > 0) {                        field.addTerrain(f.createTerrain(Terrains.WATER, level));                    }                }                field.addTerrain(f.createTerrain(Terrains.ICE,1));

⌨️ 快捷键说明

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