简体   繁体   中英

Assisstance with for loops / else-if statements in Java

In this code I am trying to simulate a forest fire starting in the top left corner of the grid. The fire has different percentages of spreading to the next tree based on its location. The code is intended to move to the next tree and if the tree to its left is on fire it has an 85% chance to spread, and a 35% chance to spread in all other directions. For some reason my third and fourth else-if statements are not working for spreading fire to the right or above it, it essentially ignores it and I am not sure why.

public class ForestFire {

    int[][] trees = new int [30][40];
    int fire = 1;
    int no_fire = 0;
    double fire_count = 0;
    double no_fire_count = 0;
    double total_fire_count = 0;
    double total_no_fire_count = 0;
    static int total = 10;
    double average = 0;
    int trial = 0;


    
    public void FireSpread() {
        for(int x = 0; x < total; x++) {
            for(int i = 0; i < trees.length; i++) {         
                for(int j = 0; j < trees[i].length; j++) {
                    double random = Math.random();
                    if(i == 0 && j == 0) {
                        trees[0][0] = fire;
                        System.out.print(trees[0][0] + " ");
                        fire_count++;
                        total_fire_count++;
                    }
                    else if((j-1) >= 0 && trees[i][j - 1] == fire && random < 0.85) {
                        trees[i][j] = fire;
                        System.out.print(trees[i][j] + " ");
                        fire_count++;
                        total_fire_count++;
                    }
                    else if((i-1) >= 0 && trees[i - 1][j] == fire && random < 0.35) {
                        trees[i][j] = fire;
                        System.out.print(trees[i][j] + " ");
                        fire_count++;
                        total_fire_count++;
                    }
                    else if((j+1) <= 39 && trees[i][j + 1] == fire && random < 0.35) {
                        trees[i][j] = fire;
                        System.out.print(trees[i][j] + " ");
                        fire_count++;
                        total_fire_count++;
                    }
                    else if((i+1) <= 29 && trees[i + 1][j] == fire && random < 0.35) {
                        trees[i][j] = fire;
                        System.out.print(trees[i][j] + " ");
                        fire_count++;
                        total_fire_count++;
                    }
                    else {
                        trees[i][j] = no_fire;
                        System.out.print(trees[i][j] + " ");
                        no_fire_count++;
                        total_no_fire_count++;
                    }
                    
                }
                System.out.println();
            }
            
            System.out.println();
            System.out.println("Fire Count: " + fire_count);
            System.out.println("No Fire Count: " + no_fire_count);
            System.out.println("Average: " + fire_count / 1200);
            if(fire_count > 480) {
                trial ++;
            }
            average += fire_count / 1200;
            System.out.println();
            for(int i = 0; i < trees.length; i++) {
                for(int j = 0; j < trees[i].length; j++) {
                    trees[i][j] = no_fire;
                }
            }
            fire_count = 0;
            no_fire_count = 0;
        }
        System.out.println("Above 40 Percent: " + trial);
        System.out.println("Total Fire Count: " + total_fire_count);
        System.out.println("Total No Fire Count: " + total_no_fire_count);
        System.out.println("Overall Average: " + average / total);

        System.out.println();

    }
    
    public double getFireCount() {
        return fire_count;
    }
    
    public double getNoFireCount() {
        return no_fire_count;
    }
    
    public double getTotalFireCount() {
        return total_fire_count;
    }
    
    public double getTotalNoFireCount() {
        return total_no_fire_count;
    }
    
    public static void main(String[] args) {
        ForestFire one = new ForestFire();
        one.FireSpread();
        System.out.println("Average Fire Count: " + one.getTotalFireCount() / total);
        System.out.println("Average No Fire Count: " + one.getTotalNoFireCount() / total);

    }
}

In general I recommend you learn to write unit tests and use an interactive debugger. Those 2 skills will resolve the vast majority of issues you face in coding.

The fundamental issue with your code is that in each step of your iteration you are writing the results of the simulation into the same array that you are reading the current state from. This makes the spread dependent on the way you happen to write your for loops (which is wrong). In general with simulations you need to create a new state for each step and then copy to current state at the end of the step. An easy check (which you should have in a unit test) is that at most 4 trees should catch fire in each step.

As an additional hint, you would make your code a lot easier to read and understand if you modelled the state as a set of positions that are on fire rather than an array that contains a value. This would make so much of the code simpler. Ideally your code to calculate next state from current state would look something like:

Set<Position> nextState = new HashSet<>(currentState);
for (Position fire: currentState) {
    for (Direction direction: Direction.values()) {
        Position neighbour = direction.move(fire);
        if (neighbour.inArea() && direction.shouldSpread())
            nextState.add(neighbour);
    }
}
currentState = nextState;

That encapsulates logic about which positions are in the area and probability of spread in Position and Direction classes rather than it all be in a single function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM