Works on disease simulations

This commit is contained in:
Shadow15510 2021-06-01 14:58:37 +02:00
parent 863473457e
commit 910bcced27
16 changed files with 118 additions and 67 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 21 KiB

BIN
old assets/Plague Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
old assets/bground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,39 @@
from PIL import Image
import numpy as np
def analyse(index, pxl):
if pxl[0] == 255: return 0
else:
if index < 18 or index > 52: return 1
if 24 < index < 40: return 3
else: return 2
def show():
img = Image.open("world.png")
data = np.array(img)
rslt = ""
for index, line in enumerate(data):
for pxl in line:
rslt += f"{analyse(index, pxl)}"
rslt += "\n"
print(rslt)
def get_tabular():
img = Image.open("world.png")
data = np.array(img)
rslt = "const unsigned int world[64][128] =\n{"
for index, line in enumerate(data):
rslt += "\n {"
for pxl in line:
rslt += f"{analyse(index, pxl)}, "
rslt = rslt[:-2] + "},"
rslt += "\n};"
print(rslt)
get_tabular()

BIN
old assets/title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
old assets/world.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -56,7 +56,6 @@ void next_frame(struct game *current_game)
message(msg);
current_game->research = 0;
}
epidemic_simulation(current_game);
}
}

View File

@ -40,7 +40,7 @@ struct game
int research, limit, priority;
// Humans stats : healthy, infected, dead, healed
long long int humans[4];
int humans[4];
// Time
int time;

View File

@ -3,7 +3,7 @@
const struct mutation symptoms_data[14] =
{
{1, 1, 0, 2, 0, "NAUSEE"},
{100, 1, 0, 0, 0, "NAUSEE"},
{3, 2, 0, 4, 0, "VOMISSEMENT"},
{2, 1, 0, 3, 0, "TOUX"},
{2, 2, 0, 4, 0, "PNEUMONIE"},

View File

@ -29,7 +29,7 @@ void display_foreground(const int background, const struct game *current_game)
{
for (int j = 0; j < current_game->grid.height; j ++)
{
if (current_game->grid.data[i + j * current_game->grid.width] == 1 && world[i][j] != 0) dpixel(i, j, C_BLACK);
if (current_game->grid.data[i + j * current_game->grid.width] != 0 && world[i][j] != 0) dpixel(i, j, C_BLACK);
}
}
@ -47,7 +47,7 @@ void display_foreground(const int background, const struct game *current_game)
{
for (int j = 0; j < 50; j ++)
{
if (current_game->grid.data[i + j * current_game->grid.width] == 1 && world[i][j] != 0) dpixel(i, j, C_BLACK);
if (current_game->grid.data[i + j * current_game->grid.width] != 0 && world[i][j] != 0) dpixel(i, j, C_BLACK);
}
}
@ -68,15 +68,15 @@ void display_foreground(const int background, const struct game *current_game)
case 3:
dprint(102, 37, C_BLACK, "%d", current_game->dna);
length = 67 * current_game->contagion / 26;
length = 67 * current_game->contagion / 100;
dline(57, 48, 57 + length, 48, C_BLACK);
dline(57, 49, 57 + length, 49, C_BLACK);
length = 67 * current_game->severity / 20;
length = 67 * current_game->severity / 100;
dline(57, 54, 57 + length, 54, C_BLACK);
dline(57, 55, 57 + length, 55, C_BLACK);
length = 67 * current_game->lethality / 33;
length = 67 * current_game->lethality / 100;
dline(57, 60, 57 + length, 60, C_BLACK);
dline(57, 61, 57 + length, 61, C_BLACK);
@ -88,9 +88,10 @@ void display_foreground(const int background, const struct game *current_game)
case 6:
for (int i = 0; i < 4; i ++)
{
length = floor(63 * current_game->humans[i] / 8192);
dline(61, i*8 + 31, 61 + length, i*8 + 31, C_BLACK);
dline(61, i*8 + 32, 61 + length, i*8 + 32, C_BLACK);
// length = 63 * current_game->humans[i] / (current_game->grid.width * current_game->grid.height);
// dline(61, i*8 + 31, 61 + length, i*8 + 31, C_BLACK);
// dline(61, i*8 + 32, 61 + length, i*8 + 32, C_BLACK);
dprint(61, i*8 + 31, C_BLACK, "%d", current_game->humans[i]);
}
break;

View File

@ -2,52 +2,59 @@
#include "epidemic_engine.h"
int can_become_infected(const struct grid epidemic_grid, const int mutations_selected[3], const int i, const int j)
#include <gint/keyboard.h>
#include <gint/display.h>
int grid_get(const struct grid epidemic_grid, const int i, const int j)
{
if (i < 0 || j < 0 || i >= epidemic_grid.width || j >= epidemic_grid.height) return epidemic_grid.data[i + j * epidemic_grid.width];
return 0;
}
bool can_become_infected(const struct grid epidemic_grid, const int mutations_selected[3], const int i, const int j)
{
extern const unsigned int world[64][128];
// In case of water, low or high temperature
if (world[i][j] == 0 && mutations_selected[2] != 3) return 0;
if (world[i][j] == 1 && mutations_selected[1] != 0 && mutations_selected[1] != 4) return 0;
if (world[i][j] == 3 && mutations_selected[1] != 1 && mutations_selected[1] != 4) return 0;
if (world[j][i] == 0 && mutations_selected[2] != 3) return false;
if (world[j][i] == 1 && mutations_selected[1] != 0 && mutations_selected[1] != 4) return false;
if (world[j][i] == 3 && mutations_selected[1] != 1 && mutations_selected[1] != 4) return false;
// return (epidemic_grid.data[i-1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i+1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j-1) * epidemic_grid.width] - 1) * (epidemic_grid.data[i (j+1) * epidemic_grid.width] - 1) == 0;
if (i == 0 && j == 0) return (epidemic_grid.data[i+1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j+1) * epidemic_grid.width] - 1) == 0;
if (i == 0 && j == epidemic_grid.height - 1) return (epidemic_grid.data[i+1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j-1) * epidemic_grid.width] - 1) == 0;
if (i == 0) return (epidemic_grid.data[i + (j-1) * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j+1) * epidemic_grid.width] - 1) * (epidemic_grid.data[i+1 + j * epidemic_grid.width] - 1) == 0;
if (i == epidemic_grid.width - 1 && j == 0) return (epidemic_grid.data[i-1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j+1) * epidemic_grid.width] - 1) == 0;
if (i == epidemic_grid.width - 1 && j == epidemic_grid.height - 1) return (epidemic_grid.data[i-1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j-1) * epidemic_grid.width] - 1) == 0;
if (i == epidemic_grid.width - 1) return (epidemic_grid.data[i-1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j-1) * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j+1) * epidemic_grid.width] - 1) == 0;
return (epidemic_grid.data[i-1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i+1 + j * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j-1) * epidemic_grid.width] - 1) * (epidemic_grid.data[i + (j+1) * epidemic_grid.width] - 1) == 0;
// Test cases around
return grid_get(epidemic_grid, i - 1, j) == 1 || grid_get(epidemic_grid, i + 1, j) == 1 || grid_get(epidemic_grid, i, j - 1) == 1 || grid_get(epidemic_grid, i, j + 1) == 1;
}
int bernoulli(const float p, const int seed)
bool bernoulli(const float p)
{
srand(seed);
return rand() > p;
return (rand() / 2147483647) <= p;
}
void epidemic_simulation(struct game *current_game)
{
float contagion_rate = current_game->contagion / 100;
float lethality_rate = current_game->lethality / 100;
float healed_rate = current_game->research / current_game->limit;
srand(15510);
double contagion_rate = current_game->contagion / 100;
double lethality_rate = current_game->lethality / 100;
double healed_rate = current_game->research / current_game->limit;
for (int i = 0; i < current_game->grid.height; i ++)
dclear(C_WHITE);
dprint(5, 5, C_BLACK, "HR:%lf", healed_rate);
dupdate();
getkey();
for (int i = 0; i < current_game->grid.width; i ++)
{
for (int j = 0; j < current_game->grid.width; j ++)
for (int j = 0; j < current_game->grid.height; j ++)
{
switch (current_game->grid.data[i + j * current_game->grid.width])
{
// Healthy
case 0:
if (can_become_infected(current_game->grid, current_game->mutations_selected, i, j)
&& bernoulli(contagion_rate, current_game->time))
&& bernoulli(contagion_rate))
{
current_game->grid.data[i + j * current_game->grid.width] = 1;
current_game->humans[0] --;
@ -59,20 +66,20 @@ void epidemic_simulation(struct game *current_game)
case 1:
// Become healed
if (bernoulli(healed_rate, current_game->time))
{
current_game->grid.data[i + j * current_game->grid.width] = 3;
current_game->humans[1] --;
current_game->humans[3] ++;
}
// Become dead
else if (bernoulli(lethality_rate, current_game->time))
if (bernoulli(healed_rate))
{
current_game->grid.data[i + j * current_game->grid.width] = 2;
current_game->humans[1] --;
current_game->humans[2] ++;
}
// Become dead
else if (bernoulli(lethality_rate))
{
current_game->grid.data[i + j * current_game->grid.width] = 3;
current_game->humans[1] --;
current_game->humans[3] ++;
}
break;
}

View File

@ -7,10 +7,10 @@
#define HUMANS_PER_CASE 1000000
// can_become_infected : return 0 if the case (i, j) isn't infectable, 1 else
int can_become_infected(const struct grid epidemic_grid, const int mutations_selected[3], const int i, const int j);
bool can_become_infected(const struct grid epidemic_grid, const int mutations_selected[3], const int i, const int j);
// bernoulli : simulate a random event
int bernoulli(const float p, const int seed);
bool bernoulli(const float p);
// epidemic_simulation : simulate the propagation of the virus
void epidemic_simulation(struct game *current_game);

View File

@ -55,7 +55,7 @@ int main(void)
.research = 0,
.limit = RESEARCH_LIMIT,
.priority = 0,
.humans = {8191, 1, 0, 0},
.humans = {0, 1, 0, 0},
.time = 0,
@ -68,6 +68,7 @@ int main(void)
current_game.grid.data = calloc(current_game.grid.width * current_game.grid.height, sizeof(uint8_t));
current_game.grid.data[95 + 20 * current_game.grid.width] = 1;
current_game.humans[0] = (current_game.grid.width * current_game.grid.height) - 1;
main_loop(&current_game);
@ -83,47 +84,51 @@ static void title_screen(void)
extern bopti_image_t img_title;
extern bopti_image_t img_explosion;
static volatile int tick_250 = 1;
static volatile int tick_100 = 1;
int t_250 = timer_configure(TIMER_ANY, 250000, GINT_CALL(callback_tick, &tick_250));
int t_100 = timer_configure(TIMER_ANY, 100000, GINT_CALL(callback_tick, &tick_100));
static volatile int tick_5 = 1;
static volatile int tick_1 = 1;
int t_1 = timer_configure(TIMER_ANY, 500000, GINT_CALL(callback_tick, &tick_5));
int t_2 = timer_configure(TIMER_ANY, 100000, GINT_CALL(callback_tick, &tick_1));
if (t_250 >= 0) timer_start(t_250);
if (t_100 >= 0) timer_start(t_100);
if (t_1 >= 0) timer_start(t_1);
if (t_2 >= 0) timer_start(t_2);
dclear(C_BLACK);
dupdate();
while (!tick_250) sleep();
tick_250 = 0;
while (!tick_5) sleep();
tick_5 = 0;
dsubimage(0, 0, &img_title, 0, 0, 128, 64, DIMAGE_NONE);
dupdate();
while (!tick_250) sleep();
tick_250 = 0;
while (!tick_5) sleep();
tick_5 = 0;
for (int frame = 0; frame < 5; frame ++)
{
dclear(C_BLACK);
dsubimage(0, 0, &img_title, 0, 0, 128, 64, DIMAGE_NONE);
dsubimage(72, 5, &img_explosion, 41 * frame, 0, 40, 40, DIMAGE_NONE);
dsubimage(76, 9, &img_explosion, 41 * frame, 0, 40, 40, DIMAGE_NONE);
dupdate();
while (!tick_100) sleep();
tick_100 = 0;
while (!tick_1) sleep();
tick_1 = 0;
}
dclear(C_BLACK);
dsubimage(0, 0, &img_title, 0, 65, 128, 64, DIMAGE_NONE);
dupdate();
while (!tick_250) sleep();
tick_250 = 0;
for (int i = 0; i < 2; i ++)
{
while (!tick_5) sleep();
tick_5 = 0;
}
for (int i = 0; i < 5; i ++)
{
dclear(C_BLACK);
dsubimage(0, 0, &img_title, 0, ((i % 2) + 1) * 65, 128, 64, DIMAGE_NONE);
dupdate();
while (!tick_250) sleep();
tick_250 = 0;
while (!tick_5) sleep();
tick_5 = 0;
}
dclear(C_BLACK);
@ -132,8 +137,8 @@ static void title_screen(void)
getkey();
if (t_250 >= 0) timer_stop(t_250);
if (t_100 >= 0) timer_stop(t_100);
if (t_1 >= 0) timer_stop(t_1);
if (t_2 >= 0) timer_stop(t_2);
}

View File

@ -131,7 +131,7 @@ int mutation_buy(struct game *current_game, const struct cursor c, const int mut
{
current_game->mutations_selected[mutation_menu - 1] = id;
update_disease(current_game);
const char *msg[5] = {"mutation", "selectionnee"};
const char *msg[5] = {"mutation", "selectionnee", "", "", ""};
message(msg);
}