Plague-fx/src/epidemic_engine.c

88 lines
2.9 KiB
C

#include <gint/std/stdlib.h>
#include "epidemic_engine.h"
#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[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;
// 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;
}
bool bernoulli(const float p)
{
return (rand() / 2147483647) <= p;
}
void epidemic_simulation(struct game *current_game)
{
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;
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.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->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->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;
}
}
}
}