Advertisement
MrMusAddict

COVID-19 Simulation

Mar 25th, 2020
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.59 KB | None | 0 0
  1. import com.hamoid.*;
  2. VideoExport videoExport;
  3.  
  4. ArrayList<Person> people;
  5. Boundary world;
  6. Boundary hospital;
  7.  
  8. int population = 2000;
  9. PopStats pStats;
  10.  
  11. int daysInfectedWithoutSymptoms = 3;
  12. int daysInfectedWithSymptoms = 7;
  13. int daysRecoveringButInfectious = 4;
  14.  
  15. int simTicksPerDay = 60;
  16.  
  17. int walkSpeed = 1;
  18.  
  19. float mortalityRate = 0.01;
  20.  
  21. boolean qStayIn = false;
  22. boolean qWithoutSymptoms = false;
  23. boolean qWithSymptoms = true;
  24. boolean qInRecovery = false;
  25.  
  26. boolean govReccomend = false;
  27. boolean govRecFinished = false;
  28. boolean govMandate = false;
  29. boolean govManFinished = false;
  30.  
  31. int recDayTicks = 28 * 60;
  32. int manDayTicks = 14 * 60;
  33.  
  34. int recTicks = 0;
  35. int manTicks = 0;
  36.  
  37. ArrayList<PopStats> graph = new ArrayList<PopStats>();
  38.  
  39. int FinishedTick = 0;
  40.  
  41. void setup() {
  42.   //fullScreen();
  43.   size(1400, 1600);
  44.   videoExport = new VideoExport(this);
  45.   videoExport.startMovie();
  46.  
  47.   world = new Boundary(0, 280, 1400, 1120);
  48.   people = new ArrayList<Person>();
  49.   for (int i = 0; i < population; i++) {
  50.     people.add(new Person(world));
  51.   }
  52.   people.get(0).setInfState(1);
  53.  
  54.   pStats = new PopStats();
  55.  
  56.   for (int i = 0; i < 1400; i++) {
  57.     graph.add(new PopStats());
  58.   }
  59. }
  60.  
  61. void draw() {
  62.   background(51);
  63.   world.show();
  64.   for (Person p : people) {    
  65.     p.update();
  66.     p.bounds();
  67.   }
  68.  
  69.   for (Person p : people) {
  70.     p.collide();
  71.     p.show();
  72.   }
  73.  
  74.   pStats.update();
  75.   graph.add(new PopStats());
  76.  
  77.   if (pStats.healthy + pStats.recd + pStats.dead == population) {
  78.     FinishedTick++;
  79.  
  80.     if (FinishedTick >= 300) {
  81.       videoExport.endMovie();
  82.       exit();
  83.     }
  84.   }
  85.  
  86.   graph.get(graph.size()-1).healthy = pStats.healthy;
  87.   graph.get(graph.size()-1).infWOSym = pStats.infWOSym;
  88.   graph.get(graph.size()-1).infWSym = pStats.infWSym;
  89.   graph.get(graph.size()-1).recWOSym = pStats.recWOSym;
  90.   graph.get(graph.size()-1).recd = pStats.recd;
  91.   graph.get(graph.size()-1).dead = pStats.dead;
  92.  
  93.   if (graph.size() > width) {
  94.     graph.remove(0);
  95.   }
  96.   println(graph.get(0).healthy/(population*1.0)*200 + ", " + graph.get(graph.size()-1).healthy/(population*1.0)*200 + ", " + graph.get((graph.size()-1)/2).healthy/(population*1.0)*200);
  97.  
  98.   for (int i = 0; i < graph.size()-1; i++) {
  99.     strokeWeight(1);    
  100.  
  101.     float s1 = (graph.get(i).healthy * 1.0) / (population*1.0) * 200.0;
  102.     float s2 = (graph.get(i).infWOSym * 1.0) / (population*1.0) * 200.0;
  103.     float s3 = (graph.get(i).infWSym * 1.0) / (population*1.0) * 200.0;
  104.     float s4 = (graph.get(i).recWOSym * 1.0) / (population*1.0) * 200.0;
  105.     float s5 = (graph.get(i).recd * 1.0) / (population*1.0) * 200.0;
  106.     float s6 = (graph.get(i).dead * 1.0) / (population*1.0) * 200.0;
  107.  
  108.     stroke(127, 127, 127);
  109.     line(i, 1400, i, 1400 + s1);
  110.     stroke(255, 255, 0);
  111.     line(i, 1400 + s1, i, 1400 + s1 + s2);
  112.     stroke(255, 0, 0);
  113.     line(i, 1400 + s1 + s2, i, 1400 + s1 + s2 + s3);
  114.     stroke(255, 0, 255);
  115.     line(i, 1400 + s1 + s2 + s3, i, 1400 + s1 + s2 + s3 + s4);
  116.     stroke(0, 0, 255);
  117.     line(i, 1400 + s1 + s2 + s3 + s4, i, 1400 + s1 + s2 + s3 + s4 + s5);
  118.     stroke(0, 0, 0);
  119.     line(i, 1400 + s1 + s2 + s3 + s4 + s5, i, 1400 + s1 + s2 + s3 + s4 + s5 + s6);
  120.   }
  121.  
  122.   if (govReccomend == true && govRecFinished == false && recTicks < recDayTicks) {
  123.     recTicks++;
  124.     if (recTicks >= recDayTicks) {
  125.       govReccomend = false;
  126.       govRecFinished = true;
  127.     }
  128.   }
  129.  
  130.  
  131.   if ((pStats.infWSym / 1.0) / (population / 1.0) > 0.02) {
  132.     if (!govRecFinished) {
  133.       govReccomend = true;
  134.     }
  135.   }
  136.  
  137.   if (govRecFinished) {
  138.     if (govMandate == true && govManFinished == false && manTicks < manDayTicks) {
  139.       manTicks++;
  140.       if (manTicks >= manDayTicks) {
  141.         govMandate = false;
  142.         govManFinished = true;
  143.       }
  144.     }
  145.  
  146.  
  147.     if ((pStats.infWSym / 1.0) / (population / 1.0) > 0.25) {
  148.       if (!govManFinished) {
  149.         govMandate = true;
  150.       }
  151.     }
  152.   }
  153.  
  154.   fill(255);
  155.   textSize(20);
  156.   text("Healthy: " + pStats.healthy, 10, 20);
  157.   text("Infected: " + (pStats.infWOSym + pStats.infWSym + pStats.recWOSym), 10, 45);
  158.   text("Showing Symptoms: " + pStats.infWSym + " (" + (round(pStats.infWSym / (population/1.0)*1000.0)/10.0) + "% of pop.)", 10, 70);
  159.   text("People showing symptoms stay home sick.", 450, 70);
  160.   text("Recovered: " + (pStats.recd), 10, 95);
  161.   text("Dead: " + (pStats.dead), 10, 120);
  162.  
  163.   if (govReccomend == true && govRecFinished == false) {
  164.     fill(255, 255, 0);
  165.     text("Stay-In reccomended by government. 60% of the population is adhering to the Stay-In.", 10, 160);
  166.     text(round((recDayTicks-recTicks)/(recDayTicks*1.0)*28.0) + " days of Stay-In remaining.", 10, 185);
  167.   }
  168.  
  169.   if (govMandate == true && govManFinished == false) {
  170.     fill(255, 0, 0);
  171.     text("Government Mandate issued. All of the population is adhering.", 10, 160);
  172.     text(round((manDayTicks-manTicks)/(manDayTicks*1.0)*14.0) + " days of mandate remaining.", 10, 185);
  173.   }
  174.  
  175.  
  176.   videoExport.saveFrame();
  177. }
  178.  
  179. class Person {
  180.   int infState;
  181.   /*
  182.   0 = Healthy
  183.    1 = Infected Without Symptoms
  184.    2 = Infected
  185.    3 = Recovering But Infectious
  186.    4 = Recovered
  187.    5 = Dead
  188.    */
  189.  
  190.   int isoState;
  191.   /*
  192.   0 = In Public
  193.    1 = At Home
  194.    3 = Hospitalized
  195.    4 = Dead
  196.    */
  197.  
  198.   int[] infTick = new int[6];
  199.  
  200.   int job; //0 = public, 1 = hospital
  201.  
  202.   PVector pos;
  203.   PVector vel;
  204.   Boundary bounds;
  205.  
  206.   color infCol;
  207.  
  208.   boolean socDist = false;
  209.  
  210.   boolean followRec;
  211.  
  212.   Person(Boundary b) {
  213.     infState = 0;
  214.     isoState = 0;
  215.     bounds = b;
  216.     pos = new PVector(random(bounds.right) + bounds.left, random(bounds.bottom) + bounds.top);
  217.     vel = new PVector(walkSpeed, 0).rotate(random(TWO_PI));
  218.  
  219.     infCol = color(127, 127, 127);
  220.  
  221.     followRec = random(1)>0.4;
  222.   }
  223.  
  224.   void update() {
  225.     infTick[infState] += 1;
  226.  
  227.     if (infState == 1 && infTick[1] >= daysInfectedWithoutSymptoms * simTicksPerDay) {
  228.       setInfState(2);
  229.     }
  230.  
  231.     if (infState == 2 && infTick[2] >= daysInfectedWithSymptoms * simTicksPerDay) {
  232.       setInfState(3);
  233.     }
  234.  
  235.     if (infState == 3 && infTick[3] >= daysRecoveringButInfectious * simTicksPerDay) {
  236.       setInfState(4);
  237.     }
  238.  
  239.     if (infState == 1 || infState == 2 || infState == 3) {
  240.       float mortalityCheck = random(1);
  241.       if (mortalityCheck <= 1.0 / ((daysInfectedWithoutSymptoms+daysInfectedWithSymptoms+daysRecoveringButInfectious) * simTicksPerDay / mortalityRate)) {
  242.         setInfState(5);
  243.       }
  244.     }
  245.  
  246.     if (!(socDist || govMandate || (followRec && govReccomend))) {
  247.       pos.x += vel.x;
  248.       pos.y += vel.y;
  249.     }
  250.   }
  251.  
  252.   void setInfState(int i) {
  253.     if (i == 1) {
  254.       infState = 1;
  255.       infCol = color(255, 255, 0);
  256.       socDist = qWithoutSymptoms || qStayIn;
  257.     }
  258.     if (i == 2) {
  259.       infState = 2;
  260.       infCol = color(255, 0, 0);
  261.       socDist = qWithSymptoms || qStayIn;
  262.     }
  263.     if (i == 3) {
  264.       infState = 3;
  265.       infCol = color(250, 0, 250);
  266.       socDist = qInRecovery || qStayIn;
  267.     }
  268.     if (i == 4) {
  269.       infState = 4;
  270.       infCol = color(0, 0, 255);
  271.       socDist = qStayIn;
  272.     }
  273.     if (i == 5) {
  274.       infState = 5;
  275.       infCol = color(0, 0, 0);
  276.       socDist = true;
  277.     }
  278.   }
  279.  
  280.   void bounds() {
  281.  
  282.     if (pos.x > bounds.left + bounds.right) {
  283.       pos.x = 2 * bounds.left + 2 * bounds.right - pos.x;
  284.       vel.x *= -1;
  285.     }
  286.     if (pos.y > bounds.top + bounds.bottom) {
  287.       pos.y = 2 * bounds.top + 2 * bounds.bottom - pos.y;
  288.       vel.y *= -1;
  289.     }
  290.     if (pos.x < bounds.left) {
  291.       pos.x = 2 * bounds.left - pos.x;
  292.       vel.x *= -1;
  293.     }
  294.     if (pos.y < bounds.top) {
  295.       pos.y = 2 * bounds.top - pos.y;
  296.       vel.y *= -1;
  297.     }
  298.   }
  299.  
  300.   void collide() {
  301.     boolean hit = false;
  302.     PVector newVel = new PVector(0, 0);
  303.     for (Person p : people) {
  304.       if (p != this && !(p.socDist || govMandate || (p.followRec && govReccomend))) {
  305.         if (!(socDist || govMandate || (followRec && govReccomend))) {
  306.           if (pos.dist(p.pos) < 10) {
  307.             fill(255, 0, 0);
  308.             hit = true;
  309.             PVector tempVel = new PVector(pos.x - p.pos.x, pos.y - p.pos.y).normalize();
  310.             newVel.x += tempVel.x;
  311.             newVel.y += tempVel.y;
  312.  
  313.             if (p.infState == 1 || p.infState == 2 || p.infState == 3) {
  314.               if (infState == 0) {
  315.                 setInfState(1);
  316.               }
  317.             }
  318.           }
  319.         }
  320.       }
  321.     }
  322.     if (hit) {
  323.       newVel.normalize().setMag(walkSpeed);
  324.       vel.x = newVel.x;
  325.       vel.y = newVel.y;
  326.     }
  327.   }
  328.  
  329.   void show() {
  330.     noStroke();
  331.     fill(infCol);
  332.     circle(pos.x, pos.y, 10);
  333.   }
  334. }
  335.  
  336. class Boundary {
  337.   float top;
  338.   float bottom;
  339.   float left;
  340.   float right;
  341.  
  342.   Boundary(float a, float b, float c, float d) {
  343.     left = a;
  344.     top = b;
  345.     right = c;
  346.     bottom = d;
  347.   }
  348.  
  349.   void show() {
  350.     stroke(255);
  351.     strokeWeight(5);
  352.     noFill();
  353.     rect(left, top, right, bottom);
  354.   }
  355. }
  356.  
  357. void keyPressed() {
  358.   if (key == 'q') {
  359.     videoExport.endMovie();
  360.     exit();
  361.   }
  362. }
  363.  
  364. class PopStats {
  365.   int healthy = population;
  366.   int infWOSym = 0;
  367.   int infWSym = 0;
  368.   int recWOSym = 0;
  369.   int recd = 0;
  370.   int dead = 0;
  371.  
  372.   void update() {
  373.     healthy = 0;
  374.     infWOSym = 0;
  375.     infWSym = 0;
  376.     recWOSym = 0;
  377.     recd = 0;
  378.     dead = 0;
  379.  
  380.     for (Person p : people) {
  381.       switch(p.infState) {
  382.       case 0:
  383.         healthy++;
  384.         break;
  385.       case 1:
  386.         infWOSym++;
  387.         break;
  388.       case 2:
  389.         infWSym++;
  390.         break;
  391.       case 3:
  392.         recWOSym++;
  393.         break;
  394.       case 4:
  395.         recd++;
  396.         break;
  397.       case 5:
  398.         dead++;
  399.         break;
  400.       }
  401.     }
  402.   }
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement