XCSF  1.4.7
XCSF learning classifier system
env_maze.c
Go to the documentation of this file.
1 /*
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  */
15 
51 #include "env_maze.h"
52 #include "param.h"
53 #include "utils.h"
54 
55 #define MAX_PAYOFF (1.)
56 
60 static const int x_moves[] = { 0, +1, +1, +1, 0, -1, -1, -1 };
61 
65 static const int y_moves[] = { -1, -1, 0, +1, +1, +1, 0, -1 };
66 
73 static double
74 env_maze_sensor(const struct XCSF *xcsf, const char s)
75 {
76  (void) xcsf;
77  switch (s) {
78  case '*':
79  return 0.1;
80  case 'O':
81  return 0.3;
82  case 'G':
83  return 0.5;
84  case 'F':
85  return 0.7;
86  case 'Q':
87  return 0.9;
88  default:
89  printf("unsupported maze state: %c\n", s);
90  exit(EXIT_FAILURE);
91  }
92 }
93 
99 void
100 env_maze_init(struct XCSF *xcsf, const char *filename)
101 {
102  // open maze file
103  FILE *fp = fopen(filename, "rt");
104  if (fp == 0) {
105  printf("could not open %s. %s.\n", filename, strerror(errno));
106  exit(EXIT_FAILURE);
107  }
108  // read maze
109  struct EnvMaze *env = malloc(sizeof(struct EnvMaze));
110  int x = 0;
111  int y = 0;
112  int c = 0;
113  while ((c = fgetc(fp)) != EOF) {
114  if (c == '\n') {
115  ++y;
116  env->xsize = x;
117  x = 0;
118  } else {
119  env->maze[y][x] = (char) c;
120  ++x;
121  }
122  // check maximum maze size not exceeded
123  if (x > MAX_SIZE || y > MAX_SIZE) {
124  printf("Maze too big. Max size = [%d,%d]\n", MAX_SIZE, MAX_SIZE);
125  fclose(fp);
126  exit(EXIT_FAILURE);
127  }
128  }
129  // check if EOF came from an end-of-file or an error
130  if (ferror(fp)) {
131  printf("EOF error opening %s. %s.\n", filename, strerror(errno));
132  fclose(fp);
133  exit(EXIT_FAILURE);
134  }
135  env->ysize = y;
136  env->state = malloc(sizeof(double) * 8);
137  xcsf->env = env;
138  fclose(fp);
139  param_init(xcsf, 8, 1, 8);
140 }
141 
146 void
147 env_maze_free(const struct XCSF *xcsf)
148 {
149  struct EnvMaze *env = xcsf->env;
150  free(env->state);
151  free(env);
152 }
153 
158 void
159 env_maze_reset(const struct XCSF *xcsf)
160 {
161  struct EnvMaze *env = xcsf->env;
162  env->done = false;
163  do {
164  env->xpos = rand_uniform_int(0, env->xsize);
165  env->ypos = rand_uniform_int(0, env->ysize);
166  } while (env->maze[env->ypos][env->xpos] != '*');
167 }
168 
174 bool
175 env_maze_is_done(const struct XCSF *xcsf)
176 {
177  const struct EnvMaze *env = xcsf->env;
178  return env->done;
179 }
180 
186 const double *
188 {
189  const struct EnvMaze *env = xcsf->env;
190  int spos = 0;
191  for (int y = -1; y < 2; ++y) {
192  for (int x = -1; x < 2; ++x) {
193  if (x == 0 && y == 0) { // ignore current pos
194  continue;
195  }
196  // toroidal maze
197  const int xsense =
198  ((env->xpos + x) % env->xsize + env->xsize) % env->xsize;
199  const int ysense =
200  ((env->ypos + y) % env->ysize + env->ysize) % env->ysize;
201  const char s = env->maze[ysense][xsense];
202  // convert sensor to real number
203  env->state[spos] = env_maze_sensor(xcsf, s);
204  ++spos;
205  }
206  }
207  return env->state;
208 }
209 
216 double
217 env_maze_execute(const struct XCSF *xcsf, const int action)
218 {
219  if (action < 0 || action > 7) {
220  printf("invalid maze action\n");
221  exit(EXIT_FAILURE);
222  }
223  struct EnvMaze *env = xcsf->env;
224  // toroidal maze
225  const int newx =
226  ((env->xpos + x_moves[action]) % env->xsize + env->xsize) % env->xsize;
227  const int newy =
228  ((env->ypos + y_moves[action]) % env->ysize + env->ysize) % env->ysize;
229  // make the move and receive reward
230  double reward = 0;
231  switch (env->maze[newy][newx]) {
232  case 'O':
233  case 'Q':
234  break;
235  case '*':
236  env->ypos = newy;
237  env->xpos = newx;
238  break;
239  case 'F':
240  case 'G':
241  env->ypos = newy;
242  env->xpos = newx;
243  env->done = true;
244  reward = MAX_PAYOFF;
245  break;
246  default:
247  printf("invalid maze type\n");
248  exit(EXIT_FAILURE);
249  }
250  return reward;
251 }
252 
258 double
260 {
261  (void) xcsf;
262  return MAX_PAYOFF;
263 }
264 
270 bool
272 {
273  (void) xcsf;
274  return true;
275 }
bool env_maze_is_done(const struct XCSF *xcsf)
Returns whether the maze is in a terminal state.
Definition: env_maze.c:175
void env_maze_free(const struct XCSF *xcsf)
Frees the maze environment.
Definition: env_maze.c:147
bool env_maze_multistep(const struct XCSF *xcsf)
Returns whether the environment is a multistep problem.
Definition: env_maze.c:271
static double env_maze_sensor(const struct XCSF *xcsf, const char s)
Returns a float encoding of a sensor perception.
Definition: env_maze.c:74
double env_maze_execute(const struct XCSF *xcsf, const int action)
Executes the specified action and returns the payoff.
Definition: env_maze.c:217
const double * env_maze_get_state(const struct XCSF *xcsf)
Returns the current animat perceptions in the maze.
Definition: env_maze.c:187
static const int y_moves[]
Maze y-axis moves.
Definition: env_maze.c:65
void env_maze_init(struct XCSF *xcsf, const char *filename)
Initialises a maze environment from a specified file.
Definition: env_maze.c:100
static const int x_moves[]
Maze x-axis moves.
Definition: env_maze.c:60
void env_maze_reset(const struct XCSF *xcsf)
Resets the animat to a random empty position in the maze.
Definition: env_maze.c:159
#define MAX_PAYOFF
The payoff provided at a food position.
Definition: env_maze.c:55
double env_maze_maxpayoff(const struct XCSF *xcsf)
Returns the maximum payoff value possible in the maze.
Definition: env_maze.c:259
The discrete maze problem environment module.
#define MAX_SIZE
The maximum width/height of a maze.
Definition: env_maze.h:29
Definition: __init__.py:1
void param_init(struct XCSF *xcsf, const int x_dim, const int y_dim, const int n_actions)
Initialises default XCSF parameters.
Definition: param.c:45
Functions for setting and printing parameters.
Maze environment data structure.
Definition: env_maze.h:34
int xsize
Maze size in x dimension.
Definition: env_maze.h:39
int ysize
Maze size in y dimension.
Definition: env_maze.h:40
bool done
Whether the maze is in a terminal state.
Definition: env_maze.h:41
double * state
Current state.
Definition: env_maze.h:35
int xpos
Current x position.
Definition: env_maze.h:37
int ypos
Current y position.
Definition: env_maze.h:38
char maze[(50)][(50)]
Maze.
Definition: env_maze.h:36
XCSF data structure.
Definition: xcsf.h:85
int rand_uniform_int(const int min, const int max)
Returns a uniform random integer [min,max] not inclusive of max.
Definition: utils.c:74
Utility functions for random number handling, etc.