Plague-fx/src/epidemic_engine.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.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;
}
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;
}
}
}
}