#include "ktkStructure.h" #include #include #include #include // for randomizeSeed unsigned long ktk_RANDOM_SEED = 1; unsigned long ktk_randomizeSeed() { ktk_RANDOM_SEED = (unsigned long)time(0); #if _WIN32 | _WIN64 srand(ktk_RANDOM_SEED); #else srandom(ktk_RANDOM_SEED); #endif return ktk_RANDOM_SEED; } int ktk_getRandom(int min, int max) { int num; if (min == 0 && max == 0) return 0; if (min == max) return min; // include max as a possible number (+1) int range = (max+1) - min; if (range >= RAND_MAX) { printf("ktk_getRandom(%d, %d): ERROR, range beyond RAND_MAX!\n", min, max); return 0; } else if (range == 0) { return min; } int buckets = RAND_MAX / range; int limit = buckets * range; #if _WIN32 | _WIN64 for (num = rand(); num >= limit; num = rand()); #else for (num = random(); num >= limit; num = random()); #endif return min + (num / buckets); } int ktk_rollNumber(struct ktkNumber number) { return (ktk_getRandom(number.a, number.b)); if (number.type == ktk_PERCENT) { } else if (number.type == ktk_DIGIT) { } } int ktk_rollNumberSet(struct ktkNumberSet set) { if (set.count <= 0) return 0; return ktk_rollNumber(set.sets[ktk_getRandom(0, set.count-1)]); } int ktk_deleteNumberSet(struct ktkNumberSet *set) { if (set->sets != NULL) { free(set->sets); set->sets = NULL; set->count = 0; } return 0; } int ktk_copyNumberSet(struct ktkNumberSet *set_1, struct ktkNumberSet *set_2) { ktk_deleteNumberSet(set_2); if (set_1->count > 0) { set_2->sets = realloc(set_2->sets, set_1->count*sizeof(struct ktkNumber)); memcpy(set_2->sets, set_1->sets, set_1->count*sizeof(struct ktkNumber)); set_2->count = set_1->count; } else { return 1; } return 0; } /*ktkField_t ktkStructureTable[] = { {FIELD(flags)}, {FIELD(x)}, {FIELD(y)}, {FIELD(size_x)}, {FIELD(size_y)}, {FIELD(id_1)}, {FIELD(id_2)}, {FIELD(data)}, {FIELD(relations)}, {FIELD(relation_count)} }; */ //int ktk_setField(ktkField_t *table, size_t table_size, const struct ktkStructure ktk_STRUCTURE_DEFAULT = { 0, NULL, { 0, 0, 0}, { 0, 0, 0}, // x, y { 0, 0, 0}, { 0, 0, 0}, // size_x, size_y { NULL, 0}, // id_1 { NULL, 0}, // id_2 { NULL, 0}, // id_1 replace rules { NULL, 0}, // id_2 replace rules NULL, NULL, 0, // relations NULL, 0 // paths + path count }; void ktk_dumpStructure(struct ktkStructure *structure) { printf("flags: %d\n", structure->flags); printf("name: %s\n", structure->name); printf("x: %dx%d\n", structure->x.a, structure->x.b); printf("y: %dx%d\n", structure->y.a, structure->y.b); printf("size_x: %dx%d\n", structure->size_x.a, structure->size_x.b); printf("size_y: %dx%d\n", structure->size_y.a, structure->size_y.b); } int ktk_deleteStructure(struct ktkStructure *structure) { if (structure->name != NULL) { free(structure->name); structure->name = NULL; } ktk_deleteNumberSet(&structure->id_1); ktk_deleteNumberSet(&structure->id_2); ktk_deleteNumberSet(&structure->replace_id_1); ktk_deleteNumberSet(&structure->replace_id_2); if (structure->relation_count > 0) { int i; for (i = 0; i < structure->relation_count; i++) { //ktk_deleteLive(structure->relations[i]); //free(structure->relations[i]); free(structure->relations[i].name); } free(structure->relations); structure->relations = NULL; structure->relation_count = 0; } if (structure->path_count > 0) { int i; for (i = 0; i < structure->path_count; i++) { free(structure->paths[i].name); free(structure->paths[i].to); free(structure->paths[i].from); ktk_deleteNumberSet(&(structure->paths[i].to_x)); ktk_deleteNumberSet(&(structure->paths[i].to_y)); ktk_deleteNumberSet(&(structure->paths[i].from_x)); ktk_deleteNumberSet(&(structure->paths[i].from_y)); ktk_deleteNumberSet(&(structure->paths[i].x)); ktk_deleteNumberSet(&(structure->paths[i].y)); } free(structure->paths); structure->paths = NULL; structure->path_count = 0; } return 0; } const struct ktkRelation ktk_RELATION_DEFAULT = { 0, NULL, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 1, 1, ktk_DIGIT}, }; const struct ktkLive ktk_LIVE_DEFAULT = { NULL, // name of this NULL, // parent NULL, 0, // children and count NULL, 0, // record pathing links + count of links 0, 0, 0, // x, y 0, 0, // size 0, 0, // id_1, id_2 NULL, // data NULL // map? }; struct ktkLive *ktk_getLiveRoot(struct ktkLive *live) { struct ktkLive *current_live = live; while (current_live->parent != NULL) { current_live = current_live->parent; } return current_live; } struct ktkLive *ktk_getLive(struct ktkLive *live, const char *get, int match_offset) { if (get == NULL) return NULL; printf("offset: %d\n", match_offset); struct ktkLive *current_live = live; size_t get_len = strlen(get); size_t get_offset = 0; while (get_offset < get_len+1) { if (get[get_offset] == ':') { current_live = ktk_getLiveRoot(current_live); get_offset++; } else if (get[get_offset] == '^') { if (current_live->parent != NULL) { current_live = current_live->parent; } else { printf("could not get requested parent of %s\n", current_live->name); return NULL; } get_offset++; } else if (get[get_offset] == '\0') { if (current_live == live) return NULL; return current_live; } else { size_t sub_offset = get_offset; while((get[sub_offset] != '^' && get[sub_offset] != ':')) { if (get[sub_offset] == '\0') break; sub_offset++; } char sub_name[sub_offset - get_offset+1]; memcpy(&sub_name, get+get_offset, sub_offset - get_offset); sub_name[sub_offset-get_offset] = '\0'; size_t i; int found = 0; int match_current = 0; for (i = 0; i < current_live->child_count; i++) { if (strcmp(sub_name, current_live->children[i]->name) == 0) { if (current_live->children[i] == current_live) continue; // we don't match ourself if (get[sub_offset] == '\0') { match_current++; if (match_current > match_offset) { current_live = current_live->children[i]; get_offset = sub_offset+1; found = 1; break; } } else { current_live = current_live->children[i]; get_offset = sub_offset+1; found = 1; break; } } } if (!found) { printf("could not find %s!\n", sub_name); return NULL; } } } if (current_live == live) return NULL; return current_live; } int ktk_addLink(struct ktkLive *live_1, struct ktkLive *live_2) { live_1->link_count++; live_1->links = realloc(live_1->links, live_1->link_count*sizeof(struct ktkLive*)); live_1->links[live_1->link_count-1] = live_2; return 0; } int ktk_containsLink(struct ktkLive *live_1, struct ktkLive *live_2) { int i; for (i = 0; i < live_1->link_count; i++) { if (live_1->links[i] == live_2) { return 1; } } return 0; } int ktk_deleteLive(struct ktkLive *live) { if (live->name != NULL) { free(live->name); live->name = NULL; } if (live->child_count > 0) { int i; for (i = 0; i < live->child_count; i++) { ktk_deleteLive(live->children[i]); free(live->children[i]); } free(live->children); live->children = NULL; live->child_count = 0; } if (live->link_count > 0) { free(live->links); live->links = NULL; } return 0; } int ktk_addLiveChild(struct ktkLive *parent, struct ktkLive *child) { parent->child_count++; parent->children = realloc(parent->children, parent->child_count*sizeof(struct ktkLive*)); parent->children[parent->child_count-1] = child; child->parent = parent; return 0; } int ktk_setLiveName(struct ktkLive *live, const char *name) { if (live->name != NULL) { free(live->name); live->name = NULL; } int size = strlen(name)+1; live->name = malloc(size); memcpy(live->name, name, size); return 0; } const struct ktkPath ktk_PATH_DEFAULT = { NULL, // pathing structure name NULL, // pathing structure 0, // pathing flags NULL, 0, // target structure in pathing syntax, target flags {NULL, 0}, // to x offset {NULL, 0}, // to y offset NULL, 0, // from structure in pathing syntax, from flags {NULL, 0}, // from x offset {NULL, 0}, // from y offset {NULL, 0}, // x offset {NULL, 0} // y offset }; int ktk_explodeString(const char *string, char delim, int depth, char ***results) { int words = 0, word_size = 1, word_i = 0; int i = 0; int len = strlen(string)+1; // TODO: resize in 8-byte chunks or so *results = malloc(1*sizeof(char*)); (*results)[words] = malloc(1*sizeof(char)); for (i = 0; i < len; i++) { if ((string[i] == delim && words < depth) || string[i] == '\0') { (*results)[words][word_i] = '\0'; *results = realloc(*results, (++words+1)*sizeof(char*)); (*results)[words] = malloc(1*sizeof(char)); //(*results)[words][0] = '\0'; word_i = 0; word_size = 1; } else { (*results)[words] = realloc((*results)[words], ++word_size*sizeof(char)); (*results)[words][word_i++] = string[i]; } } return words; }