First stable version #2
BIN
Plague.g1a
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 18 KiB |
|
@ -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()
|
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
|
@ -56,7 +56,6 @@ void next_frame(struct game *current_game)
|
|||
message(msg);
|
||||
current_game->research = 0;
|
||||
}
|
||||
|
||||
epidemic_simulation(current_game);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
45
src/main.c
|
@ -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(¤t_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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|