81 lines
3.9 KiB
C
81 lines
3.9 KiB
C
#include <gint/std/stdlib.h>
|
|
#include "epidemic_engine.h"
|
|
|
|
|
|
int 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;
|
|
|
|
// 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.width - 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.height -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.height - 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.height) 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;
|
|
}
|
|
|
|
|
|
int bernoulli(const float p, const int seed)
|
|
{
|
|
srand(seed);
|
|
return rand() > 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;
|
|
|
|
for (int i = 0; i < current_game->grid.height; i ++)
|
|
{
|
|
for (int j = 0; j < current_game->grid.width; 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))
|
|
{
|
|
current_game->grid.data[i + j * current_game->grid.width] = 1;
|
|
current_game->humans[0] --;
|
|
current_game->humans[1] ++;
|
|
}
|
|
break;
|
|
|
|
// Infected
|
|
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))
|
|
{
|
|
current_game->grid.data[i + j * current_game->grid.width] = 2;
|
|
current_game->humans[1] --;
|
|
current_game->humans[2] ++;
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
} |