0

I am a beginner in Java as well as OOP. I am creating a simulator of "a box with particles". Here's what required in the program:

  1. A box with fixed WIDTH & HEIGHT with the pattern of "-" and " | "
  2. Particles with x, y position (0 <= x <= WIDTH; 0 <= y <= HEIGHT). Symbol: *
  3. Enum Direction of 8 directions
  4. move() all particles in random direction and create a new particle if any of them collide (same position)

What I've been strugging to find the answer is that how can I create random number of particles with a loop and can still work on them outside the loop? Because I want each created particle remain after an iteration for further move() execution. Is there any syntax for this kind of access?

Here's what I've tried as this sometimes output 2, 3 particles, sometimes none:

public Box() {
    particle = new Particle();
    for (int i = 0; i <= HEIGHT + 1; i++) {
        for (int j = 0; j <= WIDTH + 1; j++) {

            if (i == 0 || i == HEIGHT + 1 && i != particle.getY()){
                System.out.print("-");
            } else {
                if (j == particle.getX() && i == particle.getY()) {
                    System.out.print("*");
                } else if (j == 0 || j == WIDTH + 1 && j != particle.getX()) {
                    System.out.print("|");
                } else if (i != 0 && i != HEIGHT + 1) {
                    System.out.print(" ");
                }
            }
        }

        System.out.println("");

    }
    
}

1 Answers1

0

Coding is easier if you break the large task into smaller tasks.

I separated the creation of the particles from the display of the particles. That way, I could focus on one part of the task at a time.

Here's the output I generated.

|------------------|
|            *     |
|                  |
|  *   * *      *  |
|    *       *     |
|        * *       |
|  * * *      *    |
|      *           |
|           * *    |
|------------------|

All I did was generate the initial condition. I'm leaving it up to you to move the particles and check for collisions. I'm assuming that once a particular particle moves south, as an example, it continues south until it hits another particle or the wall. Hitting the wall would change the direction to north.

My Eclipse generated the hashCode and equals methods of the Particle class. These methods are essential for the Set contains method to work. I used a Set so there would be no duplicate particles. Because the particles are generated randomly, there might not be all maximum particles in the simulation.

In the generateParticles method, I get a random w between 1 and WIDTH - 1, inclusive, and a random h between 1 and HEIGHT -1, inclusive. This ensures that all particles created are inside the "box".

Here's the complete runnable example code.

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class ParticleSimulator {

    public static void main(String[] args) {
        ParticleSimulator ps = new ParticleSimulator();
        ps.displaySimulation();
    }
    
    private static int WIDTH = 20;
    private static int HEIGHT = 10;
    
    private Random random;
    
    private Set<Particle> particles;
    
    public ParticleSimulator() {
        this.random = new Random();
        this.particles = generateParticles(20);
    }
    
    private Set<Particle> generateParticles(int maximum) {
        Set<Particle> particles = new HashSet<>();
        for (int i = 0; i < maximum; i++) {
            int x = random.nextInt(WIDTH - 1) + 1;
            int y = random.nextInt(HEIGHT - 1) + 1;
            Particle particle = createParticle(x, y);
            particles.add(particle);
        }
        return particles;
    }
    
    public void displaySimulation() {
        for (int h = 0; h < HEIGHT; h++) {
            for (int w = 0; w < WIDTH; w++) {
                if (w == 0 || w == (WIDTH - 1)) {
                    System.out.print('|');
                    continue;
                }
                
                if (h == 0 || h == (HEIGHT - 1)) {
                    System.out.print('-');
                    continue;
                }
                
                Particle particle = createParticle(w, h);
                if (particles.contains(particle)) {
                    System.out.print('*');
                } else {
                    System.out.print(' ');
                }
            }
            System.out.println();
        }
    }
    
    private Particle createParticle(int x, int y) {
        Particle particle = new Particle();
        particle.setX(x);
        particle.setY(y);
        return particle;
    }
    
    public class Particle {
        
        private int x;
        private int y;
        
        public int getX() {
            return x;
        }
        
        public void setX(int x) {
            this.x = x;
        }
        
        public int getY() {
            return y;
        }
        
        public void setY(int y) {
            this.y = y;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + 
                    getEnclosingInstance().hashCode();
            result = prime * result + x;
            result = prime * result + y;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Particle other = (Particle) obj;
            if (!getEnclosingInstance().equals(
                    other.getEnclosingInstance()))
                return false;
            if (x != other.x)
                return false;
            if (y != other.y)
                return false;
            return true;
        }

        private ParticleSimulator getEnclosingInstance() {
            return ParticleSimulator.this;
        }
        
    }

}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111