diff --git a/src/main/java/agents/RandomWalkingAgent.java b/src/main/java/agents/RandomWalkingAgent.java index 13457e0b1dc0060004060379f322892ebc54ee8e..78cdd180cdfb5ea806ea99c23d52e5d171b295d9 100644 --- a/src/main/java/agents/RandomWalkingAgent.java +++ b/src/main/java/agents/RandomWalkingAgent.java @@ -2,49 +2,62 @@ package agents; import agents.states.SEIRSState; import agents.states.SuceptibleSEIRSState; -import environment.ChunkedSEIRSEnvironment; import environment.SEIRSEnvironment; import utils.YamlReader; import java.awt.Point; +import java.security.SecureRandom; +import java.util.List; import java.util.Random; public class RandomWalkingAgent implements SEIRSAgent { protected Point position; - protected final Random r; + protected Random r; protected final SEIRSEnvironment environment; protected SEIRSState state; + private List<Point> authorizedPositions; + private Point nextPosition; + private int seed; + public RandomWalkingAgent(Point position, int seed, SEIRSEnvironment environment) { + this.seed = seed; this.position = position; this.state = new SuceptibleSEIRSState(this); this.environment = environment; - this.r = new Random(seed); + try{ + r = SecureRandom.getInstance("SHA1PRNG", "SUN"); + }catch (Exception e) { + System.err.println(e); + } + r.setSeed(seed); } private void move() { state.onMovement(); - int move = r.nextInt(4); - Point newPosition = switch (move) { - case SEIRSEnvironment.LEFT -> new Point(position.x- ChunkedSEIRSEnvironment.RADIUS,position.y); - case SEIRSEnvironment.RIGHT -> new Point(position.x+ ChunkedSEIRSEnvironment.RADIUS,position.y); - case SEIRSEnvironment.UP -> new Point(position.x,position.y- ChunkedSEIRSEnvironment.RADIUS); - case SEIRSEnvironment.DOWN -> new Point(position.x,position.y+ ChunkedSEIRSEnvironment.RADIUS); - default -> throw new IllegalStateException("Unexpected value: " + move); - }; - if (newPosition.x <= environment.getSize()-1 && newPosition.x >= 0 && newPosition.y <= environment.getSize()-1 && newPosition.y >=0 ) { - environment.notifyNewPosition(position,newPosition ,this); - position = newPosition; - } + environment.notifyNewPosition(nextPosition,this); + position = nextPosition; + } + + private void perceiveAuthorizedPositions() { + authorizedPositions = environment.perceiveAuthorizedPositions(this); + } + + private void decideNextMove() { + int next = r.nextInt(authorizedPositions.size()); + nextPosition = authorizedPositions.get(next); } @Override public void wakeUp() { - move(); + perceiveAuthorizedPositions(); + if (!authorizedPositions.isEmpty()) { + decideNextMove(); + move(); + } } - @Override public void changeState(SEIRSState SEIRSState) { this.state = SEIRSState; } diff --git a/src/main/java/environment/ChunkedSEIRSEnvironment.java b/src/main/java/environment/ChunkedSEIRSEnvironment.java index cf7e601697698f0169061d3639cd8632a5e71613..685281fe130f0a7826be35e866ecef12dbdbc4e4 100644 --- a/src/main/java/environment/ChunkedSEIRSEnvironment.java +++ b/src/main/java/environment/ChunkedSEIRSEnvironment.java @@ -78,15 +78,50 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment { return neighbors; } + private void wrapPosition(Point newPosition) { + if (newPosition.x >= size) { + newPosition.x -= size-1; + } + if (newPosition.x < 0) { + newPosition.x += size-1; + } + if (newPosition.y >= size) { + newPosition.y -= size-1; + } + if (newPosition.y < 0) { + newPosition.y +=size-1; + } + } + + public List<Point> perceiveAuthorizedPositions(Agent2D agent) { + List<Point> authorizedPosition = new ArrayList<>(); + + for (int move = 0; move < MAX_MOVEMENT; move++) { + Point position = switch (move) { + case LEFT -> new Point(agent.getPosition().x-RADIUS,agent.getPosition().y); + case RIGHT -> new Point (agent.getPosition().x+RADIUS,agent.getPosition().y); + case UP -> new Point(agent.getPosition().x, agent.getPosition().y-RADIUS); + case DOWN -> new Point(agent.getPosition().x, agent.getPosition().y +RADIUS); + default -> new Point(FORBIDDEN,FORBIDDEN); + }; + if (position.x < size && position.x >= 0 && position.y < size && position.y >= 0) { + authorizedPosition.add(position); + } + } + return authorizedPosition; + } + @Override - public void notifyNewPosition(Point oldPosition, Point newPosition, Agent2D agent) { + public void notifyNewPosition(Point newPosition, Agent2D agent) { if (chunks == null) { initiateChunks(); } + Point oldPosition = agent.getPosition(); if (oldPosition.x/CHUNK_SIZE != newPosition.x/CHUNK_SIZE || oldPosition.y/CHUNK_SIZE != newPosition.y/CHUNK_SIZE) { chunks[oldPosition.x/CHUNK_SIZE][oldPosition.y/CHUNK_SIZE].remove((SEIRSAgent) agent); chunks[newPosition.x/CHUNK_SIZE][newPosition.y/CHUNK_SIZE].add((SEIRSAgent) agent); } + //wrapPosition(newPosition); } @Override diff --git a/src/main/java/environment/Environment2D.java b/src/main/java/environment/Environment2D.java index d951d4f2b99f615d20e7a82a4330c35d039eb11b..531dac593f8d02961405f4cdcb9c868e898ac8d5 100644 --- a/src/main/java/environment/Environment2D.java +++ b/src/main/java/environment/Environment2D.java @@ -3,20 +3,24 @@ package environment; import agents.Agent2D; import java.awt.*; +import java.util.List; public interface Environment2D extends Environment { + int FORBIDDEN = -1; int LEFT = 0; int RIGHT = 1; int UP = 2; int DOWN = 3; int CENTER = 4; + int MAX_MOVEMENT = CENTER; int UP_LEFT = 5; int UP_RIGHT = 6; int DOWN_LEFT = 7; int DOWN_RIGHT = 8; int MAX_CHUNK = 9; - void notifyNewPosition(Point oldPosition, Point newPosition, Agent2D agent); + List<Point> perceiveAuthorizedPositions(Agent2D agent); + void notifyNewPosition(Point newPosition, Agent2D agent); int getSize(); } diff --git a/src/main/java/scheduler/FairSynchronousScheduler.java b/src/main/java/scheduler/FairSynchronousScheduler.java index e385320c24a0dfbf6a7a6a22176b136117c6d16e..e7bdd8726ec9f21b3e06ea02f5cb86ae95e0876e 100644 --- a/src/main/java/scheduler/FairSynchronousScheduler.java +++ b/src/main/java/scheduler/FairSynchronousScheduler.java @@ -2,16 +2,24 @@ package scheduler; import agents.Agent; +import java.nio.ByteBuffer; +import java.security.SecureRandom; import java.util.*; public class FairSynchronousScheduler implements Scheduler { private Agent[] agents; private Stack<Integer> executionOrder; - private final Random r; + private Random r; - public FairSynchronousScheduler(int seed) { - r = new Random(seed); + public FairSynchronousScheduler(Integer seed) { + + try{ + r = SecureRandom.getInstance("SHA1PRNG", "SUN"); + }catch (Exception e) { + System.err.println(e); + } + r.setSeed(seed); } private void generateExecutionOrder() { diff --git a/src/main/java/sma/SEIRS_SMA.java b/src/main/java/sma/SEIRS_SMA.java index d24884d8071fe22df7aab709cbd8dfa9051a99aa..d747d9e3dcdea40e17c9cd4c7d1c0898db6155df 100644 --- a/src/main/java/sma/SEIRS_SMA.java +++ b/src/main/java/sma/SEIRS_SMA.java @@ -18,6 +18,9 @@ import view.StatisticsCanvas; import java.awt.*; import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; import java.time.Duration; import java.time.Instant; import java.util.Date; @@ -33,7 +36,7 @@ public class SEIRS_SMA implements SMA{ private Scheduler scheduler; private StatisticsCanvas statisticsCanvas; private DisplaySquaredEnvironment display; - private Random r; + private SecureRandom r; private final FrameBuilder fb = new FrameBuilder(); private HashMap<String,Integer> stats; @@ -82,9 +85,9 @@ public class SEIRS_SMA implements SMA{ Point position = new Point(r.nextInt(parameters.getSize()),r.nextInt(parameters.getSize())); SEIRSAgent agent; if (parameters.isInfectionStacks()) { - agent = new RandomWalkingAgent(position,parameters.getSeed()+i,environment); + agent = new RandomWalkingAgent(position,(parameters.getSeed()+i),environment); } else { - agent = new FairInfectionRWAgent(position,parameters.getSeed()+i,environment); + agent = new FairInfectionRWAgent(position,(parameters.getSeed()+i),environment); } agents[i] = agent; } @@ -92,7 +95,8 @@ public class SEIRS_SMA implements SMA{ private void infectPatientZero() { for (int i=0 ; i< parameters.getNbOfPatientZero(); i++) { - SEIRSAgent agent = agents[(r.nextInt(parameters.getPopulation()))]; + int nextInt = (r.nextInt(parameters.getPopulation())); + SEIRSAgent agent = agents[nextInt]; while (agent.getState() instanceof InfectedSEIRSState) { agent = agents[(r.nextInt(parameters.getPopulation()))]; } @@ -113,7 +117,12 @@ public class SEIRS_SMA implements SMA{ @Override public void init() { parameters = YamlReader.getParams(); - r = new Random(parameters.getSeed()); + try{ + r = SecureRandom.getInstance("SHA1PRNG", "SUN"); + }catch (Exception e) { + System.err.println(e); + } + r.setSeed(parameters.getSeed()); agents = new RandomWalkingAgent[parameters.getPopulation()]; environment = new ChunkedSEIRSEnvironment(parameters.getSize(),agents); initPopulation(); diff --git a/src/main/resources/output.png b/src/main/resources/output.png index 9e9ed57bd7f7b957f9c77d2d984f237a29fcfc28..e7519955ea48feef9451aeeff9c5f41088f39f69 100644 Binary files a/src/main/resources/output.png and b/src/main/resources/output.png differ diff --git a/src/main/resources/parameters.yaml b/src/main/resources/parameters.yaml index d85b817cdad88272de26dcc0a419caea7b75f634..7550017412ecc4a8acc98c8631f4a0b6c15c8820 100644 --- a/src/main/resources/parameters.yaml +++ b/src/main/resources/parameters.yaml @@ -1,6 +1,6 @@ graphicalMode: true incubationRate: 0.3 -infectionRate: 0.75 +infectionRate: 1 looseImmunityRate: 0.008 recoveryRate: 0.1429 nbOfCycles: 2000 @@ -9,5 +9,5 @@ population: 3000 seed: 120 size: 1000 synchronousMode: false -timeBetweenCycles: 0 +timeBetweenCycles: 10 infectionStacks : true \ No newline at end of file