80#define CM_MAX_LOOP 27500
82#define CPUHOG_CM_MAX_LOOP (CM_MAX_LOOP * 4)
85#define GATHER_TIME_STATS
93#define PRINT_TIME_STATS_EVERY_QUERY
95#define LOG_TIME_STATS LOG_DEBUG
96#define LOG_CM_STATE LOG_DEBUG
97#define LOG_LATTICE LOG_DEBUG
98#define LOG_REACHED_LEAF LOG_DEBUG
99#define LOG_BETTER_LEAF LOG_DEBUG
100#define LOG_PRUNE_BRANCH LOG_DEBUG
102#ifdef GATHER_TIME_STATS
141#define SPECVEC_TAG tile
142#define SPECVEC_TYPE struct cm_tile
146#define SPECVEC_TAG tile_type
147#define SPECVEC_TYPE struct cm_tile_type *
149#define tile_type_vector_iterate(vector, var) { \
150 struct cm_tile_type *var; \
151 TYPED_VECTOR_ITERATE(struct cm_tile_type*, vector, var##p) { \
154#define tile_type_vector_iterate_end }} VECTOR_ITERATE_END; }
248#define print_tile_type(loglevel, ptype, prefix) \
249 if (log_do_output_for_level(loglevel)) { \
250 real_print_tile_type(loglevel, __FILE__, __FUNCTION__, __FC_LINE__, \
257#define print_lattice(loglevel, lattice) \
258 if (log_do_output_for_level(loglevel)) { \
259 real_print_lattice(loglevel, __FILE__, __FUNCTION__, __FC_LINE__, \
268#define print_partial_solution(loglevel, soln, state) \
269 if (log_do_output_for_level(loglevel)) { \
270 real_print_partial_solution(loglevel, __FILE__, __FUNCTION__, \
271 __FC_LINE__, soln, state); \
275#define print_tile_type(loglevel, ptype, prefix)
276#define print_lattice(loglevel, lattice)
277#define print_partial_solution(loglevel, soln, state)
281 const struct city *pcity,
bool *workers_map);
284 const int production[]);
296#ifdef GATHER_TIME_STATS
332#ifdef GATHER_TIME_STATS
370 if (result !=
NULL) {
515 for (
i = 0;
i < vec->size;
i++) {
531 if (
type->is_specialist) {
546 return ptype->better_types.size;
576 return &
ptype->tiles.p[j];
629 fitness.weighted += parameter->happy_factor;
630 }
else if (parameter->require_happy) {
634 if (disorder && !parameter->allow_disorder) {
706#ifndef FREECIV_NDEBUG
710#ifdef GATHER_TIME_STATS
739#ifndef FREECIV_NDEBUG
745 if (
type->is_specialist) {
773 bool *disorder,
bool *happy)
789 struct city *pcity = state->pcity;
791 bool disorder,
happy;
831 if (
soln->idle != 0) {
961 const struct tile *ptile,
988 type = lattice->p[
i];
1000 }
else if (
cmp < 0) {
1007 type->lattice_index = lattice->size;
1012 if (!
type->is_specialist) {
1031 const struct city *pcity)
1061 if (lattice->size > 0) {
1063 bool marked[lattice->size];
1085 while (next->size != 0) {
1104 if (!
marked[better->lattice_index]) {
1131 for (
i = 0;
i < lattice->size;
i++) {
1159 const struct city *pcity)
1172 if (lattice->size > 0) {
1188 lattice->p[j] =
ptype;
1189 lattice->p[j]->lattice_index = j;
1224 qsort(lattice->p, lattice->size,
sizeof(*lattice->p),
1228 for (
i = 0;
i < lattice->size;
i++) {
1229 lattice->p[
i]->lattice_index =
i;
1313 int itype,
int number,
1341 soln->prereqs_filled[
other->lattice_index]--;
1347 soln->prereqs_filled[
other->lattice_index]++;
1517 if (
soln->idle == 0) {
1523 if (
soln->worker_counts[
i] != 0) {
1532 int used =
soln->worker_counts[
ptype->lattice_index];
1546 touse = total - used;
1552 if (
soln->idle == 0) {
1570 count +=
soln->worker_counts[
i];
1599 if (
soln->idle == 1) {
1772 const struct city *pcity = state->
pcity;
1965 if (
ptype->is_specialist || workers < num) {
1988#ifdef GATHER_TIME_STATS
2019#ifdef GATHER_TIME_STATS
2022#ifdef PRINT_TIME_STATS_EVERY_QUERY
2058#ifdef GATHER_TIME_STATS
2081#ifdef FREECIV_TESTMATIC
2093 "Did not find a cm solution in %d iterations for %s.",
2097#ifndef CM_LOOP_NO_LIMIT
2104#ifdef CM_LOOP_NO_LIMIT
2145 if (
p1->minimal_surplus[
i] !=
p2->minimal_surplus[
i]) {
2148 if (
p1->factor[
i] !=
p2->factor[
i]) {
2152 if (
p1->require_happy !=
p2->require_happy) {
2155 if (
p1->allow_disorder !=
p2->allow_disorder) {
2158 if (
p1->allow_specialists !=
p2->allow_specialists) {
2161 if (
p1->happy_factor !=
p2->happy_factor) {
2164 if (
p1->max_growth !=
p2->max_growth) {
2262 const struct city *pcity)
2273 const struct city *pcity,
bool *workers_map)
2284 if (workers_map ==
NULL) {
2332 "%s%s fitness %g depth %d, idx %d; %d tiles", prefix,
2345 "lattice has %u terrain types", (
unsigned) lattice->size);
2364 if (
soln->idle != 0) {
2366 "** partial solution has %d idle workers",
soln->idle);
2376 if (
soln->worker_counts[
i] != 0) {
2378 soln->worker_counts[
i]);
2385 if (
soln->worker_counts[
i] != 0) {
2404#ifdef GATHER_TIME_STATS
2423 "CM-%s: overall=%fs queries=%d %fms / query, %d applies",
2437 log_test(
" size=%d, specialists=%s",
2474 log_test(
"cm_print_result(result=%p)", (
void *) result);
2475 log_test(
" found_a_valid=%d disorder=%d happy=%d",
2487 log_test(
"workers map (2: free worked; 1: worker; 0: not used):");
bool base_city_celebrating(const struct city *pcity)
bool is_free_worked(const struct city *pcity, const struct tile *ptile)
int city_granary_size(int city_size)
struct tile * city_map_to_tile(const struct civ_map *nmap, const struct tile *city_center, int city_radius_sq, int city_map_x, int city_map_y)
const char * city_name_get(const struct city *pcity)
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
bool city_tile_index_to_xy(int *city_map_x, int *city_map_y, int city_tile_index, int city_radius_sq)
citizens player_content_citizens(const struct player *pplayer)
void citylog_map_data(enum log_level level, int radius_sq, int *map_data)
bool city_unhappy(const struct city *pcity)
void set_city_production(struct city *pcity)
const char * get_output_name(Output_type_id output)
void city_refresh_from_main_map(const struct civ_map *nmap, struct city *pcity, bool *workers_map)
bool city_happy(const struct city *pcity)
int city_map_radius_sq_get(const struct city *pcity)
citizens city_specialists(const struct city *pcity)
static int cmp(int v1, int v2)
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
int city_map_tiles(int city_radius_sq)
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
#define city_tile(_pcity_)
#define city_tile_iterate_index(_nmap, _radius_sq, _city_tile, _tile, _index)
#define CITY_MAP_MAX_RADIUS_SQ
static citizens city_size_get(const struct city *pcity)
#define city_tile_iterate_index_end
#define output_type_iterate(output)
#define city_owner(_pcity_)
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
#define city_map_iterate_end
#define city_map_iterate(_radius_sq, _index, _x, _y)
#define city_tile_iterate_end
#define is_free_worked_index(city_tile_index)
#define city_map_tiles_from_city(_pcity)
#define output_type_iterate_end
void cm_init_citymap(void)
static void convert_solution_to_result(struct cm_state *state, const struct partial_solution *soln, struct cm_result *result)
static void sort_lattice_by_fitness(const struct cm_state *state, struct tile_type_vector *lattice)
static double estimate_fitness(const struct cm_state *state, const int production[])
static void get_tax_rates(const struct player *pplayer, int rates[])
static int specialists_in_solution(const struct cm_state *state, const struct partial_solution *soln)
static void begin_search(struct cm_state *state, const struct cm_parameter *parameter, bool negative_ok)
static int min_food_surplus_for_fastest_growth(struct cm_state *state)
static int next_choice(struct cm_state *state, int oldchoice, bool negative_ok)
static void tile_type_destroy(struct cm_tile_type *type)
static struct cm_fitness compute_fitness(const int surplus[], bool disorder, bool happy, const struct cm_parameter *parameter)
static void init_partial_solution(struct partial_solution *into, int ntypes, int idle, bool negative_ok)
static void complete_solution(struct partial_solution *soln, const struct cm_state *state, const struct tile_type_vector *lattice)
static const struct cm_tile * tile_get(const struct cm_tile_type *ptype, int j)
static struct cm_fitness worst_fitness(void)
static bool take_child_choice(struct cm_state *state, bool negative_ok)
static void compute_tile_production(const struct city *pcity, const struct tile *ptile, struct cm_tile_type *out)
void cm_clear_cache(struct city *pcity)
static const struct cm_tile_type * tile_type_get(const struct cm_state *state, int type)
static Output_type_id compare_key
static struct cm_fitness evaluate_solution(struct cm_state *state, const struct partial_solution *soln)
static int tile_type_vector_find_equivalent(const struct tile_type_vector *vec, const struct cm_tile_type *ptype)
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
static bool choice_stack_empty(struct cm_state *state)
static void tile_type_vector_free_all(struct tile_type_vector *vec)
static struct cm_state * cm_state_init(struct city *pcity, bool negative_ok)
static struct cm_tile_type * tile_type_dup(const struct cm_tile_type *oldtype)
static bool prereqs_filled(const struct partial_solution *soln, int type, const struct cm_state *state)
static void clean_lattice(struct tile_type_vector *lattice, const struct city *pcity)
void cm_init_parameter(struct cm_parameter *dest)
static int tile_type_num_prereqs(const struct cm_tile_type *ptype)
static void copy_partial_solution(struct partial_solution *dst, const struct partial_solution *src, const struct cm_state *state)
static void cm_state_free(struct cm_state *state)
static int compare_tile_type_by_fitness(const void *va, const void *vb)
struct cm_result * cm_result_new(struct city *pcity)
static void destroy_partial_solution(struct partial_solution *into)
int cm_result_specialists(const struct cm_result *result)
#define print_partial_solution(loglevel, soln, state)
void cm_result_from_main_map(struct cm_result *result, const struct city *pcity)
#define print_lattice(loglevel, lattice)
static bool tile_type_equal(const struct cm_tile_type *a, const struct cm_tile_type *b)
static void tile_type_init(struct cm_tile_type *type)
static void cm_result_copy(struct cm_result *result, const struct city *pcity, bool *workers_map)
#define tile_type_vector_iterate(vector, var)
static void add_worker(struct partial_solution *soln, int itype, const struct cm_state *state)
static bool choice_is_promising(struct cm_state *state, int newchoice, bool negative_ok)
bool cm_are_parameter_equal(const struct cm_parameter *const p1, const struct cm_parameter *const p2)
static double compare_key_trade_bonus
static void init_tile_lattice(struct city *pcity, struct tile_type_vector *lattice)
static bool take_sibling_choice(struct cm_state *state, bool negative_ok)
static void cm_find_best_solution(struct cm_state *state, const struct cm_parameter *const parameter, struct cm_result *result, bool negative_ok)
static void apply_solution(struct cm_state *state, const struct partial_solution *soln)
static void init_min_production(struct cm_state *state)
void cm_result_destroy(struct cm_result *result)
void cm_print_result(const struct cm_result *result)
static void end_search(struct cm_state *state)
static int compare_tile_type_by_stat(const void *va, const void *vb)
static int tile_type_num_tiles(const struct cm_tile_type *type)
static bool fitness_better(struct cm_fitness a, struct cm_fitness b)
void cm_query_result(struct city *pcity, const struct cm_parameter *param, struct cm_result *result, bool negative_ok)
static bool bb_next(struct cm_state *state, bool negative_ok)
static void top_sort_lattice(struct tile_type_vector *lattice)
static void get_city_surplus(const struct city *pcity, int surplus[], bool *disorder, bool *happy)
static void compute_max_stats_heuristic(const struct cm_state *state, const struct partial_solution *soln, int production[], int check_choice, bool negative_ok)
static int last_choice(struct cm_state *state)
#define print_tile_type(loglevel, ptype, prefix)
static int compare_tile_type_by_lattice_order(const struct cm_tile_type *a, const struct cm_tile_type *b)
static void remove_worker(struct partial_solution *soln, int itype, const struct cm_state *state)
#define CPUHOG_CM_MAX_LOOP
static int tile_type_better(const struct cm_tile_type *a, const struct cm_tile_type *b)
static void init_specialist_lattice_nodes(struct tile_type_vector *lattice, const struct city *pcity)
static void add_workers(struct partial_solution *soln, int itype, int number, const struct cm_state *state)
int cm_result_citizens(const struct cm_result *result)
static void tile_type_lattice_add(struct tile_type_vector *lattice, const struct cm_tile_type *newtype, int tindex)
void cm_init_emergency_parameter(struct cm_parameter *dest)
static void pop_choice(struct cm_state *state)
static int num_types(const struct cm_state *state)
#define tile_type_vector_iterate_end
void cm_print_city(const struct city *pcity)
int cm_result_workers(const struct cm_result *result)
struct timer * wall_timer
static void base(QVariant data1, QVariant data2)
enum output_type_id Output_type_id
struct government * government_of_player(const struct player *pplayer)
void do_log(const char *file, const char *function, int line, bool print_from_where, enum log_level level, const char *message,...)
#define fc_assert_ret(condition)
#define log_warn(message,...)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_base(level, message,...)
#define fc_calloc(n, esz)
static bool player_is_cpuhog(const struct player *pplayer)
struct setting_list * level[OLEVELS_NUM]
const char * specialists_string(const citizens *specialist_list)
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
#define specialist_type_iterate_end
#define specialist_type_iterate(sp)
struct universal production
citizens specialists[SP_MAX]
struct packet_game_info info
struct government * government_during_revolution
int minimal_surplus[O_LAST]
citizens specialists[SP_MAX]
struct partial_solution best
struct cm_parameter parameter
int min_production[O_LAST]
struct tile_type_vector lattice
struct partial_solution current
struct tile_type_vector lattice_by_prod[O_LAST]
struct cm_fitness best_value
struct cm_state::@15 choice
struct tile_type_vector better_types
struct tile_type_vector worse_types
const struct cm_tile_type * type
struct player_economic economic
int fc_snprintf(char *str, size_t n, const char *format,...)
#define tile_worked(_tile)
void timer_destroy(struct timer *t)
void timer_start(struct timer *t)
void timer_stop(struct timer *t)
struct timer * timer_new(enum timer_timetype type, enum timer_use use, const char *name)
double timer_read_seconds(struct timer *t)