return ok;
}
+char *command_get(command_t *self, int i) {
+ char **p = array_get(self->data, i);
+ return *p;
+}
+
+int command_get_int(command_t *self, int i) {
+ char **p = array_get(self->data, i);
+ return atoi(*p);
+}
+
array_t *read_word(command_t *self,const char line[],int pstart,int pstop) {
array_t *tmp = new_array(sizeof(char *), 1);
howmany_read++;
}
- if ((pstop >= 0) && (tmp->count != (pstop - pstart))) {
+ if ((pstop >= 0) && (tmp->count != ((pstop - pstart) + 1))) {
free_array(tmp);
tmp = NULL;
}
* blablabla
*/
typedef enum {
+ COMMAND_COMMENT,
COMMAND_TICK,
COMMAND_DISPLAY,
COMMAND_READFILE,
int command_read_file(command_t *self,const char line[],int pstart,int pstop);
+char *command_get(command_t *self, int i);
+
+int command_get_int(command_t *self, int i);
+
#endif /* COMMAND_H */
int tickit();
-engine_t *new_engine(map_t *map) {
+engine_t *new_engine() {
engine_t *self = malloc(sizeof(engine_t));
- if (!init_engine(self, map)) {
+ if (!init_engine(self)) {
free(self);
self = NULL;
}
return self;
}
-int init_engine(engine_t *self, map_t *map) {
+int init_engine(engine_t *self) {
size_t sz = sizeof(self->CNAME);
strncpy(self->CNAME, "[engine ", sz);
self->CNAME[sz - 2] = ']';
self->CNAME[sz - 1] = '\0';
- self->map = map;
+ self->map = NULL;
self->current_tick = 0;
self->waves = new_array(sizeof(wave_t) , 10);
self->events = new_array(sizeof(event_t), 20);
free_array(self->ebases) ; self->ebases = NULL;
}
+int engine_reset_map(engine_t *self, int width, int height) {
+ if (self->map)
+ free_map(self->map);
+ self->current_tick = 0;
+ self->current_wave = 0;
+ self->last_enemy = NULL;
+ self->map = new_map(width, height);
+
+ return !!self->map;
+}
+
void engine_tick(engine_t *self) {
+ if (!self->map) {
+ event_t event;
+ init_event(&event, ERROR);
+ event.x = EEVENT_NOMAP;
+ array_push(self->events, &event);
+
+ return;
+ }
+
// Note that multiple ennemies per tick will trigger the backfill
array_loop_i (self->waves, wave, wave_t, i) {
if (wave->done)
/**
* Create a new engine.
*
- * @param map the game map (will be owned by this engine)
- *
* @note always identical to <tt>malloc</tt> + <tt>init_engine</tt>
*
* @see malloc()
*
* @return a new engine (you must later call `free_engine()`)
*/
-engine_t *new_engine(map_t *map);
+engine_t *new_engine();
/**
* Initialise a new engine.
- *
- * @param map the game map (will be owned by this engine)
*/
-int init_engine(engine_t *self, map_t *map);
+int init_engine(engine_t *self);
/**
* Free the resources held for the given engine: you must not use it any more.
*/
void uninit_engine(engine_t *self);
+// @param map the game map (will be owned by this engine)
+int engine_reset_map(engine_t *self, int width, int height);
+
// will clear events on start!
void engine_tick(engine_t *self);
case WAVE : return "WAVE" ;
case WIN : return "WIN" ;
case LOOSE : return "LOOSE" ;
+ case ERROR : return "ERROR" ;
}
return "Unknown";
}
case WIN: case LOOSE:
cstring_addp(out, "EVENT:%s\n", name);
break;
+ case ERROR:
+ cstring_addp(out, "ERROR: %d\n", self->x);
+ break;
}
}
WAVE,
WIN,
LOOSE,
+ ERROR,
} event_type;
+typedef enum {
+ EEVENT_NOMAP,
+} eevent_type;
+
/**
* @brief bla
*
// KEYWORD
// or:
// KEYWORD: [parameters]
+// or:
+// # comment... (mostly used for data files)
//
// Parameters are given in the form of:
// int_parameter1, int_parameter2...
char car = line->string[first_non_space];
if ((car == ':') || (car == '\0'))
return 1;
+ // Special empty line/comment check:
+ if (!cmd[0] && car == '#')
+ return 1;
}
return 0;
if (cstring_readline(line, file)) {
cmd = new_command(COMMAND_UNKNOWN);
- if (is_cmd(line, ".")) {
+ if (is_cmd(line, "")) { // also checks for "#"
+ cmd->type = COMMAND_COMMENT;
+ } else if (is_cmd(line, ".")) {
cmd->type = COMMAND_TICK;
if (command_read_count(cmd, line->string))
cmd->type = COMMAND_INVALID;
cmd->type = COMMAND_MAP;
if (!command_read_int(cmd, line->string, 0, 1))
cmd->type = COMMAND_INVALID;
- if (command_read_count(cmd, line->string) > 2)
+ if (command_read_count(cmd, line->string) != 2)
cmd->type = COMMAND_INVALID;
} else if (is_cmd(line, "life")) {
cmd->type = COMMAND_LIFE;
#include <stdlib.h>
#include "setup.h"
+#include "event.h"
tower_base_t *setup_tower_base(engine_t *self, int type, int cost) {
tower_base_t *base = engine_get_tower_base(self, type);
}
int setup_path(engine_t *self, int x, int y) {
+ if (!self->map) {
+ event_t event;
+ init_event(&event, ERROR);
+ event.x = EEVENT_NOMAP;
+ array_push(self->events, &event);
+
+ return 0;
+ }
+
return map_add_path(self->map, x, y);
}
out = new_cstring();
switch(cmd->type) {
+ case COMMAND_COMMENT:
+ break;
case COMMAND_TICK:
engine_tick(engine);
break;
fprintf(stdout, "Done reading: %s\n",subname);
}
break;
+ case COMMAND_MAP:
+ engine_reset_map(
+ engine,
+ command_get_int(cmd, 0),
+ command_get_int(cmd, 1)
+ );
+ break;
+ case COMMAND_LIFE:
+ engine->life = command_get_int(cmd, 0);
+ break;
+ case COMMAND_BITS:
+ engine->bits = command_get_int(cmd, 0);
+ break;
+ case COMMAND_PATH:
+ setup_path(
+ engine,
+ command_get_int(cmd, 0),
+ command_get_int(cmd, 1)
+ );
+ break;
+ case COMMAND_QUIT:
+ return 0;
+
+ // Error management:
case COMMAND_FILE404:
fprintf(stderr, "Unknown file(s):\n");
array_loop_i (cmd->data, ptr, char*, i) {
case COMMAND_INVALID:
fprintf(stderr, "Invalid command\n");
break;
- case COMMAND_QUIT:
- return 0;
}
// Process all events
}
int main(int argc, char **argv) {
- map_t *map = new_map(6, 4);
- engine_t *engine = new_engine(map);
- if (!map || !engine) {
+ engine_t *engine = new_engine();
+ if (!engine) {
fprintf(stderr, "Allocation error");
return 1;
}
- setup_path(engine, 0, 0);
- setup_path(engine, 1, 0);
- setup_path(engine, 2, 0);
- setup_path(engine, 3, 0);
- setup_path(engine, 3, 1);
- setup_path(engine, 3, 2);
- setup_path(engine, 4, 2);
- setup_path(engine, 5, 2);
-
- setup_tower_base(engine, 0, 10);
-
- enemy_t *enemy = setup_enemy(engine, 0, 0, 0);
- enemy->speed = 2;
- enemy->bits = 5;
-
- engine->bits = 100;
- engine_add_tower(engine, 0, 2, 1);
+ /* DEBUG */
+ command_t debug;
+ init_command(&debug, COMMAND_READFILE);
+ debug.data = new_array(sizeof(char **), 1);
+ char **ptr = array_new(debug.data);
+ *ptr = cstring_convert(cstring_clone("setup.debug"));
+ process_cmd(&debug, engine);
+ /* */
read_commands(engine, stdin);