about summary refs log tree commit diff
path: root/src/game.h
blob: 5d5163a03f9b22574d5e6ca47fc82477fa41ee0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef GAME_H
#define GAME_H

#include <stddef.h>
#include <stdio.h>
#include <assert.h>

#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;

// TODO: use Env type
// TODO: Change env_map to struct
// maybe other env types need to store additional data like agents
#define ENV_MAP_NONE 0
#define ENV_MAP_WALL 1
#define ENV_MAP_FOOD 2
#define ENV_MAP_AGENTS 3

typedef struct {
  Agent agents[AGENTS_COUNT];
  int env_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