#ifndef GAME_H #define GAME_H #include #include #include #define BOARD_HEIGHT 100 #define BOARD_WIDTH 100 #define AGENTS_COUNT 2000 #define FOODS_COUNT 1000 #define WALLS_COUNT 60 #define STATES_COUNT 7 #define FOOD_HUNGER_RECOVERY 10 #define STEP_HUNGER_DAMAGE 5 #define HUNGER_MAX 100 #define HEALTH_MAX 100 #define ATTACK_DAMAGE 10 #define GENES_COUNT 20 #define SELECTION_POOL 50 #define MUTATION_CHANCE 100 #define DUMP_FILEPATH "./game.bin" #define TRAINED_FILEPATH "./trained.bin" static_assert(SELECTION_POOL <= AGENTS_COUNT, "Too large Selection Pool for amount of Agents"); static_assert(AGENTS_COUNT > 0, "Not Enough Agents"); static_assert(AGENTS_COUNT + FOODS_COUNT + WALLS_COUNT <= BOARD_WIDTH * BOARD_HEIGHT, "Board is FULL, Too many entities"); static_assert(GENES_COUNT % 2 == 0, "GENES_COUNT must be even for chromosome pairing."); typedef struct { int x, y; } Coord; typedef enum { DIR_RIGHT = 0, DIR_UP, DIR_LEFT, DIR_DOWN, } Dir; typedef int State; typedef enum { ACTION_NOP = 0, ACTION_STEP, ACTION_TURN_LEFT, ACTION_TURN_RIGHT, ACTION_COUNT, } Action; typedef enum { ENV_NOTHING = 0, ENV_AGENT, ENV_FOOD, ENV_WALL, ENV_COUNT, } Env; typedef struct { State state; Env env; Action action; State next_state; } Gene; typedef struct { size_t count; Gene genes[GENES_COUNT]; } Chromo; typedef struct { Coord pos; Dir dir; int hunger; int health; State state; int lifetime; Chromo chromo; } Agent; typedef struct { Agent agents[AGENTS_COUNT]; //int agents_map[BOARD_HEIGHT][BOARD_WIDTH]; int foods_map[BOARD_HEIGHT][BOARD_WIDTH]; int walls_map[BOARD_HEIGHT][BOARD_WIDTH]; } Game; void init_game(Game *game); void dump_game(const char *filepath, const Game *game); void load_game(const char *filepath, Game *game); void step_game(Game *game); Agent *agent_at(Game *game, Coord pos); void print_chromo(FILE *stream, const Chromo *chromo); void print_agent(FILE *stream, const Agent *agent); void combine_agents(const Agent *agent_a, const Agent *agent_b, Agent *agent_ab); void mutate_agent(Agent *agent); void make_next_generation(Game *prev_game, Game *next_game); int is_everyone_dead(const Game *game); #endif