Here's a slightly modified version which includes a death rate of 3%.

Code: Select all

```
INSTALL @lib$ + "aagfxlib"
VDU 23,22,800;480;8,20,16,128
PEOPLE = 200
SIZE = 10
COLL = 4*SIZE^2
SPEED = 5
FATAL = 0.03
DURATION = 300
HEALTHY = 0
SICK = 1
RECOVERED = 2
DEAD = 3
LEDGE = SIZE
REDGE = 1600 - SIZE
BEDGE = SIZE
TEDGE = 800 - SIZE
LINE 0, 800, 1600, 800
VDU 28, 0, 23, 99, 4, 5, 30
OSCLI "font """ + @lib$ + "DejaVuSans"", 11"
PRINT " Dead" ' " Recovered"' " Healthy" ' " Sick" ;
OSCLI "font """ + @lib$ + "DejaVuSans"", 11, B"
DIM x(PEOPLE), y(PEOPLE), u(PEOPLE), v(PEOPLE), f%(PEOPLE), t%(PEOPLE)
DIM col%(3), num%(3)
col%() = &FFCAC6AA, &FF1D64BB, &FFC08ACB, &00000000
COLOUR 1,&AA,&C6,&CA : COLOUR 2,&BB,&64,&1D : COLOUR 3,&CB,&8A,&C0
ON ERROR OSCLI "REFRESH ON" : CLS : REPORT : END
REM Initialise to random positions and velocities:
FOR I% = 1 TO PEOPLE
direction = 2 * PI * RND(1)
x(I%) = (1598 - 2*SIZE) * RND(1) + SIZE
y(I%) = ( 798 - 2*SIZE) * RND(1) + SIZE
u(I%) = SPEED * COS(direction)
v(I%) = SPEED * SIN(direction)
NEXT
REM Infect one person:
f%(RND(PEOPLE)) = SICK
REM Animate
*REFRESH OFF
graph = 300
REPEAT
CLS
num%() = 0
REM Update positions, display and count:
FOR I% = 1 TO PEOPLE
x = x(I%) : y = y(I%)
x += u(I%) : IF x > LEDGE IF x < REDGE x(I%) = x ELSE u(I%) *= -1
y += v(I%) : IF y > BEDGE IF y < TEDGE y(I%) = y ELSE v(I%) *= -1
PROC_aasector(x(I%), y(I%), SIZE, SIZE, 0, 360, col%(f%(I%)))
IF f%(I%) = SICK THEN
t%(I%) += 1
IF t%(I%) > DURATION f%(I%) = RECOVERED : IF RND(1) < FATAL f%(I%) = DEAD
ENDIF
num%(f%(I%)) += 1
NEXT
REM Check for collisions:
FOR I% = 1 TO PEOPLE - 1
x = x(I%) : y = y(I%)
FOR J% = I% + 1 TO PEOPLE
d = (x-x(J%))^2 + (y-y(J%))^2
IF d < COLL IF f%(I%) <> DEAD IF f%(J%) <> DEAD THEN
IF d < (x-u(I%)-x(J%)+u(J%))^2 + (y-v(I%)-y(J%)+v(J%))^2 THEN
u(I%) *= -1 : v(I%) *= -1
u(J%) *= -1 : v(J%) *= -1
ENDIF
IF f%(I%) = SICK IF f%(J%) = HEALTHY f%(J%) = SICK
IF f%(J%) = SICK IF f%(I%) = HEALTHY f%(I%) = SICK
ENDIF
NEXT
NEXT I%
REM Report and graph:
GCOL 15 : RECTANGLE FILL 200, 820, 80, 140
GCOL 0 : MOVE 200,958 : PRINT ;num%(3);
GCOL 3 : MOVE 200,922 : PRINT ;num%(2);
GCOL 1 : MOVE 200,886 : PRINT ;num%(0);
GCOL 2 : MOVE 200,846 : PRINT ;num%(1);
y0 = 830
y1 = y0 + num%(1) / 2
y2 = y1 + num%(0) / 2
y3 = y2 + num%(2) / 2
y4 = y3 + num%(3) / 2
IF y1 <> y0 PROC_aaline(graph, y0, graph, y1, 2, col%(1), 0)
IF y2 <> y1 PROC_aaline(graph, y1, graph, y2, 2, col%(0), 0)
IF y3 <> y2 PROC_aaline(graph, y2, graph, y3, 2, col%(2), 0)
IF y4 <> y3 PROC_aaline(graph, y3, graph, y4, 2, &FF000000, 0)
graph += 1
*REFRESH
UNTIL FALSE
END
```