From: Niki Roo Date: Fri, 4 Apr 2025 22:51:25 +0000 (+0200) Subject: some code and cutils X-Git-Url: http://git.nikiroo.be/?a=commitdiff_plain;h=7d30a879ef18c2ca18fdefd14b882c7ae12b5343;p=tdef.git some code and cutils --- diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..abd99b7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "src/cutils"] + path = src/cutils + url = git@git.nikiroo.be:workspace/cutils.git + branch = subtree diff --git a/Makefile b/Makefile index 790beea..44eac28 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,9 @@ # > NAMES: list of all the programs to compile # > TESTS: list of all test programs to compile and run # -NAME = program -NAMES = $(NAME) program2 -TESTS = tests-program +NAME = tdef +NAMES = $(NAME) +TESTS = ################################################################################ diff --git a/src/cutils b/src/cutils new file mode 160000 index 0000000..d6fa07c --- /dev/null +++ b/src/cutils @@ -0,0 +1 @@ +Subproject commit d6fa07c12023662e16ace68bba78047e0244a9f7 diff --git a/src/tdef/Makefile b/src/tdef/Makefile new file mode 100755 index 0000000..4b2abfa --- /dev/null +++ b/src/tdef/Makefile @@ -0,0 +1,10 @@ +# Simply pass everything to makefile.d, but calling from "../" + +.PHONY: default $(MAKECMDGOALS) + +default $(MAKECMDGOALS): + @for mk in makefile.d; do \ + $(MAKE) --no-print-directory -C ../ -f "$(CURDIR)/$$mk" \ + $(MAKECMDGOALS); \ + done; + diff --git a/src/tdef/any.c b/src/tdef/any.c new file mode 100644 index 0000000..0315baa --- /dev/null +++ b/src/tdef/any.c @@ -0,0 +1,54 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "any.h" + +path_t *anyloc(any_t *self) { + if (self && self->_.type == 'l') + return (path_t*)(void*)self; + return NULL; +} + +tower_t *anytower(any_t *self) { + if (self && self->_.type == 't') + return (tower_t*)(void*)self; + return NULL; +} + +enemy_t *anyenemy(any_t *self) { + if (self && self->_.type == 'e') + return (enemy_t*)(void*)self; + return NULL; +} + +any_t *loc2any(path_t *self) { + return (any_t*)(void*)self; +} + +any_t *tower2any(tower_t *self) { + return (any_t*)(void*)self; +} + +any_t *enemy2any(enemy_t *self) { + return (any_t*)(void*)self; +} + diff --git a/src/tdef/any.h b/src/tdef/any.h new file mode 100644 index 0000000..33a755e --- /dev/null +++ b/src/tdef/any.h @@ -0,0 +1,44 @@ +/** + * @file any.h + * @author Niki + * @date 2025 + * + * @brief bla + * + * blablabla + * + */ + +#ifndef ANY_H +#define ANY_H + +#include "path.h" +#include "tower.h" +#include "enemy.h" + +/** + * @brief bla + * + * blablabla + */ +typedef union { + struct { char _; char type; } _; + path_t _l; + tower_t _t; + enemy_t _e; +} any_t; + +path_t *anyloc(any_t *self); + +tower_t *anytower(any_t *self); + +enemy_t *anyenemy(any_t *self); + +any_t *loc2any(path_t *self); + +any_t *tower2any(tower_t *self); + +any_t *enemy2any(enemy_t *self); + +#endif /* ANY_H */ + diff --git a/src/tdef/enemy.c b/src/tdef/enemy.c new file mode 100644 index 0000000..b611728 --- /dev/null +++ b/src/tdef/enemy.c @@ -0,0 +1,56 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "enemy.h" + +enemy_t *new_enemy(size_t start_tick) { + enemy_t *self = malloc(sizeof(enemy_t)); + if (!init_enemy(self, start_tick)) { + free(self); + self = NULL; + } + + return self; +} + +int init_enemy(enemy_t *self, size_t start_tick) { + size_t sz = sizeof(self->CNAME); + strncpy(self->CNAME, "[enemy ", sz); + self->CNAME[sz - 2] = ']'; + self->CNAME[sz - 1] = '\0'; + + self->start_tick = start_tick; + + return 1; +} + +void free_enemy(enemy_t *self) { + if (self) + uninit_enemy(self); + + free(self); +} + +void uninit_enemy(enemy_t *self) { + self->CNAME[0] = '!'; +} + diff --git a/src/tdef/enemy.h b/src/tdef/enemy.h new file mode 100644 index 0000000..5702326 --- /dev/null +++ b/src/tdef/enemy.h @@ -0,0 +1,71 @@ +/** + * @file enemy.h + * @author Niki + * @date 2025 + * + * @brief bla + * + * blablabla + * + */ + +#ifndef ENEMY_H +#define ENEMY_H + +#include + +/** + * @brief bla + * + * blablabla + */ +typedef struct { + char CNAME[10]; + size_t start_tick; + int hp; + int speed; // paths per tick +} enemy_t; + +/** + * Create a new enemy. + * + * @param start_tick the tick at which the enemy will start on the map + * + * @note always identical to malloc + init_enemy + * + * @see malloc() + * @see init_enemy(enemy_t *self) + * + * @return a new enemy (you must later call `free_enemy()`) + */ +enemy_t *new_enemy(size_t start_tick); + +/** + * Initialise a new enemy. + * + * @param start_tick the tick at which the enemy will start on the map + */ +int init_enemy(enemy_t *self, size_t start_tick); + +/** + * Free the resources held for the given enemy: you must not use it any more. + * + * @note always equivalent to uninit_enemy + free + * + * @see uninit_enemy(enemy_t *self) + * @see free(void *data) + */ +void free_enemy(enemy_t *self); + +/** + * Free the resources held for the given enemy: you must not use it any more + * unless you call init_enemy on it again. + * + * The memory pointed to by self is not free'd. + * + * + * @see init_enemy(enemy_t *self) + */ +void uninit_enemy(enemy_t *self); + +#endif /* ENEMY_H */ diff --git a/src/tdef/engine.c b/src/tdef/engine.c new file mode 100644 index 0000000..ca2c7ff --- /dev/null +++ b/src/tdef/engine.c @@ -0,0 +1,93 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "engine.h" + +void move(engine_t *self, enemy_t *enemy, path_t *path); + +engine_t *new_engine(map_t *map) { + engine_t *self = malloc(sizeof(engine_t)); + if (!init_engine(self, map)) { + free(self); + self = NULL; + } + + return self; +} + +int init_engine(engine_t *self, map_t *map) { + size_t sz = sizeof(self->CNAME); + strncpy(self->CNAME, "[engine ", sz); + self->CNAME[sz - 2] = ']'; + self->CNAME[sz - 1] = '\0'; + + self->map = map; + self->current_tick = 0; + self->events = new_array(sizeof(int), 10); + self->last_enemy = NULL; + + return (self->events != NULL); +} + +void free_engine(engine_t *self) { + if (self) + uninit_engine(self); + + free(self); +} + +void uninit_engine(engine_t *self) { + self->CNAME[0] = '!'; + free_map(self->map); + self->map = NULL; + free_array(self->events); + self->events = NULL; +} + +void engine_tick(engine_t *self) { +printf("Tick is: %d\n", self->current_tick); + array_clear(self->events); + + // TODO: all the rest + + enemy_t *enemy; + if (self->last_enemy) + enemy = array_next(self->map->enemies, self->last_enemy); + else + enemy = array_first(self->map->enemies); + + // We allow only one enemy per tick (because one per path!) + if (enemy->start_tick == self->current_tick) { + move(self, enemy, array_first(self->map->paths)); + } + + self->current_tick++; +} + + +void move(engine_t *self, enemy_t *enemy, path_t *path) { + if (path->enemy) + printf("woops: TODO"); + + path->enemy = enemy; +} + diff --git a/src/tdef/engine.h b/src/tdef/engine.h new file mode 100644 index 0000000..b19d6e9 --- /dev/null +++ b/src/tdef/engine.h @@ -0,0 +1,80 @@ +/** + * @file engine.h + * @author Niki + * @date 2025 + * + * @brief bla + * + * blablabla + * + */ + +#ifndef ENGINE_H +#define ENGINE_H + +#include +#include "cutils/array.h" +#include "map.h" + +/** + * @brief bla + * + * blablabla + */ +typedef struct { + char CNAME[10]; + map_t *map; + size_t current_tick; + array_t *events; + enemy_t *last_enemy; +} engine_t; + +/** + * Create a new engine. + * + * @param map the game map (will be owned by this engine) + * + * @note always identical to malloc + init_engine + * + * @see malloc() + * @see init_engine(engine_t *self) + * + * @return a new engine (you must later call `free_engine()`) + */ +engine_t *new_engine(map_t *map); + +/** + * Initialise a new engine. + * + * @param map the game map (will be owned by this engine) + */ +int init_engine(engine_t *self, map_t *map); + +/** + * Free the resources held for the given engine: you must not use it any more. + * The map will also be free'd. + * + * @note always equivalent to uninit_engine + free + * + * @see uninit_engine(engine_t *self) + * @see free(void *data) + */ +void free_engine(engine_t *self); + +/** + * Free the resources held for the given engine: you must not use it any more + * unless you call init_engine on it again. + * The map will also be free'd. + * + * The memory pointed to by self is not free'd. + * + * + * @see init_engine(engine_t *self) + */ +void uninit_engine(engine_t *self); + +// will clear events on start! +void engine_tick(engine_t *self); + +#endif /* ENGINE_H */ + diff --git a/src/tdef/makefile.d b/src/tdef/makefile.d new file mode 100755 index 0000000..c093aa2 --- /dev/null +++ b/src/tdef/makefile.d @@ -0,0 +1,108 @@ +# +# Makefile for C projets +# > NAME : the name of the main program (if programs, make a single .d file +# per program, link them up in Makfile and use a $ssrcdir) +# > srcdir : the source directory +# > ssrcdir: the sub-sources directory (defaults to $srcdir) +# > dstdir: the destination directory (defaults to $srcdir/bin) +# +# Environment variables: +# > PREFIX: where to (un)install (defaults to /usr/local) +# > DEBUG: define it to build with all debug symbols +# +NAME = tdef +srcdir = $(NAME) +ssrcdir = $(srcdir) + +# Note: c99+ required for for-loop initial declaration (not default in CentOS 6) +# Note: gnu99 can be required for some projects (i.e.: libcutils-net) +CFLAGS += -Wall -pedantic -I./ -std=c99 +CXXFLAGS += -Wall -pedantic -I./ +PREFIX = /usr/local + +# Required libraries if any: +# LDFLAGS += -lcheck $(shell pkg-config --libs --clfags check) + +# Required *locally compiled* libraries if any: +# LIBS = cutils +LIBS = cutils + +################################################################################ + +ifeq ($(dstdir),) +dstdir = $(srcdir)/bin +endif + +ifdef DEBUG +CFLAGS += -ggdb -O0 +CXXFLAGS += -ggdb -O0 +endif + +# Default target +.PHONY: all deps +all: + +# locally compiled libs: +ifneq ($(LIBS),) +LDFLAGS += -L$(dstdir) +LDFLAGS += $(foreach lib,$(LIBS),-l$(lib)) +endif +deps: + $(foreach lib,$(LIBS),$(MAKE) --no-print-directory \ + -C $(lib)/ $(lib) dstdir=$(dstdir)) + +.PHONY: build rebuild install uninstall clean mrpropre mrpropre \ + $(NAME) test run run-test run-test-more + +SOURCES=$(wildcard $(ssrcdir)/*.c) +OBJECTS=$(SOURCES:%.c=%.o) +DEPENDS =$(SOURCES:%.c=%.d) + +# Autogenerate dependencies from code +-include $(DEPENDS) +%.o: %.c + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ + +# Main targets + +all: build + +build: $(NAME) + +rebuild: clean build + +$(NAME): deps $(dstdir)/$(NAME) + +# Program, so no test +run: + @echo + $(dstdir)/$(NAME) --help +test run-test run-test-more: + @echo you are in the sources of the program, look at the tests instead + +$(dstdir)/$(NAME): $(OBJECTS) + mkdir -p $(dstdir) + # note: LDFLAGS *must* be near the end + $(CC) $(CFLAGS) $(OBJECTS) -o $@ $(LDFLAGS) + +clean: + $(foreach lib,$(LIBS),$(MAKE) --no-print-directory \ + -C $(lib)/ $@ dstdir=$(dstdir)) + rm -f $(OBJECTS) + rm -f $(DEPENDS) + +mrproper: mrpropre +mrpropre: clean + $(foreach lib,$(LIBS),$(MAKE) --no-print-directory \ + -C $(lib)/ $@ dstdir=$(dstdir)) + rm -f $(dstdir)/$(NAME) + rmdir $(dstdir) 2>/dev/null || true + +install: build + mkdir -p "$(PREFIX)/bin" + cp "$(dstdir)/$(NAME)" "$(PREFIX)/bin/" + +uninstall: + rm "$(PREFIX)/bin/$(NAME)" + rmdir "$(PREFIX)/bin" 2>/dev/null + diff --git a/src/tdef/map.c b/src/tdef/map.c new file mode 100644 index 0000000..91c31c8 --- /dev/null +++ b/src/tdef/map.c @@ -0,0 +1,129 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "map.h" + +map_t *new_map(int width, int height) { + map_t *self = malloc(sizeof(map_t)); + if (!init_map(self, width, height)) { + free(self); + self = NULL; + } + + return self; +} + +int init_map(map_t *self, int width, int height) { + size_t sz = sizeof(self->CNAME); + strncpy(self->CNAME, "[map ", sz); + self->CNAME[sz - 2] = ']'; + self->CNAME[sz - 1] = '\0'; + + self->width = width; + self->height = height; + self->data = calloc((width*height), sizeof(any_t*)); + + self->paths = new_array(sizeof(path_t ), 100); + self->towers = new_array(sizeof(tower_t*), 20); + self->enemies = new_array(sizeof(enemy_t ), 100); + self->alive = new_array(sizeof(enemy_t*), 10); + + if (!self->data || !self->paths || !self->towers + || !self->enemies || !self->alive + ) { + uninit_map(self); + return 0; + } + + return 1; +} + +void free_map(map_t *self) { + if (self) + uninit_map(self); + + free(self); +} + +void uninit_map(map_t *self) { + self->CNAME[0] = '!'; + + if (self->towers) { + array_loop(self->towers, tower, tower_t*) { + free_tower(*tower); + } + } + + if (self->enemies) { + array_loop(self->enemies, enemy, enemy_t) { + uninit_enemy(enemy); + } + } + + free (self->data ); self->data = NULL; + free_array(self->paths ); self->paths = NULL; + free_array(self->towers ); self->towers = NULL; + free_array(self->enemies); self->enemies = NULL; + free_array(self->alive) ; self->alive = NULL; +} + +int map_path(map_t *self, int x, int y) { + if (x < 0 || y < 0) + return 0; + if (x >= self->width || y >= self->height) + return 0; + if (self->data[y * self->width + x]) + return 0; + + path_t *loc = array_new(self->paths); + init_path(loc, x, y); + loc->index = self->paths->count - 1; + + self->data[y * self->width + x] = loc2any(loc); + return 1; +} + +int map_add_tower(map_t *self, tower_t *tower) { + int x = tower->x; + int y = tower->y; + if (x < 0 || y < 0) + return 0; + if (x >= self->width || y >= self->height) + return 0; + if (self->data[y * self->width + x]) + return 0; + + tower_t **ttt = array_new(self->towers); + *ttt = tower; + + self->data[y * self->width + x] = tower2any(tower); + return 1; +} + +int map_enemy(map_t *self, enemy_t *enemy) { + if (!array_push(self->enemies, enemy)) + return 0; + + return 1; +} + diff --git a/src/tdef/map.h b/src/tdef/map.h new file mode 100644 index 0000000..e8c4ff1 --- /dev/null +++ b/src/tdef/map.h @@ -0,0 +1,86 @@ +/** + * @file map.h + * @author Niki + * @date 2025 + * + * @brief bla + * + * blablabla + * + */ + +#ifndef MAP_H +#define MAP_H + +#include "cutils/array.h" + +#include "any.h" + +/** + * @brief bla + * + * blablabla + */ +typedef struct { + char CNAME[10]; + int width; + int height; + any_t **data; + array_t *paths; + array_t *towers; + array_t *enemies; + array_t *alive; +} map_t; + +/** + * Create a new map. + * + * @param width the width of the map + * @param height the height of the map + * + * @note always identical to malloc + init_map + * + * @see malloc() + * @see init_map(map_t *self) + * + * @return a new map (you must later call `free_map()`) + */ +map_t *new_map(int width, int height); + +/** + * Initialise a new map. + * + * @param width the width of the map + * @param height the height of the map + */ +int init_map(map_t *self, int width, int height); + +/** + * Free the resources held for the given map: you must not use it any more. + * + * @note always equivalent to uninit_map + free + * + * @see uninit_map(map_t *self) + * @see free(void *data) + */ +void free_map(map_t *self); + +/** + * Free the resources held for the given map: you must not use it any more + * unless you call init_map on it again. + * + * The memory pointed to by self is not free'd. + * + * + * @see init_map(map_t *self) + */ +void uninit_map(map_t *self); + +int map_path(map_t *self, int x, int y); + +int map_add_tower(map_t *self, tower_t *tower); + +int map_enemy(map_t *self, enemy_t *enemy); + +#endif /* MAP_H */ + diff --git a/src/tdef/path.c b/src/tdef/path.c new file mode 100644 index 0000000..0f8bb82 --- /dev/null +++ b/src/tdef/path.c @@ -0,0 +1,59 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "path.h" + +path_t *new_path(int x, int y) { + path_t *self = malloc(sizeof(path_t)); + if (!init_path(self, x, y)) { + free(self); + self = NULL; + } + + return self; +} + +int init_path(path_t *self, int x, int y) { + size_t sz = sizeof(self->CNAME); + strncpy(self->CNAME, "[loc ", sz); + self->CNAME[sz - 2] = ']'; + self->CNAME[sz - 1] = '\0'; + + self->x = x; + self->y = y; + self->index = -1; + self->enemy = NULL; + + return 1; +} + +void free_path(path_t *self) { + if (self) + uninit_path(self); + + free(self); +} + +void uninit_path(path_t *self) { + self->CNAME[0] = '!'; +} + diff --git a/src/tdef/path.h b/src/tdef/path.h new file mode 100644 index 0000000..e4d8c22 --- /dev/null +++ b/src/tdef/path.h @@ -0,0 +1,74 @@ +/** + * @file path.h + * @author Niki + * @date 2025 + * + * @brief bla + * + * blablabla + * + */ + +#ifndef PATH_H +#define PATH_H + +#include "enemy.h" + +/** + * @brief bla + * + * blablabla + */ +typedef struct { + char CNAME[10]; + int x; + int y; + int index; + enemy_t *enemy; +} path_t; + +/** + * Create a new loc. + * + * @param x the X coordinate + * @param y the Y coordinate + * + * @note always identical to malloc + init_path + * + * @see malloc() + * @see init_path(path_t *self) + * + * @return a new loc (you must later call `free_path()`) + */ +path_t *new_path(int x, int y); + +/** + * Initialise a new loc. + * + * @param x the X coordinate + * @param y the Y coordinate + */ +int init_path(path_t *self, int x, int y); + +/** + * Free the resources held for the given loc: you must not use it any more. + * + * @note always equivalent to uninit_path + free + * + * @see uninit_path(path_t *self) + * @see free(void *data) + */ +void free_path(path_t *self); + +/** + * Free the resources held for the given loc: you must not use it any more + * unless you call init_path on it again. + * + * The memory pointed to by self is not free'd. + * + * + * @see init_path(path_t *self) + */ +void uninit_path(path_t *self); + +#endif /* PATH_H */ diff --git a/src/tdef/tdef.c b/src/tdef/tdef.c new file mode 100644 index 0000000..4c4b914 --- /dev/null +++ b/src/tdef/tdef.c @@ -0,0 +1,92 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "any.h" +#include "map.h" +#include "engine.h" + +void display(map_t *self) { + printf("==========\n\n"); + for (int y = 0 ; y < self->height; y++) { + for (int x = 0 ; x < self->width ; x++) { + any_t *any = self->data[y * self->width + x]; + path_t *path = anyloc(any); + tower_t *tower = anytower(any); + if (tower) { + printf("T"); + } else if (path) { + if (path->enemy) { + printf("e"); + } + else if (path->index == 0) { + printf(">"); + } else if (path->index == self->paths->count - 1) { + printf(">"); + } else { + printf("#"); + } + } else if (any) { + printf("?"); + //printf("\n<%s>\n", any->CNAME); + } else { + printf("."); + } + } + printf("\n"); + } + printf("\n"); +} + +int main(int argc, char **argv) { + map_t *map = new_map(6, 4); + if (!map) { + fprintf(stderr, "Cannot create the map"); + return 1; + } + + map_path(map, 0, 0); + map_path(map, 1, 0); + map_path(map, 2, 0); + map_path(map, 3, 0); + map_path(map, 3, 1); + map_path(map, 3, 2); + map_path(map, 4, 2); + map_path(map, 5, 2); + + tower_t *tower = new_tower(2, 1); + map_add_tower(map, tower); + + enemy_t *enemy = new_enemy(1); + map_enemy(map, enemy); + + engine_t *engine = new_engine(map); + engine_tick(engine); + + display(map); + engine_tick(engine); + display(map); + + free_engine(engine); + return 0; +} + diff --git a/src/tdef/tower.c b/src/tdef/tower.c new file mode 100644 index 0000000..40aa981 --- /dev/null +++ b/src/tdef/tower.c @@ -0,0 +1,57 @@ +/* + * TDef: small tower defense game + * + * Copyright (C) 2025 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "tower.h" + +tower_t *new_tower(int x, int y) { + tower_t *self = malloc(sizeof(tower_t)); + if (!init_tower(self, x, y)) { + free(self); + self = NULL; + } + + return self; +} + +int init_tower(tower_t *self, int x, int y) { + size_t sz = sizeof(self->CNAME); + strncpy(self->CNAME, "[tower ", sz); + self->CNAME[sz - 2] = ']'; + self->CNAME[sz - 1] = '\0'; + + self->x = x; + self->y = y; + + return 1; +} + +void free_tower(tower_t *self) { + if (self) + uninit_tower(self); + + free(self); +} + +void uninit_tower(tower_t *self) { + self->CNAME[0] = '!'; +} + diff --git a/src/tdef/tower.h b/src/tdef/tower.h new file mode 100644 index 0000000..890b454 --- /dev/null +++ b/src/tdef/tower.h @@ -0,0 +1,70 @@ +/** + * @file tower.h + * @author Niki + * @date 2025 + * + * @brief bla + * + * blablabla + * + */ + +#ifndef TOWER_H +#define TOWER_H + +/** + * @brief bla + * + * blablabla + */ +typedef struct { + char CNAME[10]; + int x; + int y; +} tower_t; + +/** + * Create a new tower. + * + * @param x the X coordinate + * @param y the Y coordinate + * + * @note always identical to malloc + init_tower + * + * @see malloc() + * @see init_tower(tower_t *self) + * + * @return a new tower (you must later call `free_tower()`) + */ +tower_t *new_tower(int x, int y); + +/** + * Initialise a new tower. + * + * @param x the X coordinate + * @param y the Y coordinate + */ +int init_tower(tower_t *self, int x, int y); + +/** + * Free the resources held for the given tower: you must not use it any more. + * + * @note always equivalent to uninit_tower + free + * + * @see uninit_tower(tower_t *self) + * @see free(void *data) + */ +void free_tower(tower_t *self); + +/** + * Free the resources held for the given tower: you must not use it any more + * unless you call init_tower on it again. + * + * The memory pointed to by self is not free'd. + * + * + * @see init_tower(tower_t *self) + */ +void uninit_tower(tower_t *self); + +#endif /* TOWER_H */