|
Post by Brandon Parker on Mar 21, 2020 12:02:11 GMT -5
So, the line that kept track of the maxSickCount was logically incorrect and causing the maxSickCount to be lower than the recoCount. This bothered me so much since I initially thought something was wrong with recoCount, but there was no issue there; it was with the maxSickCount line below.
if (sickCount > maxSickCount) then maxSickCount = sickCount
The problem is that sickCount does not always go up. It can start going down when individuals start to be moved to recoCount. When that occured, the next uptick in sickCount would not cause the maxSickCount to tick up until sickCount exceeded maxSickCount again. To resolve the issue I just removed the line above and added an increment of maxSickCount to both spots where sickCount is incremented.
NoMainWin
Struct oldValues, maxSickCount As ptr, _ wellCount As ptr, _ sickCount As ptr, _ recoCount As ptr, _ mortalityCount As ptr
population=100 'population seeds=5 'number of starting sick transferRate=0.40'probability of contracting on contact recoCount=0'number of sims that were sick but recovered fractionStationary=0.45 daysInfectious=21 immunePercentage = 2 mortalityPercentage = 10 'Mortality numbers to be tracked by mortalityCount
Confirm "Would you like to change any of the default values?";responseVar$ If (Upper$(responseVar$) = "YES") Then prompt "Population: ";population prompt "Seeds: ";seeds prompt "Percentage with Natural Immunity: ";immunePercentage
prompt "Stationary fraction: ";fractionStationary prompt "Transfer on contact fraction: ";transferRate prompt "Days infectious: ";daysInfectious avgDaysUntilMortality = (daysInfectious - 1) prompt "Mortality Percentage : ";mortalityPercentage prompt "Days until Mortality : ";avgDaysUntilMortality End If
population = Max(population, seeds) immunePercentage = Min(immunePercentage, (100 - (100 * (seeds/ population)))) avgDaysUntilMortality = (daysInfectious - 1) sickCount = seeds maxSickCount = sickCount wellCount=population-seeds mortalityCountMax = Int(seeds * (mortalityPercentage/ 100))
WindowWidth=800 WindowHeight=600 UpperLeftX = Int((DisplayWidth - WindowWidth)/ 2) UpperLeftY = Int((DisplayHeight - WindowHeight)/ 2)
graphicbox #1.g, 1, 1, 500, 500 graphicbox #1.t1, 1, 501, 800, 100 graphicbox #1.t2, 501, 1, 300, 245 texteditor #1.txt, 501, 245, 300, 255 open "COVID-19 Simulation" for graphics_nf_nsb as #1 #1.g "fill white;flush" #1.t1 "fill darkblue;flush" #1.t2 "fill black;flush" #1 "trapclose [q]"
dim sim(population,10)'500 sims, 10 parameters each '1=x location '2=y location '3=x velocity '4=y velocity '5=wellness parameter (0=well, 1=sick, 2=recovered, 3 = dead) '6=time since initial infection '7 = Natural Immunity
'set initial paramaters 'random location for a =1 to population sim(a,1)=int(rnd(1)*450)+20 sim(a,2)=int(rnd(1)*450)+20 sim(a,3)=(0.5-rnd(1))*5 if sim(a,3)<1 and sim(a,3)>-1 then if sim(a,3)<1 then sim(a,3)=sim(a,3)-2 if sim(a,3)>1 then sim(a,3)=sim(a,3)+2 end if sim(a,4)=(0.5-rnd(1))*5 if sim(a,4)<1 and sim(a,4)>-1 then if sim(a,4)<1 then sim(a,4)=sim(a,4)-2 if sim(a,4)>1 then sim(a,4)=sim(a,4)+2 end if if (a/population)<fractionStationary then sim(a,3)=0:sim(a,4)=0 next a
'make sprites #1.t2 "down;place 1 1;color white;backcolor white;boxfilled 10 10;place 5 5;backcolor black;color black;circlefilled 5;place 5 15;color green;backcolor green;circlefilled 5" #1.t2 "getbmp well 1 1 8 20" #1.t2 "color red;backcolor red;circlefilled 4" #1.t2 "getbmp sick 1 1 8 20" #1.t2 "color blue;backcolor blue;circlefilled 4" #1.t2 "getbmp reco 1 1 8 20"
#1.t2 "color Yellow;backcolor Yellow;circlefilled 4" #1.t2 "getbmp immune 1 1 8 20"
#1.t2 "color Black;backcolor Black;circlefilled 4" #1.t2 "getbmp dead 1 1 8 20"
#1.g "getbmp bg 1 1 500 500" #1.g "background bg" #1.g "drawbmp well 10 10;drawbmp sick 40 40;drawbmp reco 80 80;drawbmp immune 120 120; drawbmp dead 160 160"
for a = 1 to population #1.g "addsprite sim";a;" well sick reco immune dead" #1.g "spritexy sim";a;" ";sim(a,1);" ";sim(a,2) #1.g "spritemovexy sim";a;" ";sim(a,3);" ";sim(a,4) next a
for a = 1 to seeds ' seed sick people with random times since infection sim(a,5)=1 sim(a,6)=Int((rnd(1)*24*daysInfectious) + 0.5) 'rnd(1)*14*24 #1.g "spriteimage sim";a;" sick" next a
For i = 0 To ((population * (immunePercentage/ 100)) - 1) element = Int((rnd(1) * population) + 0.4) If (sim(element, 7) = 0) And (sim(element, 5) = 0) Then sim(element, 7) = 1 #1.g "spriteimage sim";element;" immune" immunePersons = (immunePersons + 1) Else i = (i - 1) End If Next i
#1.g "drawsprites" #1.t2 "cls; fill white;flush"
timer 1, [animate] wait
[animate] scan if sickCount<=0 then waitCount=waitCount+1 if waitCount>0 then timer 0 goto [endSim] end if end if hours=hours+1 #1.g "drawsprites" For a = 1 To population If (sim(a,5) = 1) Then If (sim(a,6) > 0) Then 'decrement time sick sim(a,6) = sim(a,6) - 1 If (sim(a,6) = 0) And Not(sickCount = (mortalityCountMax - mortalityCount)) Then sim(a,5) = 2 'move to reco #1.g "spriteimage sim";a;" reco" recoCount = (recoCount + 1) sickCount = (sickCount - 1) Else If (sim(a,6) <= ((daysInfectious - avgDaysUntilMortality) * 24)) Then If ((rnd(1) * maxSickCount) >= (population - (maxSickCount * (mortalityPercentage/ 100))) And (mortalityCount < mortalityCountMax)) _ Or (sickCount = (mortalityCountMax - mortalityCount)) Then 'Make Dead here sim(a,5) = 3 #1.g "spritemovexy sim";a;" 0 0" sim(a,3) = 0 : sim(a,4) = 0 #1.g "spriteimage sim";a;" dead" mortalityCount = (mortalityCount + 1) sickCount = (sickCount - 1) End If End If End If End If End If
#1.g "spritexy? sim";a;" x y" #1.g "spritecollides sim";a;" col$" If col$<>"" Then If rnd(1)<0.5 Then sim(a,3)=sim(a,3)*(-1) 'change direction If rnd(1)<0.5 Then sim(a,4)=sim(a,4)*(-1) 'change direction
col=val(left$(after$(col$,"sim"),2)) 'get the colliding sim If sim(a,5)=1 And sim(col,5)=0 And rnd(1)<transferRate And (sim(col,7) = 0) Then 'move from well to sick sim(col,5)=1:sim(col,6)=daysInfectious*24 #1.g "spriteimage sim";col;" sick" wellCount = (wellCount - 1) sickCount = (sickCount + 1) maxSickCount = (maxSickCount + 1) Else If sim(a,5)=0 And sim(col,5)=1 And rnd(1)<transferRate And (sim(a,7) = 0) Then sim(a,5)=1:sim(a,6)=daysInfectious*24 'move from well to sick #1.g "spriteimage sim";a;" sick" wellCount = (wellCount - 1) sickCount = (sickCount + 1) maxSickCount = (maxSickCount + 1) End If End If End If
If (sim(a,5) < 3) Then if ((x >= 480) or (x <= 10)) Or (Int(rnd(1) + 0.01) >= 1) then sim(a,3)=sim(a,3)*(-1) 'change direction at perimeter if ((y >= 480) or (y <= 10)) Or (Int(rnd(1) + 0.01) >= 1) then sim(a,4)=sim(a,4)*(-1) 'change direction at perimeter #1.g "spritemovexy sim";a;" ";sim(a,3);" ";sim(a,4) End If next a
mortalityCountMax = Int(maxSickCount * (mortalityPercentage/ 100)) #1.t1, "place 10 40;\Time: ";hours;" Well: ";wellCount;" Sick: ";sickCount;" Reco: ";recoCount;" Immune: ";immunePersons;" Dead: ";mortalityCount;" " '#1.t2 "discard;cls" #1.t2, "place 30 105;backcolor white;color black;boxfilled 60 5" #1.t2, "place 60 105;backcolor white;color black;boxfilled 90 5" #1.t2, "place 90 105;backcolor white;color black;boxfilled 120 5" #1.t2, "place 120 105;backcolor white;color black;boxfilled 150 5" #1.t2, "place 60 105;backcolor pink;color black;boxfilled 90 ";105-(100*maxSickCount/population)
#1.t2, "place 30 105;backcolor green;color black;boxfilled 60 ";105-(100*wellCount/population) #1.t2, "place 60 105;backcolor red;color black;boxfilled 90 ";105-(100*sickCount/population) #1.t2, "place 90 105;backcolor blue;color black;boxfilled 120 ";105-(100*recoCount/population) #1.t2, "place 120 105;backcolor black;color black;boxfilled 150 ";105-(100*mortalityCount/population)
#1.t2 "Color Black; BackColor White; Place 30 220; GoTo 30 120" #1.t2 "Place 30 220; GoTo 280 220" 'Keep a time coordinate since it is use so much below....tired of changing it each time I adjust something :) xTimeCoord = (30 + (hours/ 24)) If (hours = 1) Then 'Draw some axis lines #1.t2 "Place 5 ";220-(100*wellCount/population);"; Size 1" #1.t2 "|";population #1.t2 "Place 5 ";(230 - ((230 - (220-(100*wellCount/population)))/ 2)) #1.t2 "|";(population/ 2) #1.t2 "Place 20 235" #1.t2 "|0" 'Added some labels down here as welld #1.t2 "Place 160 12" #1.t2 "|Color Legend" #1.t2 "Place 160 14; GoTo 250 14" #1.t2, "color pink; set ";xTimeCoord;" ";220-(100*maxSickCount/population) oldValues.maxSickCount.struct = xTimeCoord;" ";220-(100*maxSickCount/population) #1.t2 "Place 160 60" #1.t2 "|Pink = Max Sick" #1.t2, "color green; set ";xTimeCoord;" ";220-(100*wellCount/population) oldValues.wellCount.struct = xTimeCoord;" ";220-(100*wellCount/population) #1.t2 "Place 160 30" #1.t2 "|Green = Well" #1.t2, "color red; set ";xTimeCoord;" ";220-(100*sickCount/population) oldValues.sickCount.struct = xTimeCoord;" ";220-(100*sickCount/population) #1.t2 "Place 160 45" #1.t2 "|Red = Sick" #1.t2, "color blue; set ";xTimeCoord;" ";220-(100*recoCount/population) oldValues.recoCount.struct = xTimeCoord;" ";220-(100*recoCount/population) #1.t2 "Place 160 75" #1.t2 "|Blue = Recovered" #1.t2, "color black; set ";xTimeCoord;" ";220-(100*mortalityCount/population) oldValues.mortalityCount.struct = xTimeCoord;" ";220-(100*mortalityCount/population) #1.t2 "Place 160 90" #1.t2 "|Black = Mortality" Else 'Adds a tick mark at each week If ((hours Mod (24 * 7)) = 0) Then #1.t2 "Place ";xTimeCoord;" 220; GoTo ";xTimeCoord;" 225" End If #1.t2 "color pink; place ";Winstring(oldValues.maxSickCount.struct);"; GoTo ";xTimeCoord;" ";220-(100*maxSickCount/population) oldValues.maxSickCount.struct = xTimeCoord;" ";220-(100*maxSickCount/population) #1.t2 "color green; place ";Winstring(oldValues.wellCount.struct);"; GoTo ";xTimeCoord;" ";220-(100*wellCount/population) oldValues.wellCount.struct = xTimeCoord;" ";220-(100*wellCount/population) #1.t2 "color red; place ";Winstring(oldValues.sickCount.struct);"; GoTo ";xTimeCoord;" ";220-(100*sickCount/population) oldValues.sickCount.struct = xTimeCoord;" ";220-(100*sickCount/population) #1.t2 "color blue; place ";Winstring(oldValues.recoCount.struct);"; GoTo ";xTimeCoord;" ";220-(100*recoCount/population) oldValues.recoCount.struct = xTimeCoord;" ";220-(100*recoCount/population) #1.t2 "color black; place ";Winstring(oldValues.mortalityCount.struct);"; GoTo ";xTimeCoord;" ";220-(100*mortalityCount/population) oldValues.mortalityCount.struct = xTimeCoord;" ";220-(100*mortalityCount/population) End If Wait
[endSim] 'Display the number of weeks passed and account for the extra 50 hours at the end of the simulation #1.t2 "Place ";(xTimeCoord - (50/ 24));" 235" #1.t2 "|";Using("#####.##",((hours - 50)/ (24 * 7)));" Weeks" #1.t2, "flush" timer 0 print #1.txt, "Simulation Complete" print #1.txt, "Population: ";population print #1.txt, "Seed sick: ";seeds Print #1.txt, "Immune Persons: ";immunePersons print #1.txt, "Stationary: ";fractionStationary print #1.txt, "Tran rate: ";transferRate print #1.txt, "Days infec: ";daysInfectious print #1.txt,"" print #1.txt, "Hrs of end: ";hours print #1.txt, "% Recovered ";((recoCount/ maxSickCount) * 100);"%" print #1.txt, "Max % sick: ";((maxSickCount/ population) * 100);"%" 'print "------------------------" wait
[q] timer 0 unloadbmp "well" unloadbmp "sick" unloadbmp "reco" #1.g "cls;discard" #1.t1 "cls;discard" #1.t2 "cls;discard" close #1 end
{:0)
Brandon Parker
|
|
|
Post by David Drake on Mar 21, 2020 14:27:44 GMT -5
Well, my intent with the maxSickCount was to simulate the maximum instantaneous burden on healthcare. If the number stays low, you have “flattened the curve” as they are saying today. So I think the variable captures what I originally tried to do.
|
|
|
Post by Brandon Parker on Mar 21, 2020 20:37:56 GMT -5
Fair enough ...
I had viewed it differently.
On that note, I have taken everything rewritten it in my style of programming. I am not a fan of labels (except for exception trapping within Subs/ Functions). Also, I try to shy away from the Timer as much as possible due to the ticks building up if the routine takes longer than the Timer's interval. I'm not saying anything is wrong with either, but I wanted to do a few things with the simulation and stuff was getting in the way.
Here is my updated version. It comes with the ability to "Shelter in Place", "Allow Movement", and "Restart Simulation" as these are things I wanted it to do. You can "Shelter in Place" and "Allow Movement" back and forth to see how it affects the graphs/outcome.
I used a structure for all of the variables since I like how it keeps them together (... In my mind anyway ...). My style is not for everyone, but I definitely like how it turned out.
I might find some time to add some more features at some point soon ...
NoMainWin Dim entity(0, 0) Global CRLF$ : CRLF$ = chr$(13);chr$(10) Struct simulationValues, population As long, _ seeds As long, _ transferRate As long, _ wellCount As long, _ sickCount As long, _ maxSickCount As long, _ recoCount As long, _ immunePersons As long, _ percentStationary As long, _ daysInfectious As long, _ immunityPercentage As long, _ mortalityPercentage As long, _ mortalityCount AS long, _ mortalityCountMax AS long, _ avgDaysUntilMortality As long, _ hours As long, _ xTimeCoord As long, _ waitCount As long, _ shelterInPlace As boolean, _ simulationStatus AS boolean
Struct oldValues, maxSickCount As ptr, _ wellCount As ptr, _ sickCount As ptr, _ recoCount As ptr, _ mortalityCount As ptr
Call initializeDefaultValues Call changeDefaultValues Call openSimulationWindow Call initializeEntities Call initializeSprites
simulationValues.simulationStatus.struct = 1
While Hwnd(#Simulation) Scan If (simulationValues.simulationStatus.struct = 1) Then Call animateSimulation End If result = Sleep(1) Wend
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub openSimulationWindow WindowWidth = 805 WindowHeight = 620 UpperLeftX = Int((DisplayWidth - WindowWidth)/ 2) UpperLeftY = Int((DisplayHeight - WindowHeight)/ 2)
GraphicBox #Simulation.gBoxSim, 1, 1, 500, 520 GraphicBox #Simulation.gBoxInfo, 1, 521, 645, 100 GraphicBox #Simulation.gBoxGraphs, 501, 1, 300, 245 TextEditor #Simulation.txtEdOutput, 501, 245, 300, 275 Button #Simulation.btnShelterInPlace, "Shelter In Place", shelterInPlace, UL, 657, 527 , 125, 25 Button #Simulation.btnRestartSimulation, "Restart Simulation", restartSimulation, UL, 657, 557 , 130, 25 Open "COVID-19 Simulation" For graphics_nf_nsb As #Simulation #Simulation.gBoxSim "Fill White; Flush" #Simulation.gBoxInfo "Fill DarkBlue; Flush" #Simulation.gBoxGraphs "Fill White; Flush" #Simulation.txtEdOutput "Simulation Started!";CRLF$ #Simulation "TrapClose quitSimulation" #Simulation.btnShelterInPlace "!SetFocus" End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub animateSimulation If (simulationValues.sickCount.struct <= 0) Then simulationValues.waitCount.struct = (simulationValues.waitCount.struct + 1) If (simulationValues.waitCount.struct > 0) Then Call endSimulation End If End If simulationValues.hours.struct = (simulationValues.hours.struct + 1) #Simulation.gBoxSim "DrawSprites" For i = 0 To (simulationValues.population.struct - 1) If (entity(i, 5) = 1) Then If (entity(i, 6) > 0) Then 'decrement time sick entity(i, 6) = (entity(i, 6) - 1) If (entity(i, 6) = 0) And Not(simulationValues.sickCount.struct = (simulationValues.mortalityCountMax.struct - simulationValues.mortalityCount.struct)) Then entity(i, 5) = 2 'move to reco #Simulation.gBoxSim "SpriteImage simEntity";i;" reco" simulationValues.recoCount.struct = (simulationValues.recoCount.struct + 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct - 1) Else If (entity(i, 6) <= ((simulationValues.daysInfectious.struct - simulationValues.avgDaysUntilMortality.struct) * 24)) Then If ((rnd(1) * simulationValues.maxSickCount.struct) >= (simulationValues.population.struct.struct - (simulationValues.maxSickCount.struct * (simulationValues.mortalityPercentage.struct/ 100))) And (simulationValues.mortalityCount.struct < simulationValues.mortalityCountMax.struct)) _ Or (simulationValues.sickCount.struct = (simulationValues.mortalityCountMax.struct - simulationValues.mortalityCount.struct)) Then 'Make Dead here entity(i, 5) = 3 #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" 0 0" entity(i, 3) = 0 : entity(i, 4) = 0 #Simulation.gBoxSim "SpriteImage simEntity";i;" dead" simulationValues.mortalityCount.struct = (simulationValues.mortalityCount.struct + 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct - 1) End If End If End If End If End If
#Simulation.gBoxSim "SpriteXY? simEntity";i;" x y" #Simulation.gBoxSim "SpriteCollides simEntity";i;" col$" If (col$ <> "") Then If (Rnd(1) < 0.5) Then entity(i, 3) = (entity(i, 3) * (-1)) 'change direction If (Rnd(1) < 0.5) Then entity(i, 4) = (entity(i, 4) * (-1)) 'change direction
col = Val(Left$(After$(col$,"simEntity"), 2)) 'get the colliding simEntity If (entity(i, 5) = 1) And (entity(col, 5) = 0) And (Rnd(1) < (simulationValues.transferRate.struct/ 100)) And (entity(col, 7) = 0) Then 'move from well to sick entity(col, 5) = 1 : entity(col, 6) = (simulationValues.daysInfectious.struct * 24) #Simulation.gBoxSim "SpriteImage simEntity";col;" sick" simulationValues.wellCount.struct = (simulationValues.wellCount.struct - 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct + 1) simulationValues.maxSickCount.struct = (simulationValues.maxSickCount.struct + 1) Else If (entity(i, 5) = 0) And (entity(col, 5) = 1) And (Rnd(1) < (simulationValues.transferRate.struct/ 100)) And (entity(i, 7) = 0) Then entity(i,5) = 1 : entity(i, 6) = (simulationValues.daysInfectious.struct * 24) 'move from well to sick #Simulation.gBoxSim "SpriteImage simEntity";i;" sick" simulationValues.wellCount.struct = (simulationValues.wellCount.struct - 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct + 1) simulationValues.maxSickCount.struct = (simulationValues.maxSickCount.struct + 1) End If End If End If
If (entity(i, 5) < 3) And Not(simulationValues.shelterInPlace.struct) Then If ((x >= 480) Or (x <= 10)) Or (Int(Rnd(1) + 0.01) >= 1) Then entity(i, 3) = (entity(i, 3) * (-1)) 'change direction at perimeter If ((y >= 500) Or (y <= 10)) Or (Int(Rnd(1) + 0.01) >= 1) Then entity(i, 4) = (entity(i, 4) * (-1)) 'change direction at perimeter #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" ";entity(i, 3);" ";entity(i, 4) End If Next i
simulationValues.mortalityCountMax.struct = Int(simulationValues.maxSickCount.struct * (simulationValues.mortalityPercentage.struct/ 100)) #Simulation.gBoxInfo, "Place 10 40;\Time: ";simulationValues.hours.struct;" Well: ";simulationValues.wellCount.struct;" Sick: ";simulationValues.sickCount.struct;" Reco: "; _ simulationValues.recoCount.struct;" Immune: ";simulationValues.immunePersons.struct;" Dead: ";simulationValues.mortalityCount.struct;" " '#Simulation.gBoxGraphs "discard;cls" #Simulation.gBoxGraphs, "Place 30 105; BackColor White; Color Black; BoxFilled 60 5" #Simulation.gBoxGraphs, "Place 60 105; BackColor White; Color Black; BoxFilled 90 5" #Simulation.gBoxGraphs, "Place 90 105; BackColor White; Color Black; BoxFilled 120 5" #Simulation.gBoxGraphs, "Place 120 105; BackColor White; Color Black; BoxFilled 150 5" #Simulation.gBoxGraphs, "Place 60 105; BackColor Pink; Color Black; BoxFilled 90 ";(105 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct))
#Simulation.gBoxGraphs, "Place 30 105; BackColor Green; Color Black; BoxFilled 60 ";(105 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs, "Place 60 105; BackColor Red; Color Black; BoxFilled 90 ";(105 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs, "Place 90 105; BackColor Blue; Color Black; BoxFilled 120 ";(105 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs, "Place 120 105; BackColor Black; Color Black; BoxFilled 150 ";(105 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct))
#Simulation.gBoxGraphs "Color Black; BackColor White; Place 30 220; GoTo 30 120" #Simulation.gBoxGraphs "Place 30 220; GoTo 280 220" 'Keep a time coordinate since it is use so much below....tired of changing it each time I adjust something :) simulationValues.xTimeCoord.struct = (30 + (simulationValues.hours.struct/ 24)) If (simulationValues.hours.struct = 1) Then 'Draw some axis lines #Simulation.gBoxGraphs "Place 5 ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct));"; Size 1" #Simulation.gBoxGraphs "|";simulationValues.population.struct #Simulation.gBoxGraphs "Place 5 ";(230 - ((230 - (220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)))/ 2)) #Simulation.gBoxGraphs "|";(simulationValues.population.struct/ 2) #Simulation.gBoxGraphs "Place 20 235" #Simulation.gBoxGraphs "|0" 'Added some labels down here as welld #Simulation.gBoxGraphs "Place 160 12" #Simulation.gBoxGraphs "|Color Legend" #Simulation.gBoxGraphs "Place 160 14; GoTo 250 14" #Simulation.gBoxGraphs, "Color Pink; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) oldValues.maxSickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 60" #Simulation.gBoxGraphs "|Pink = Max Sick" #Simulation.gBoxGraphs, "Color Green; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) oldValues.wellCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 30" #Simulation.gBoxGraphs "|Green = Well" #Simulation.gBoxGraphs, "Color Red; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) oldValues.sickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 45" #Simulation.gBoxGraphs "|Red = Sick" #Simulation.gBoxGraphs, "Color Blue; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) oldValues.recoCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 75" #Simulation.gBoxGraphs "|Blue = Recovered" #Simulation.gBoxGraphs, "Color Black; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) oldValues.mortalityCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 90" #Simulation.gBoxGraphs "|Black = Mortality" Else 'Adds a tick mark at each week If ((simulationValues.hours.struct Mod (24 * 7)) = 0) Then #Simulation.gBoxGraphs "Place ";simulationValues.xTimeCoord.struct;" 220; GoTo ";simulationValues.xTimeCoord.struct;" 225" End If #Simulation.gBoxGraphs "Color Pink; Place ";Winstring(oldValues.maxSickCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) oldValues.maxSickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Green; Place ";Winstring(oldValues.wellCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) oldValues.wellCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Red; Place ";Winstring(oldValues.sickCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) oldValues.sickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Blue; Place ";Winstring(oldValues.recoCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 -(100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) oldValues.recoCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Black; Place ";Winstring(oldValues.mortalityCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) oldValues.mortalityCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) End If End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub endSimulation 'Display the number of weeks passed and account for the extra 50 hours at the end of the simulation #Simulation.gBoxGraphs "Place ";Min(200, (simulationValues.xTimeCoord.struct - (50/ 24)));" 237" #Simulation.gBoxGraphs "|";Using("#####.##",((simulationValues.hours.struct - 50)/ (24 * 7)));" Weeks" #Simulation.gBoxSim "GetBMP finishedSim 0 0 501 521; Place 0 0; DrawBMP finishedSim; Flush finishedSim" #Simulation.gBoxInfo "Flush" #Simulation.gBoxGraphs "Flush" #Simulation.txtEdOutput CRLF$;"Population: ";simulationValues.population.struct #Simulation.txtEdOutput "Infected Seeds: ";simulationValues.seeds.struct #Simulation.txtEdOutput "Immune Persons: ";simulationValues.immunePersons.struct #Simulation.txtEdOutput "Initial Stationary %: ";Using("#####.##",simulationValues.percentStationary.struct) #Simulation.txtEdOutput "Transmission Rate: ";Using("#####.##",simulationValues.transferRate.struct) #Simulation.txtEdOutput "Days Infectious: ";simulationValues.daysInfectious.struct;CRLF$ #Simulation.txtEdOutput "Outbreak Duration: ";(simulationValues.hours.struct - 50);" Hrs" #Simulation.txtEdOutput "Recovery %: ";Using("#####.##",((simulationValues.recoCount.struct/ simulationValues.maxSickCount.struct) * 100));" %" #Simulation.txtEdOutput "Max % Sick: ";Using("#####.##",((simulationValues.maxSickCount.struct/ simulationValues.population.struct) * 100));" %"
#Simulation.txtEdOutput "Mortality %: ";Using("#####.##",((simulationValues.mortalityCount.struct/ simulationValues.maxSickCount.struct) * 100));" %";CRLF$ #Simulation.txtEdOutput "Simulation Complete!" #Simulation.btnShelterInPlace "!Disable" simulationValues.simulationStatus.struct = 0 End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub quitSimulation handle$ If isBitMap("bg") Then UnloadBMP "bg" If isBitMap("well") Then UnloadBMP "well" If isBitMap("sick") Then UnloadBMP "sick" If isBitMap("reco") Then UnloadBMP "reco" If isBitMap("immune") Then UnloadBMP "immune" If isBitMap("dead") Then UnloadBMP "dead" If isBitMap("finishedSim") Then UnloadBMP "finishedSim" #Simulation.gBoxSim "CLS; Discard" #Simulation.gBoxInfo "CLS; Discard" #Simulation.gBoxGraphs "CLS; Discard" Close #handle$ End End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub shelterInPlace handle$ If Not(simulationValues.shelterInPlace.struct) Then For i = 0 to (simulationValues.population.struct - 1) #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" 0 0" 'entity(i, 3) = 0 : entity(i, 4) = 0 Next i simulationValues.shelterInPlace.struct = 1 #Simulation.btnShelterInPlace "Allow Movement" #Simulation.txtEdOutput "All Persons Sheltered in Place!"
Else simulationValues.shelterInPlace.struct = 0 #Simulation.btnShelterInPlace, "Shelter In Place" #Simulation.txtEdOutput "Movement Allowed!" End If End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub restartSimulation handle$ For i = 0 to (simulationValues.population.struct - 1) #Simulation.gBoxSim "RemoveSprite simEntity";i Next i #Simulation.gBoxSim "DelSegment finishedSim" #Simulation.gBoxSim "CLS; Discard" #Simulation.gBoxInfo "CLS; Discard" #Simulation.gBoxGraphs "CLS; Discard" #Simulation.gBoxSim "Fill White; Flush" #Simulation.gBoxInfo "Fill DarkBlue; Flush" #Simulation.gBoxGraphs "Fill White; Flush" #Simulation.txtEdOutput "!CLS" #Simulation.txtEdOutput "Simulation Restarted!";CRLF$ #Simulation.btnShelterInPlace "Shelter In Place" If isBitMap("finishedSim") Then UnloadBMP "finishedSim" simulationValues.hours.struct = 0 simulationValues.xTimeCoord.struct = 0 simulationValues.waitCount.struct = 0 simulationValues.mortalityCount.struct = 0 simulationValues.immunePersons.struct = 0 simulationValues.shelterInPlace.struct = 0 Call initializeDefaultValues Call changeDefaultValues Call initializeEntities Call initializeSprites
#Simulation.btnShelterInPlace "!Enable" simulationValues.simulationStatus.struct = 1 End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub initializeDefaultValues simulationValues.population.struct = 100 'population simulationValues.seeds.struct = 5 'number of starting sick simulationValues.transferRate.struct = 33'probability of contracting on contact simulationValues.recoCount.struct = 0'number of sims that were sick but recovered simulationValues.percentStationary.struct = 25 simulationValues.daysInfectious.struct = 28 simulationValues.immunityPercentage.struct = 2 simulationValues.mortalityPercentage.struct = 10 'Mortality numbers to be tracked by mortalityCount simulationValues.avgDaysUntilMortality.struct = 21'(simulationValues.daysInfectious.struct - 1) End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub changeDefaultValues question$ = "Would you like to change any of the default values?";CRLF$;CRLF$; _ "Default Values";CRLF$; _ "Population: ";simulationValues.population.struct;CRLF$; _ "Infected Seeds: ";simulationValues.seeds.struct;CRLF$; _ "Percentage with Natural Immunity: ";simulationValues.immunityPercentage.struct;CRLF$; _ "Stationary Percentage: ";simulationValues.percentStationary.struct;CRLF$; _ "Transmission Rate: ";simulationValues.transferRate.struct;CRLF$; _ "Days Infectious: ";simulationValues.daysInfectious.struct;CRLF$; _ "Mortality Rate: ";simulationValues.mortalityPercentage.struct;CRLF$; _ "Days until Mortality: ";simulationValues.avgDaysUntilMortality.struct Confirm question$;responseVar$ If (Upper$(responseVar$) = "YES") Then Prompt "Population: ";simulationValues.population.struct Prompt "Infected Seeds: ";simulationValues.seeds.struct Prompt "Percentage with Natural Immunity: ";simulationValues.immunityPercentage.struct Prompt "Stationary Percentage: ";simulationValues.percentStationary.struct Prompt "Transmission Rate: ";simulationValues.transferRate.struct Prompt "Days Infectious: ";simulationValues.daysInfectious.struct simulationValues.avgDaysUntilMortality.struct = (simulationValues.daysInfectious.struct - 1) Prompt "Mortality Rate: ";simulationValues.mortalityPercentage.struct Prompt "Days until Mortality: ";simulationValues.avgDaysUntilMortality.struct End If
simulationValues.population.struct = Max(simulationValues.population.struct, simulationValues.seeds.struct) simulationValues.immunityPercentage.struct = Min(simulationValues.immunityPercentage.struct, (100 - (100 * (simulationValues.seeds.struct/ simulationValues.population.struct)))) simulationValues.avgDaysUntilMortality.struct = (simulationValues.daysInfectious.struct - 1) simulationValues.sickCount.struct = simulationValues.seeds.struct simulationValues.maxSickCount.struct = simulationValues.sickCount.struct simulationValues.wellCount.struct = simulationValues.population.struct - simulationValues.seeds.struct simulationValues.mortalityCountMax.struct = Int(simulationValues.seeds.struct * (simulationValues.mortalityPercentage.struct/ 100))
ReDim entity(simulationValues.population.struct, 10)'#Population entities, 10 parameters each '1=x location '2=y location '3=x velocity '4=y velocity '5=wellness parameter (0=well, 1=sick, 2=recovered, 3 = dead) '6=time since initial infection '7 = Natural Immunity End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub initializeEntities 'set initial paramaters 'random location For i = 0 To (simulationValues.population.struct - 1) entity(i, 1) = (Int(rnd(1) * 450) + 20) entity(i, 2) = (Int(rnd(1) * 450) + 20) entity(i, 3) = ((0.5 - rnd(1)) * 5) If (entity(i, 3) < 1) And (entity(i,3) > -1) Then If (entity(i, 3) < 1) Then entity(i, 3) = (entity(i, 3) - 2) If (entity(i, 3) > 1) Then entity(i, 3) = (entity(i, 3) + 2) End If entity(i, 4) = (0.5 - rnd(1)) * 5 If (entity(i, 4) < 1) And (entity(i,4) > -1) Then If (entity(i, 4) < 1) Then entity(i, 4) = (entity(i, 4) - 2) If (entity(i, 4) > 1) Then entity(i, 4) = (entity(i, 4) + 2) End if If (i/ simulationValues.population.struct) < (simulationValues.percentStationary.struct/ 100) Then entity(a, 3) = 0 : entity(a, 4) = 0 Next i End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub initializeSprites 'make sprites #Simulation.gBoxGraphs "Down; Place 1 1; Color White; BackColor White; BoxFilled 10 10" #Simulation.gBoxGraphs "Place 5 5; BackColor Black; Color Black; CircleFilled 3" #Simulation.gBoxGraphs "Place 5 15; BackColor Black; Color Black; CircleFilled 3; Color Green; BackColor Green; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP well 1 1 8 20" #Simulation.gBoxGraphs "BackColor Black; Color Black; CircleFilled 3; Color Red; BackColor Red; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP sick 1 1 8 20" #Simulation.gBoxGraphs "Color Blue; BackColor Blue; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP reco 1 1 8 20"
#Simulation.gBoxGraphs "Color Yellow; BackColor Yellow; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP immune 1 1 8 20"
#Simulation.gBoxGraphs "Color Black; BackColor Black; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP dead 1 1 8 20"
#Simulation.gBoxSim "GetBMP bg 1 1 500 520" #Simulation.gBoxSim "Background bg" #Simulation.gBoxSim "DrawBMP well 10 10; DrawBMP sick 40 40; DrawBMP reco 80 80; DrawBMP immune 120 120; DrawBMP dead 160 160"
For i = 0 to (simulationValues.population.struct - 1) #Simulation.gBoxSim "AddSprite simEntity";i;" well sick reco immune dead" #Simulation.gBoxSim "SpriteXY simEntity";i;" ";entity(i, 1);" ";entity(i, 2) #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" ";entity(i, 3);" ";entity(i, 4) Next i
For i = 0 to (simulationValues.seeds.struct - 1) ' seed sick people with random times since infection entity(i, 5) = 1 entity(i, 6) = Int((rnd(1) * 24 * simulationValues.daysInfectious.struct) + 0.5) 'rnd(1)*14*24 #Simulation.gBoxSim "SpriteImage simEntity";i;" sick" next i
For i = 0 To ((simulationValues.population.struct * (simulationValues.immunityPercentage.struct/ 100)) - 1) element = Int((rnd(1) * simulationValues.population.struct) + 0.4) If (entity(element, 7) = 0) And (entity(element, 5) = 0) Then entity(element, 7) = 1 #Simulation.gBoxSim "SpriteImage simEntity";element;" immune" simulationValues.immunePersons.struct = (simulationValues.immunePersons.struct + 1) Else i = (i - 1) End If Next i
#Simulation.gBoxSim "DrawSprites" #Simulation.gBoxGraphs "CLS; Fill White; Flush" End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function isBitMap(BMPName$) On Error GoTo [Error] isBitMap = Hbmp(BMPName$) [Error] End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Sleep(milliseconds) CallDLL #kernel32, "Sleep", milliseconds As ulong, _ ret As void End Function
{:0)
Brandon Parker
|
|
|
Post by David Drake on Mar 22, 2020 6:48:57 GMT -5
Brilliant! I love your interpretation of the concept. Well done.
|
|
|
Post by Brandon Parker on Mar 22, 2020 9:51:24 GMT -5
Thanks!
I updated the code to use the function called isBitMap(BMPName$). This prevents an unhandled exception when a Bitmap has not been generated yet (specifically the "finishedSim" Bitmap) when the program is restarted or exited prior to the simulation completing. I just used it for each one of the Bitmaps when they are unloaded just to be safe.
Note that the use of isBitMap(BMPName$) does break the Debugger if the code runs through it and the Bitmap does not exist. The Debugger treats all exceptions as fatal even if there is runtime trapping within the Sub/Function that would otherwise handle the exception correctly. I have never been able to get the Debugger to actually "Step Over" or "Step Out" in this type of situation either for some reason.
The Runtime Engine handles the exception correctly though ...
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Mar 24, 2020 22:33:35 GMT -5
Fixed an issue in the changeDefaultValues subroutine where new values were not being set. This seems to be a bug in Liberty BASIC that I was not aware of. Apparently one cannot use a Struct element as a return variable for a Prompt. I will be issuing a new bug report for this unless I find that it has already been listed and I just missed it.
Here is the new code ...
NoMainWin Dim entity(0, 0) Global CRLF$ : CRLF$ = chr$(13);chr$(10) Struct simulationValues, population As long, _ seeds As long, _ transferRate As long, _ wellCount As long, _ sickCount As long, _ maxSickCount As long, _ recoCount As long, _ immunePersons As long, _ percentStationary As long, _ daysInfectious As long, _ immunityPercentage As long, _ mortalityPercentage As long, _ mortalityCount AS long, _ mortalityCountMax AS long, _ avgDaysUntilMortality As long, _ hours As long, _ xTimeCoord As long, _ waitCount As long, _ shelterInPlace As boolean, _ simulationStatus AS boolean
Struct oldValues, maxSickCount As ptr, _ wellCount As ptr, _ sickCount As ptr, _ recoCount As ptr, _ mortalityCount As ptr
Call initializeDefaultValues Call changeDefaultValues Call openSimulationWindow Call initializeEntities Call initializeSprites
simulationValues.simulationStatus.struct = 1
While Hwnd(#Simulation) Scan If (simulationValues.simulationStatus.struct = 1) Then Call animateSimulation End If result = Sleep(1) Wend
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub openSimulationWindow WindowWidth = 805 WindowHeight = 620 UpperLeftX = Int((DisplayWidth - WindowWidth)/ 2) UpperLeftY = Int((DisplayHeight - WindowHeight)/ 2)
GraphicBox #Simulation.gBoxSim, 1, 1, 500, 520 GraphicBox #Simulation.gBoxInfo, 1, 521, 645, 100 GraphicBox #Simulation.gBoxGraphs, 501, 1, 300, 245 TextEditor #Simulation.txtEdOutput, 501, 245, 300, 275 Button #Simulation.btnShelterInPlace, "Shelter In Place", shelterInPlace, UL, 657, 527 , 125, 25 Button #Simulation.btnRestartSimulation, "Restart Simulation", restartSimulation, UL, 657, 557 , 130, 25 Open "COVID-19 Simulation" For graphics_nf_nsb As #Simulation #Simulation.gBoxSim "Fill White; Flush" #Simulation.gBoxInfo "Fill DarkBlue; Flush" #Simulation.gBoxGraphs "Fill White; Flush" #Simulation.txtEdOutput "Simulation Started!";CRLF$ #Simulation "TrapClose quitSimulation" #Simulation.btnShelterInPlace "!SetFocus" End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub animateSimulation If (simulationValues.sickCount.struct <= 0) Then simulationValues.waitCount.struct = (simulationValues.waitCount.struct + 1) If (simulationValues.waitCount.struct > 0) Then Call endSimulation End If End If simulationValues.hours.struct = (simulationValues.hours.struct + 1) #Simulation.gBoxSim "DrawSprites" For i = 0 To (simulationValues.population.struct - 1) If (entity(i, 5) = 1) Then If (entity(i, 6) > 0) Then 'decrement time sick entity(i, 6) = (entity(i, 6) - 1) If (entity(i, 6) = 0) And Not(simulationValues.sickCount.struct = (simulationValues.mortalityCountMax.struct - simulationValues.mortalityCount.struct)) Then entity(i, 5) = 2 'move to reco #Simulation.gBoxSim "SpriteImage simEntity";i;" reco" simulationValues.recoCount.struct = (simulationValues.recoCount.struct + 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct - 1) Else If (entity(i, 6) <= ((simulationValues.daysInfectious.struct - simulationValues.avgDaysUntilMortality.struct) * 24)) Then If ((rnd(1) * simulationValues.maxSickCount.struct) >= (simulationValues.population.struct.struct - (simulationValues.maxSickCount.struct * (simulationValues.mortalityPercentage.struct/ 100))) And (simulationValues.mortalityCount.struct < simulationValues.mortalityCountMax.struct)) _ Or (simulationValues.sickCount.struct = (simulationValues.mortalityCountMax.struct - simulationValues.mortalityCount.struct)) Then 'Make Dead here entity(i, 5) = 3 #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" 0 0" entity(i, 3) = 0 : entity(i, 4) = 0 #Simulation.gBoxSim "SpriteImage simEntity";i;" dead" simulationValues.mortalityCount.struct = (simulationValues.mortalityCount.struct + 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct - 1) End If End If End If End If End If
#Simulation.gBoxSim "SpriteXY? simEntity";i;" x y" #Simulation.gBoxSim "SpriteCollides simEntity";i;" col$" If (col$ <> "") Then If (Rnd(1) < 0.5) Then entity(i, 3) = (entity(i, 3) * (-1)) 'change direction If (Rnd(1) < 0.5) Then entity(i, 4) = (entity(i, 4) * (-1)) 'change direction
col = Val(Left$(After$(col$,"simEntity"), 2)) 'get the colliding simEntity If (entity(i, 5) = 1) And (entity(col, 5) = 0) And (Rnd(1) < (simulationValues.transferRate.struct/ 100)) And (entity(col, 7) = 0) Then 'move from well to sick entity(col, 5) = 1 : entity(col, 6) = (simulationValues.daysInfectious.struct * 24) #Simulation.gBoxSim "SpriteImage simEntity";col;" sick" simulationValues.wellCount.struct = (simulationValues.wellCount.struct - 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct + 1) simulationValues.maxSickCount.struct = (simulationValues.maxSickCount.struct + 1) Else If (entity(i, 5) = 0) And (entity(col, 5) = 1) And (Rnd(1) < (simulationValues.transferRate.struct/ 100)) And (entity(i, 7) = 0) Then entity(i,5) = 1 : entity(i, 6) = (simulationValues.daysInfectious.struct * 24) 'move from well to sick #Simulation.gBoxSim "SpriteImage simEntity";i;" sick" simulationValues.wellCount.struct = (simulationValues.wellCount.struct - 1) simulationValues.sickCount.struct = (simulationValues.sickCount.struct + 1) simulationValues.maxSickCount.struct = (simulationValues.maxSickCount.struct + 1) End If End If End If
If (entity(i, 5) < 3) And Not(simulationValues.shelterInPlace.struct) Then 'Fix them getting trapped outside these boundaries 'If (((x + entity(i, 3)) >= 480) If ((x >= 480) Or (x <= 10)) Or (Int(Rnd(1) + 0.01) >= 1) Then entity(i, 3) = (entity(i, 3) * (-1)) 'change direction at perimeter If ((y >= 500) Or (y <= 10)) Or (Int(Rnd(1) + 0.01) >= 1) Then entity(i, 4) = (entity(i, 4) * (-1)) 'change direction at perimeter #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" ";entity(i, 3);" ";entity(i, 4) End If Next i
simulationValues.mortalityCountMax.struct = Int(simulationValues.maxSickCount.struct * (simulationValues.mortalityPercentage.struct/ 100)) #Simulation.gBoxInfo, "Fill DarkBlue; Place 10 40;\ Time: ";simulationValues.hours.struct;" Well: ";simulationValues.wellCount.struct;" Sick: ";simulationValues.sickCount.struct;" Reco: "; _ simulationValues.recoCount.struct;" Immune: ";simulationValues.immunePersons.struct;" Dead: ";simulationValues.mortalityCount.struct;" " '#Simulation.gBoxGraphs "discard;cls" #Simulation.gBoxGraphs, "Place 30 105; BackColor White; Color Black; BoxFilled 60 5" #Simulation.gBoxGraphs, "Place 60 105; BackColor White; Color Black; BoxFilled 90 5" #Simulation.gBoxGraphs, "Place 90 105; BackColor White; Color Black; BoxFilled 120 5" #Simulation.gBoxGraphs, "Place 120 105; BackColor White; Color Black; BoxFilled 150 5" #Simulation.gBoxGraphs, "Place 60 105; BackColor Pink; Color Black; BoxFilled 90 ";(105 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct))
#Simulation.gBoxGraphs, "Place 30 105; BackColor Green; Color Black; BoxFilled 60 ";(105 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs, "Place 60 105; BackColor Red; Color Black; BoxFilled 90 ";(105 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs, "Place 90 105; BackColor Blue; Color Black; BoxFilled 120 ";(105 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs, "Place 120 105; BackColor Black; Color Black; BoxFilled 150 ";(105 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct))
#Simulation.gBoxGraphs "Color Black; BackColor White; Place 30 220; GoTo 30 120" #Simulation.gBoxGraphs "Place 30 220; GoTo 280 220" 'Keep a time coordinate since it is use so much below....tired of changing it each time I adjust something :) simulationValues.xTimeCoord.struct = (30 + (simulationValues.hours.struct/ 24)) If (simulationValues.hours.struct = 1) Then 'Draw some axis lines #Simulation.gBoxGraphs "Place 5 ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct));"; Size 1" #Simulation.gBoxGraphs "|";simulationValues.population.struct #Simulation.gBoxGraphs "Place 5 ";(230 - ((230 - (220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)))/ 2)) #Simulation.gBoxGraphs "|";(simulationValues.population.struct/ 2) #Simulation.gBoxGraphs "Place 20 235" #Simulation.gBoxGraphs "|0" 'Added some labels down here as welld #Simulation.gBoxGraphs "Place 160 15" #Simulation.gBoxGraphs "|Color Legend" #Simulation.gBoxGraphs "Place 160 17; GoTo 250 17" #Simulation.gBoxGraphs, "Color Pink; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) oldValues.maxSickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 65" #Simulation.gBoxGraphs "|Pink = Max Sick" #Simulation.gBoxGraphs, "Color Green; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) oldValues.wellCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 35" #Simulation.gBoxGraphs "|Green = Well" #Simulation.gBoxGraphs, "Color Red; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) oldValues.sickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 50" #Simulation.gBoxGraphs "|Red = Sick" #Simulation.gBoxGraphs, "Color Blue; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) oldValues.recoCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 80" #Simulation.gBoxGraphs "|Blue = Recovered" #Simulation.gBoxGraphs, "Color Black; Set ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) oldValues.mortalityCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Place 160 95" #Simulation.gBoxGraphs "|Black = Mortality" Else 'Adds a tick mark at each week If ((simulationValues.hours.struct Mod (24 * 7)) = 0) Then #Simulation.gBoxGraphs "Place ";simulationValues.xTimeCoord.struct;" 220; GoTo ";simulationValues.xTimeCoord.struct;" 225" End If #Simulation.gBoxGraphs "Color Pink; Place ";Winstring(oldValues.maxSickCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) oldValues.maxSickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.maxSickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Green; Place ";Winstring(oldValues.wellCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) oldValues.wellCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.wellCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Red; Place ";Winstring(oldValues.sickCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) oldValues.sickCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.sickCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Blue; Place ";Winstring(oldValues.recoCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 -(100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) oldValues.recoCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.recoCount.struct/ simulationValues.population.struct)) #Simulation.gBoxGraphs "Color Black; Place ";Winstring(oldValues.mortalityCount.struct);"; GoTo ";simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) oldValues.mortalityCount.struct = simulationValues.xTimeCoord.struct;" ";(220 - (100 * simulationValues.mortalityCount.struct/ simulationValues.population.struct)) End If End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub endSimulation 'Display the number of weeks passed and account for the extra 50 hours at the end of the simulation #Simulation.gBoxGraphs "Place ";Min(200, (simulationValues.xTimeCoord.struct - (50/ 24)));" 237" #Simulation.gBoxGraphs "|";Trim$(Using("#####.##",((simulationValues.hours.struct - 50)/ (24 * 7))));" Weeks" #Simulation.gBoxSim "GetBMP finishedSim 0 0 501 521; Place 0 0; DrawBMP finishedSim; Flush finishedSim" #Simulation.gBoxInfo "Flush" #Simulation.gBoxGraphs "Flush" #Simulation.txtEdOutput "Population: ";simulationValues.population.struct #Simulation.txtEdOutput "Infected Seeds: ";simulationValues.seeds.struct #Simulation.txtEdOutput "Immune Persons: ";simulationValues.immunePersons.struct #Simulation.txtEdOutput "Initial Stationary %: ";Trim$(Using("#####.##",simulationValues.percentStationary.struct)) #Simulation.txtEdOutput "Transmission Rate: ";Trim$(Using("#####.##",simulationValues.transferRate.struct)) #Simulation.txtEdOutput "Days Infectious: ";simulationValues.daysInfectious.struct;CRLF$ #Simulation.txtEdOutput "Outbreak Duration: ";(simulationValues.hours.struct - 50);" Hrs" #Simulation.txtEdOutput "Recovery %: ";Trim$(Using("#####.##",((simulationValues.recoCount.struct/ simulationValues.maxSickCount.struct) * 100)));" %" #Simulation.txtEdOutput "Max % Sick: ";Trim$(Using("#####.##",((simulationValues.maxSickCount.struct/ simulationValues.population.struct) * 100)));" %"
#Simulation.txtEdOutput "Mortality %: ";Trim$(Using("#####.##",((simulationValues.mortalityCount.struct/ simulationValues.maxSickCount.struct) * 100)));" %";CRLF$ #Simulation.txtEdOutput "Simulation Complete!" #Simulation.btnShelterInPlace "!Disable" simulationValues.simulationStatus.struct = 0 End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub quitSimulation handle$ If isBitMap("bg") Then UnloadBMP "bg" If isBitMap("well") Then UnloadBMP "well" If isBitMap("sick") Then UnloadBMP "sick" If isBitMap("reco") Then UnloadBMP "reco" If isBitMap("immune") Then UnloadBMP "immune" If isBitMap("dead") Then UnloadBMP "dead" If isBitMap("finishedSim") Then UnloadBMP "finishedSim" #Simulation.gBoxSim "CLS; Discard" #Simulation.gBoxInfo "CLS; Discard" #Simulation.gBoxGraphs "CLS; Discard" Close #handle$ End End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub shelterInPlace handle$ If Not(simulationValues.shelterInPlace.struct) Then For i = 0 to (simulationValues.population.struct - 1) #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" 0 0" 'entity(i, 3) = 0 : entity(i, 4) = 0 Next i simulationValues.shelterInPlace.struct = 1 #Simulation.btnShelterInPlace "Allow Movement" #Simulation.txtEdOutput "Sheltered in Place at day ";Trim$(Using("#####.##", (simulationValues.hours.struct/ 24)));"!"
Else simulationValues.shelterInPlace.struct = 0 #Simulation.btnShelterInPlace, "Shelter In Place" #Simulation.txtEdOutput "Movement Allowed at day ";Trim$(Using("#####.##", (simulationValues.hours.struct/ 24)));"!" End If End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub restartSimulation handle$ For i = 0 to (simulationValues.population.struct - 1) #Simulation.gBoxSim "RemoveSprite simEntity";i Next i #Simulation.gBoxSim "DelSegment finishedSim" #Simulation.gBoxSim "CLS; Discard" #Simulation.gBoxInfo "CLS; Discard" #Simulation.gBoxGraphs "CLS; Discard" #Simulation.gBoxSim "Fill White; Flush" #Simulation.gBoxInfo "Fill DarkBlue; Flush" #Simulation.gBoxGraphs "Fill White; Flush" #Simulation.txtEdOutput "!CLS" #Simulation.txtEdOutput "Simulation Restarted!";CRLF$ #Simulation.btnShelterInPlace "Shelter In Place" If isBitMap("finishedSim") Then UnloadBMP "finishedSim" simulationValues.hours.struct = 0 simulationValues.xTimeCoord.struct = 0 simulationValues.waitCount.struct = 0 simulationValues.mortalityCount.struct = 0 simulationValues.immunePersons.struct = 0 simulationValues.shelterInPlace.struct = 0 Call initializeDefaultValues Call changeDefaultValues Call initializeEntities Call initializeSprites
#Simulation.btnShelterInPlace "!Enable" simulationValues.simulationStatus.struct = 1 End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub initializeDefaultValues simulationValues.population.struct = 100 'population simulationValues.seeds.struct = 5 'number of starting sick simulationValues.transferRate.struct = 33'probability of contracting on contact simulationValues.recoCount.struct = 0'number of sims that were sick but recovered simulationValues.percentStationary.struct = 25 simulationValues.daysInfectious.struct = 28 simulationValues.immunityPercentage.struct = 2 simulationValues.mortalityPercentage.struct = 10 'Mortality numbers to be tracked by mortalityCount simulationValues.avgDaysUntilMortality.struct = 21'(simulationValues.daysInfectious.struct - 1) End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub changeDefaultValues question$ = "Would you like to change any of the default values?";CRLF$;CRLF$; _ "Default Values";CRLF$; _ "Population: ";simulationValues.population.struct;CRLF$; _ "Infected Seeds: ";simulationValues.seeds.struct;CRLF$; _ "Percentage with Natural Immunity: ";simulationValues.immunityPercentage.struct;CRLF$; _ "Stationary Percentage: ";simulationValues.percentStationary.struct;CRLF$; _ "Transmission Rate: ";simulationValues.transferRate.struct;CRLF$; _ "Days Infectious: ";simulationValues.daysInfectious.struct;CRLF$; _ "Mortality Rate: ";simulationValues.mortalityPercentage.struct;CRLF$; _ "Days until Mortality: ";simulationValues.avgDaysUntilMortality.struct Confirm question$;responseVar$ If (Upper$(responseVar$) = "YES") Then tempPopulation = simulationValues.population.struct tempSeeds = simulationValues.seeds.struct immunityPercentage = simulationValues.immunityPercentage.struct tempPercentStationary = simulationValues.percentStationary.struct tempTransferRate = simulationValues.transferRate.struct tempDaysInfectious = simulationValues.daysInfectious.struct tempMortalityPercentage = simulationValues.mortalityPercentage.struct tempAvgDaysUntilMortality = simulationValues.avgDaysUntilMortality.struct
Prompt "Population: ";tempPopulation Prompt "Infected Seeds: ";tempSeeds Prompt "Percentage with Natural Immunity: ";immunityPercentage Prompt "Stationary Percentage: ";tempPercentStationary Prompt "Transmission Rate: ";tempTransferRate Prompt "Days Infectious: ";tempDaysInfectious tempAvgDaysUntilMortality = (tempDaysInfectious - 1) Prompt "Mortality Rate: ";tempMortalityPercentage Prompt "Days until Mortality: ";tempAvgDaysUntilMortality
simulationValues.population.struct = tempPopulation simulationValues.seeds.struct = tempSeeds simulationValues.immunityPercentage.struct = immunityPercentage simulationValues.percentStationary.struct = tempPercentStationary simulationValues.transferRate.struct = tempTransferRate simulationValues.daysInfectious.struct = tempDaysInfectious simulationValues.mortalityPercentage.struct = tempMortalityPercentage simulationValues.avgDaysUntilMortality.struct = tempAvgDaysUntilMortality
End If
simulationValues.population.struct = Max(simulationValues.population.struct, simulationValues.seeds.struct) simulationValues.immunityPercentage.struct = Min(simulationValues.immunityPercentage.struct, (100 - (100 * (simulationValues.seeds.struct/ simulationValues.population.struct)))) simulationValues.avgDaysUntilMortality.struct = (simulationValues.daysInfectious.struct - 1) simulationValues.sickCount.struct = simulationValues.seeds.struct simulationValues.maxSickCount.struct = simulationValues.sickCount.struct simulationValues.wellCount.struct = simulationValues.population.struct - simulationValues.seeds.struct simulationValues.mortalityCountMax.struct = Int(simulationValues.seeds.struct * (simulationValues.mortalityPercentage.struct/ 100))
ReDim entity(simulationValues.population.struct, 10)'#Population entities, 10 parameters each '1=x location '2=y location '3=x velocity '4=y velocity '5=wellness parameter (0=well, 1=sick, 2=recovered, 3 = dead) '6=time since initial infection '7 = Natural Immunity End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub initializeEntities 'set initial paramaters 'random location For i = 0 To (simulationValues.population.struct - 1) entity(i, 1) = (Int(rnd(1) * 450) + 20) entity(i, 2) = (Int(rnd(1) * 450) + 20) entity(i, 3) = ((0.5 - rnd(1)) * 5) If (entity(i, 3) < 1) And (entity(i,3) > -1) Then If (entity(i, 3) < 1) Then entity(i, 3) = (entity(i, 3) - 2) If (entity(i, 3) > 1) Then entity(i, 3) = (entity(i, 3) + 2) End If entity(i, 4) = (0.5 - rnd(1)) * 5 If (entity(i, 4) < 1) And (entity(i,4) > -1) Then If (entity(i, 4) < 1) Then entity(i, 4) = (entity(i, 4) - 2) If (entity(i, 4) > 1) Then entity(i, 4) = (entity(i, 4) + 2) End if If (i/ simulationValues.population.struct) < (simulationValues.percentStationary.struct/ 100) Then entity(a, 3) = 0 : entity(a, 4) = 0 Next i End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub initializeSprites 'make sprites #Simulation.gBoxGraphs "Down; Place 0 0; Color White; BackColor White; BoxFilled 7 14" #Simulation.gBoxGraphs "Place 3 3; BackColor Black; Color Black; CircleFilled 3" #Simulation.gBoxGraphs "Place 3 10; BackColor Black; Color Black; CircleFilled 3; Color Green; BackColor Green; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP well 0 0 7 14" #Simulation.gBoxGraphs "BackColor Black; Color Black; CircleFilled 3; Color Red; BackColor Red; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP sick 0 0 7 14" #Simulation.gBoxGraphs "Color Blue; BackColor Blue; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP reco 0 0 7 14"
#Simulation.gBoxGraphs "Color Yellow; BackColor Yellow; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP immune 0 0 7 14"
#Simulation.gBoxGraphs "BackColor Red; Color Red; CircleFilled 3; Color Black; BackColor Black; CircleFilled 2" #Simulation.gBoxGraphs "GetBMP dead 0 0 7 14"
#Simulation.gBoxSim "GetBMP bg 1 1 500 520" #Simulation.gBoxSim "Background bg" #Simulation.gBoxSim "DrawBMP well 10 10; DrawBMP sick 40 40; DrawBMP reco 80 80; DrawBMP immune 120 120; DrawBMP dead 160 160"
For i = 0 to (simulationValues.population.struct - 1) #Simulation.gBoxSim "AddSprite simEntity";i;" well sick reco immune dead" #Simulation.gBoxSim "SpriteXY simEntity";i;" ";entity(i, 1);" ";entity(i, 2) #Simulation.gBoxSim "SpriteMoveXY simEntity";i;" ";entity(i, 3);" ";entity(i, 4) Next i
For i = 0 to (simulationValues.seeds.struct - 1) ' seed sick people with random times since infection entity(i, 5) = 1 entity(i, 6) = Int((rnd(1) * 24 * simulationValues.daysInfectious.struct) + 0.5) 'rnd(1)*14*24 #Simulation.gBoxSim "SpriteImage simEntity";i;" sick" next i
For i = 0 To ((simulationValues.population.struct * (simulationValues.immunityPercentage.struct/ 100)) - 1) element = Int((rnd(1) * simulationValues.population.struct) + 0.4) If (entity(element, 7) = 0) And (entity(element, 5) = 0) Then entity(element, 7) = 1 #Simulation.gBoxSim "SpriteImage simEntity";element;" immune" simulationValues.immunePersons.struct = (simulationValues.immunePersons.struct + 1) Else i = (i - 1) End If Next i
#Simulation.gBoxSim "DrawSprites" #Simulation.gBoxGraphs "CLS; Fill White; Flush" End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function isBitMap(BMPName$) On Error GoTo [Error] isBitMap = Hbmp(BMPName$) [Error] End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Sleep(milliseconds) CallDLL #kernel32, "Sleep", milliseconds As ulong, _ ret As void End Function
{:0)
Brandon Parker
|
|