X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=libplomrogue.c;h=33da37af6e2085940b2586be22951f9267a15cd4;hb=842bb83352b0f1d62936c568df766d7502c51071;hp=384c81db0094fd512a5e2eb8b6e7407cea2926c5;hpb=94504421e041769058facdea5dbf310d3561c3aa;p=plomrogue diff --git a/libplomrogue.c b/libplomrogue.c index 384c81d..33da37a 100644 --- a/libplomrogue.c +++ b/libplomrogue.c @@ -1,3 +1,4 @@ +#include /* pow() */ #include /* NULL */ #include /* ?(u)int(8|16|32)_t, ?(U)INT8_(MIN|MAX) */ #include /* free, malloc */ @@ -339,7 +340,8 @@ static uint8_t shade_hex(uint32_t left_angle, uint32_t right_angle, */ static uint8_t eval_position(uint16_t dist, uint16_t hex_i, char * fov_map, struct yx_uint8 * test_pos, - struct shadow_angle ** shadows) + struct shadow_angle ** shadows, + const char * symbols_obstacle) { int32_t left_angle_uncorrected = ((CIRCLE / 12) / dist) - (hex_i * (CIRCLE / 6) / dist); @@ -356,7 +358,7 @@ static uint8_t eval_position(uint16_t dist, uint16_t hex_i, char * fov_map, uint16_t pos_in_map = test_pos->y * maplength + test_pos->x; uint8_t all_shaded = shade_hex(left_angle, right_angle_1st, middle_angle, shadows, pos_in_map, fov_map); - if (!all_shaded && 'X' == worldmap[pos_in_map]) + if (!all_shaded && NULL != strchr(symbols_obstacle, worldmap[pos_in_map])) { if (set_shadow(left_angle, right_angle_1st, shadows)) { @@ -377,8 +379,9 @@ static uint8_t eval_position(uint16_t dist, uint16_t hex_i, char * fov_map, /* Update field of view in "fovmap" of "worldmap_input" as seen from "y"/"x". * Return 1 on malloc error, else 0. */ -extern uint8_t build_fov_map(uint8_t y, uint8_t x, - char * fovmap, char * worldmap_input) +extern uint8_t build_fov_map(uint8_t y, uint8_t x, char * fovmap, + char * worldmap_input, + const char * symbols_obstacle) { worldmap = worldmap_input; struct shadow_angle * shadows = NULL; @@ -407,7 +410,8 @@ extern uint8_t build_fov_map(uint8_t y, uint8_t x, } if (mv_yx_in_dir_legal(dir_char, &test_pos)) { - if (eval_position(circle_i, hex_i, fovmap, &test_pos, &shadows)) + if (eval_position(circle_i, hex_i, fovmap, &test_pos, &shadows, + symbols_obstacle)) { return 1; } @@ -448,20 +452,6 @@ extern uint8_t set_map_score(uint16_t pos, uint16_t score) return 1; } score_map[pos] = score; -/* - uint32_t mup_size = maplength * maplength; - uint32_t pus; - FILE * file = fopen("test_set", "w"); - for (pus = 0; pus < mup_size; pus++) - { - fprintf(file, "%d ", score_map[pus]); - if (0 == pus % maplength) - { - fprintf(file, "\n"); - } - } - fclose(file); -*/ return 0; } @@ -532,7 +522,8 @@ extern uint16_t get_neighbor_score(uint8_t i) * neighbor's score is at least two points lower than the current cell's score, * re-set it to 1 point higher than its lowest-scored neighbor. Repeat this * whole process until all cells have settled on their final score. Ignore cells - * whose score is greater than UINT16_MAX - 1 (treat those as unreachable). + * whose score is greater than UINT16_MAX - 1 (treat those as unreachable). Also + * ignore cells whose score is smaller or equal the number of past iterations. * Return 1 on error, else 0. */ extern uint8_t dijkstra_map() @@ -552,7 +543,8 @@ extern uint8_t dijkstra_map() scores_still_changing = 0; for (pos = 0; pos < map_size; pos++) { - if (score_map[pos] <= max_score) + uint16_t score = score_map[pos]; + if (score <= max_score && score > i_scans) { get_neighbor_scores(pos, max_score, neighbors); min_neighbor = max_score; @@ -573,3 +565,209 @@ extern uint8_t dijkstra_map() } return 0; } + + +/* 7DRL/TCE addition: Init AI score map to all-eatable unknown fields. */ +extern uint8_t TCE_init_score_map() +{ + uint32_t map_size = maplength * maplength; + score_map = malloc(map_size * sizeof(uint16_t)); + if (!score_map) + { + return 1; + } + uint32_t i = 0; + for (; i < map_size; i++) + { + score_map[i] = UINT16_MAX - 1; + } + return 0; +} + +/* 7DRL/TCE addition: movement cost map setting. */ +static uint8_t * TCE_move_cost_map = NULL; +extern uint8_t TCE_set_movement_cost_map(char * mem_map) +{ + uint32_t map_size = maplength * maplength; + free(TCE_move_cost_map); + TCE_move_cost_map = malloc(map_size * sizeof(uint8_t)); + uint32_t pos = 0; + for (; pos < map_size; pos++) + { + TCE_move_cost_map[pos] = 0; + } + if (!TCE_move_cost_map) + { + return 1; + } + for (pos = 0; pos < map_size; pos++) + { + switch(mem_map[pos]) { + case '-': + case '+': + case '$': + case '0': + TCE_move_cost_map[pos] = 1; + break; + case '1': + TCE_move_cost_map[pos] = 2; + break; + case '2': + TCE_move_cost_map[pos] = 4; + break; + case '3': + TCE_move_cost_map[pos] = 3; + break; + case '4': + TCE_move_cost_map[pos] = 6; + break; + } + } + return 0; +} + + +/* 7DRL/TCE addition: Like dijkstra_map(), but with movement costs applied. */ +extern uint8_t TCE_dijkstra_map_with_movement_cost() +{ + if (!score_map || !TCE_move_cost_map) + { + return 1; + } + uint16_t max_score = UINT16_MAX - 1; + uint32_t map_size = maplength * maplength; + uint32_t pos; + uint16_t i_scans, neighbors[6], min_neighbor; + uint8_t scores_still_changing = 1; + uint8_t i_dirs; + for (i_scans = 0; scores_still_changing; i_scans++) + { + scores_still_changing = 0; + for (pos = 0; pos < map_size; pos++) + { + uint16_t score = score_map[pos]; + uint8_t mov_cost = TCE_move_cost_map[pos]; + if (score <= max_score && mov_cost > 0 && score > i_scans) + { + get_neighbor_scores(pos, max_score, neighbors); + min_neighbor = max_score; + for (i_dirs = 0; i_dirs < 6; i_dirs++) + { + if (min_neighbor > neighbors[i_dirs]) + { + min_neighbor = neighbors[i_dirs]; + } + } + if (score_map[pos] > min_neighbor + mov_cost) + { + score_map[pos] = min_neighbor + mov_cost; + scores_still_changing = 1; + } + } + } + } + return 0; +} + + +extern uint8_t zero_score_map_where_char_on_memdepthmap(char c, + char * memdepthmap) +{ + if (!score_map) + { + return 1; + } + uint32_t map_size = maplength * maplength; + uint16_t pos; + for (pos = 0; pos < map_size; pos++) + { + if (c == memdepthmap[pos]) + { + score_map[pos] = 0; + } + } + return 0; +} + +extern void age_some_memdepthmap_on_nonfov_cells(char * memdepthmap, + char * fovmap) +{ + uint32_t map_size = maplength * maplength; + uint16_t pos; + for (pos = 0; pos < map_size; pos++) + { + if ('v' != fovmap[pos]) + { + char c = memdepthmap[pos]; + if( '0' <= c && '9' > c && !(rrand() % (uint16_t) pow(2, c - 48))) + { + memdepthmap[pos]++; + } + } + } +} + +extern uint8_t set_cells_passable_on_memmap_to_65534_on_scoremap(char * mem_map, + const char * symbols_passable) +{ + if (!score_map) + { + return 1; + } + uint32_t map_size = maplength * maplength; + uint16_t pos; + for (pos = 0; pos < map_size; pos++) + { + if (NULL != strchr(symbols_passable, mem_map[pos])) + { + score_map[pos] = 65534; + } + } + return 0; +} + + +extern void update_mem_and_memdepthmap_via_fovmap(char * map, char * fovmap, + char * memdepthmap, + char * memmap) +{ + uint32_t map_size = maplength * maplength; + uint16_t pos; + for (pos = 0; pos < map_size; pos++) + { + if ('v' == fovmap[pos]) + { + memdepthmap[pos] = '0'; + memmap[pos] = map[pos]; + } + } +} + +/* USEFUL FOR DEBUGGING +#include +extern void write_score_map() +{ + FILE *f = fopen("score_map", "a"); + + fprintf(f, "\n---------------------------------------------------------\n"); + uint32_t y, x; + for (y = 0; y < maplength; y++) + { + for (x = 0; x < maplength; x++) + { + uint32_t pos = y * maplength + x; + uint16_t val = score_map[pos]; + if (val == UINT16_MAX) + { + fprintf(f, " Z"); + } else if (val == UINT16_MAX - 1) { + fprintf(f, " Y"); + } else { + fprintf(f, "%2X", score_map[pos] % 256); + } + } + fprintf(f, "\n"); + } + fclose(f); +} +*/