16 #include <QLoggingCategory>
72 #define CM_MAX_LOOP 25000
74 #define CPUHOG_CM_MAX_LOOP (CM_MAX_LOOP * 4)
77 #define GATHER_TIME_STATS
82 #define PRINT_TIME_STATS_EVERY_QUERY
84 #define LOG_TIME_STATS LOG_DEBUG
85 #define LOG_CM_STATE LOG_DEBUG
86 #define LOG_LATTICE LOG_DEBUG
87 #define LOG_REACHED_LEAF LOG_DEBUG
88 #define LOG_BETTER_LEAF LOG_DEBUG
89 #define LOG_PRUNE_BRANCH LOG_DEBUG
91 #ifdef GATHER_TIME_STATS
100 struct one_perf *current;
103 static void print_performance(
struct one_perf *counts);
129 #define SPECVEC_TAG tile
130 #define SPECVEC_TYPE struct cm_tile
134 #define SPECVEC_TAG tile_type
135 #define SPECVEC_TYPE struct cm_tile_type *
137 #define tile_type_vector_iterate(vector, var) \
139 struct cm_tile_type *var; \
140 TYPED_VECTOR_ITERATE(struct cm_tile_type *, vector, var##p) \
144 #define tile_type_vector_iterate_end \
147 VECTOR_ITERATE_END; \
167 struct tile_vector
tiles;
199 struct tile_type_vector
lattice;
212 std::array<cached_waste, O_LAST>
waste;
247 static void real_print_tile_type(QtMsgType
level,
const char *file,
248 const char *
function,
int line,
251 #define print_tile_type(loglevel, ptype, prefix) \
252 real_print_tile_type(loglevel, __FILE__, __FUNCTION__, __FC_LINE__, \
255 static void real_print_lattice(QtMsgType
level,
const char *file,
256 const char *
function,
int line,
257 const struct tile_type_vector *lattice);
258 #define print_lattice(loglevel, lattice) \
259 real_print_lattice(loglevel, __FILE__, __FUNCTION__, __FC_LINE__, lattice);
261 static void real_print_partial_solution(QtMsgType
level,
const char *file,
262 const char *
function,
int line,
265 #define print_partial_solution(loglevel, soln, state) \
266 real_print_partial_solution(loglevel, __FILE__, __FUNCTION__, \
267 __FC_LINE__, soln, state);
270 #define print_tile_type(loglevel, ptype, prefix)
271 #define print_lattice(loglevel, lattice)
272 #define print_partial_solution(loglevel, soln, state)
276 const struct city *pcity,
bool *workers_map);
279 const int production[]);
291 #ifdef GATHER_TIME_STATS
292 memset(&performance, 0,
sizeof(performance));
295 performance.greedy.name =
"greedy";
298 performance.opt.name =
"opt";
317 #ifdef GATHER_TIME_STATS
318 print_performance(&performance.greedy);
319 print_performance(&performance.opt);
323 memset(&performance, 0,
sizeof(performance));
333 auto result = std::make_unique<cm_result>();
334 result->city_radius_sq =
338 result->worker_positions.resize(tiles,
false);
357 memset(type, 0,
sizeof(*type));
358 tile_vector_init(&type->
tiles);
371 memcpy(newtype, oldtype,
sizeof(*oldtype));
372 tile_vector_init(&newtype->tiles);
373 tile_type_vector_init(&newtype->better_types);
374 tile_type_vector_init(&newtype->worse_types);
386 tile_vector_free(&type->
tiles);
405 tile_type_vector_free(vec);
469 for (i = 0; i < vec->size; i++) {
488 return tile_vector_size(&type->
tiles);
531 return &ptype->
tiles.p[j];
573 fitness.weighted = 0;
577 fitness.weighted += surplus[stat_index] * parameter->factor[stat_index];
578 if (surplus[stat_index] < parameter->minimal_surplus[stat_index]) {
579 fitness.sufficient =
false;
585 fitness.weighted += parameter->happy_factor;
586 }
else if (parameter->require_happy) {
587 fitness.sufficient =
false;
590 if (disorder && !parameter->allow_disorder) {
591 fitness.sufficient =
false;
608 int idle,
bool negative_ok)
659 int i, citizen_count = 0;
661 #ifdef GATHER_TIME_STATS
662 performance.current->apply_count++;
684 citizen_count += nworkers;
695 for (j = 0; j < nworkers; j++) {
715 bool *disorder,
bool *happy)
731 struct city *pcity = state->pcity;
733 bool disorder,
happy;
757 +
game.
info.happy_cost *
MAX(specialists_amount - max_content, 0)
770 std::unique_ptr<cm_result> &result)
774 if (soln->
idle != 0) {
777 result->found_a_valid =
false;
787 fitness =
compute_fitness(result->surplus, result->disorder, result->happy,
889 if (valuea != valueb) {
891 return valueb - valuea;
906 const struct tile *ptile,
934 type = lattice->p[i];
944 tile_type_vector_append(&other->worse_types, type);
946 tile_type_vector_append(&other->better_types, type);
947 tile_type_vector_append(&type->
worse_types, other);
954 tile_type_vector_append(lattice, type);
977 const struct city *pcity)
988 std::array<int, O_LAST> outputs = {0};
1017 std::vector<bool> marked;
1018 std::vector<bool> will_mark;
1019 marked.resize(lattice->size);
1020 will_mark.resize(lattice->size);
1022 struct tile_type_vector vectors[2];
1023 struct tile_type_vector *current, *next;
1025 tile_type_vector_init(&vectors[0]);
1026 tile_type_vector_init(&vectors[1]);
1027 current = &vectors[0];
1034 tile_type_vector_append(next, ptype);
1041 while (next->size != 0) {
1043 struct tile_type_vector *vtmp = current;
1054 bool can_mark =
true;
1057 if (will_mark[ptype->lattice_index]) {
1062 if (!marked[better->lattice_index]) {
1079 will_mark[ptype->lattice_index] =
true;
1082 tile_type_vector_append(next, worse);
1087 ptype->lattice_depth = sumdepth;
1093 for (i = 0; i < lattice->size; i++) {
1094 marked[i] = marked[i] || will_mark[i];
1095 will_mark[i] =
false;
1099 tile_type_vector_free(&vectors[0]);
1100 tile_type_vector_free(&vectors[1]);
1120 const struct city *pcity)
1123 struct tile_type_vector tofree;
1124 bool forced_loop =
false;
1128 tile_type_vector_init(&tofree);
1133 if (lattice->size > 0) {
1136 for (i = 0, j = 0; i < lattice->size || forced_loop; i++) {
1139 forced_loop =
false;
1142 tile_type_vector_append(&tofree, ptype);
1148 lattice->p[j] = ptype;
1152 for (ci = 0, cj = 0; ci < ptype->
worse_types.size; ci++) {
1174 struct tile_type_vector *lattice)
1186 qsort(lattice->p, lattice->size,
sizeof(*lattice->p),
1190 for (i = 0; i < lattice->size; i++) {
1191 lattice->p[i]->lattice_index = i;
1274 return tile_type_vector_size(&state->
lattice);
1295 newcount = soln->
idle - number;
1298 soln->
idle = newcount;
1392 for (newchoice = oldchoice + 1; newchoice <
num_types(state);
1398 == tile_vector_size(&ptype->
tiles))) {
1433 newchoice =
next_choice(state, oldchoice, negative_ok);
1456 int oldchoice, newchoice;
1469 newchoice =
next_choice(state, oldchoice - 1, negative_ok);
1490 const struct tile_type_vector *lattice)
1492 int last_worker_choice = -1;
1495 if (soln->
idle == 0) {
1500 for (i = 0; i <
num_types(state); i++) {
1502 last_worker_choice = i;
1515 if (ptype->lattice_index < last_worker_choice) {
1525 touse = total - used;
1526 if (touse > soln->
idle) {
1529 add_workers(soln, ptype->lattice_index, touse, state);
1531 if (soln->
idle == 0) {
1548 for (i = 0; i <
num_types(state); i++) {
1579 if (soln->
idle == 1) {
1638 bool beats_best =
false;
1676 int specialists_suppress_unhappy =
1679 +
game.
info.happy_cost * specialists_suppress_unhappy;
1681 if (max_luxury < state->min_luxury) {
1684 specialists_suppress_unhappy, state->
min_luxury);
1690 "--- pruning: best is better in all important ways");
1719 const int SCIENCE = 0, TAX = 1, LUXURY = 2;
1724 rates[TAX] = 100 - rates[SCIENCE] - rates[LUXURY];
1726 rates[SCIENCE] =
game.
info.forced_science;
1727 rates[LUXURY] =
game.
info.forced_luxury;
1728 rates[TAX] =
game.
info.forced_gold;
1734 rates[LUXURY] = 100;
1750 const int SCIENCE = 0, TAX = 1, LUXURY = 2;
1751 const struct city *pcity = state->
pcity;
1754 double estimates[
O_LAST];
1760 estimates[stat_index] = production[stat_index];
1770 estimates[
O_SCIENCE] += rates[SCIENCE] * trade / 100.0;
1771 estimates[
O_LUXURY] += rates[LUXURY] * trade / 100.0;
1772 estimates[
O_GOLD] += rates[TAX] * trade / 100.0;
1777 estimates[stat_index] *= pcity->
bonus[stat_index] / 100.0;
1846 const int SCIENCE = 0, TAX = 1, LUXURY = 2;
1850 state->parameter = *param;
1858 state->pcity = pcity;
1861 tile_type_vector_init(&state->lattice);
1863 numtypes = tile_type_vector_size(&state->lattice);
1873 state->waste[o].level =
1887 tile_type_vector_init(&state->lattice_by_prod[stat_index]);
1888 tile_type_vector_copy(&state->lattice_by_prod[stat_index],
1892 switch (stat_index) {
1908 qsort(state->lattice_by_prod[stat_index].p,
1909 state->lattice_by_prod[stat_index].size,
1910 sizeof(*state->lattice_by_prod[stat_index].p),
1926 state->choice.size = 0;
1943 int max_surplus = -
game.
info.food_cost * city_size;
1959 if (max_surplus <= 0) {
1963 if (food_needed <= 0) {
1969 int num = tile_vector_size(&ptype->tiles);
1971 if (ptype->is_specialist || workers < num) {
1972 max_surplus += workers * ptype->production[
O_FOOD];
1975 max_surplus += num * ptype->production[
O_FOOD];
1982 min_turns = (food_needed + max_surplus - 1) / max_surplus;
1984 return (food_needed + min_turns - 1) / min_turns;
1995 #ifdef GATHER_TIME_STATS
1997 performance.current->query_count++;
2027 #ifdef GATHER_TIME_STATS
2030 #ifdef PRINT_TIME_STATS_EVERY_QUERY
2031 print_performance(performance.current);
2034 performance.current =
nullptr;
2065 std::unique_ptr<cm_result> &result,
2072 #ifdef GATHER_TIME_STATS
2073 performance.current = &performance.opt;
2079 memcpy(&backup, state->
pcity,
sizeof(backup));
2087 result->aborted =
false;
2090 while (!
bb_next(state, negative_ok)) {
2094 if (loop_count > max_count) {
2095 qCWarning(cm_category,
2096 "Did not find a cm solution in %d iterations for %s.",
2098 result->aborted =
true;
2106 memcpy(state->
pcity, &backup,
sizeof(backup));
2116 std::unique_ptr<cm_result> &result,
bool negative_ok)
2177 dest->
factor[stat_index] = 1;
2197 dest->
factor[stat_index] = 1;
2221 if (result->worker_positions[cindex]) {
2272 for (
auto position : result->worker_positions) {
2278 if (workers_map ==
nullptr) {
2282 result->worker_positions[ctindex] =
2283 (
nullptr != pwork && pwork == pcity);
2285 result->worker_positions[ctindex] = workers_map[ctindex];
2293 result->specialists[spec] = pcity->
specialists[spec];
2302 result->found_a_valid =
true;
2308 #ifdef FREECIV_DEBUG
2309 static void snprint_production(
char *buffer,
size_t bufsz,
2320 static void real_print_tile_type(QtMsgType
level,
const char *file,
2321 const char *
function,
int line,
2331 snprint_production(prodstr, sizeof(prodstr), ptype->
production);
2332 qCDebug(cm_category, "%s%s fitness %g depth %d, idx %d; %d tiles", prefix,
2333 prodstr, ptype->estimated_fitness, ptype->lattice_depth,
2340 static
void real_print_lattice(QtMsgType
level, const
char *file,
2341 const
char *function,
int line,
2342 const struct tile_type_vector *lattice)
2344 qCDebug(cm_category,
"lattice has %u terrain types",
2345 (
unsigned) lattice->size);
2348 real_print_tile_type(
level, file,
function, line, ptype,
" ");
2356 static void real_print_partial_solution(QtMsgType
level,
const char *file,
2357 const char *
function,
int line,
2365 if (soln->
idle != 0) {
2366 qCDebug(cm_category,
"** partial solution has %d idle workers",
2369 qCDebug(cm_category,
"** completed solution:");
2372 snprint_production(buf,
sizeof(buf), soln->
production);
2373 qCDebug(cm_category,
"production: %s", buf);
2375 qCDebug(cm_category,
"tiles used:");
2376 for (i = 0; i <
num_types(state); i++) {
2378 fc_snprintf(buf,
sizeof(buf),
" %d tiles of type ",
2380 real_print_tile_type(
level, file,
function, line,
2385 for (i = 0; i <
num_types(state); i++) {
2391 qCDebug(cm_category,
"tiles available:");
2392 for (i = last_type; i <
num_types(state); i++) {
2397 real_print_tile_type(
level, file,
function, line,
2405 #ifdef GATHER_TIME_STATS
2409 static void print_performance(
struct one_perf *counts)
2413 int queries, applies;
2418 queries = counts->query_count;
2421 applies = counts->apply_count;
2423 qCDebug(timers_category,
2424 "CM-%s: overall=%fs queries=%d %fms / query, %d applies",
2425 counts->name, s, queries, ms / q, applies);
2446 if (
nullptr != pwork && pwork == pcity) {
2474 int *city_map_data =
new int[
city_map_tiles(result->city_radius_sq)]();
2476 log_test(
"cm_print_result(result=%p)", (
void *) result.get());
2477 log_test(
" found_a_valid=%d disorder=%d happy=%d", result->found_a_valid,
2478 result->disorder, result->happy);
2483 city_map_data[cindex] = 2;
2484 }
else if (result->worker_positions[cindex]) {
2485 city_map_data[cindex] = 1;
2487 city_map_data[cindex] = 0;
2491 log_test(
"workers map (2: free worked; 1: worker; 0: not used):");
2493 delete[] city_map_data;
bool base_city_celebrating(const struct city *pcity)
Return TRUE if the city was celebrating at the start of the turn, and it still has sufficient size to...
struct output_type * get_output_type(Output_type_id output)
Return the output type for this index.
int city_granary_size(int city_size)
Generalized formula used to calculate granary size.
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
void set_city_production(struct city *pcity, const std::vector< city * > &gov_centers, const std::array< cached_waste, O_LAST > *pcwaste)
Set food, trade and shields production in a city.
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Returns TRUE iff the given city can use this kind of specialist.
struct tile * city_map_to_tile(const struct tile *city_center, int city_radius_sq, int city_map_x, int city_map_y)
Finds the map position for a given city map coordinate of a certain city.
bool city_tile_index_to_xy(int *city_map_x, int *city_map_y, int city_tile_index, int city_radius_sq)
Returns the coordinates for the given city tile index taking into account the squared city radius.
citizens player_content_citizens(const struct player *pplayer)
Give base number of content citizens in any city owned by pplayer.
const char * city_name_get(const struct city *pcity)
Return the name of the city.
bool city_unhappy(const struct city *pcity)
Return TRUE iff the city is unhappy.
void citylog_map_data(QtMsgType level, int radius_sq, int *map_data)
Display 'map_data' on a city map with the given radius 'radius_sq' for the requested log level.
bool city_happy(const struct city *pcity)
Return TRUE iff the city is happy.
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
citizens city_specialists(const struct city *pcity)
Give the number of specialists in a city.
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
Calculate the output for the tile.
void city_refresh_from_main_map(struct city *pcity, bool *workers_map, const std::vector< city * > &gov_centers, const std::array< cached_waste, O_LAST > *pcwaste, const std::vector< std::array< int, O_LAST >> *pcsoutputs)
Refreshes the internal cached data in the city structure.
int city_map_tiles(int city_radius_sq)
Return the number of tiles for the given city radius.
bool is_city_center(const struct city *pcity, const struct tile *ptile)
Return TRUE if the city is centered at the given tile.
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Returns TRUE when a tile is available to be worked, or the city itself is currently working the tile ...
const char * get_output_name(Output_type_id output)
Return a translated name for the output type.
citizens city_size_get(const struct city *pcity)
Get the city size.
#define CITY_MAP_MAX_RADIUS_SQ
#define city_tile_iterate_index_end
#define output_type_iterate(output)
#define city_map_iterate_end
#define is_city_center_index(city_tile_index)
#define city_map_iterate(_radius_sq, _index, _x, _y)
#define CITY_MAP_CENTER_TILE_INDEX
#define city_tile_iterate_index(_radius_sq, _city_tile, _tile, _index)
#define city_map_tiles_from_city(_pcity)
#define city_map_iterate_without_index(_radius_sq, _x, _y)
#define output_type_iterate_end
static void sort_lattice_by_fitness(const struct cm_state *state, struct tile_type_vector *lattice)
Determine the estimated_fitness fields, and sort by that.
static double estimate_fitness(const struct cm_state *state, const int production[])
Estimate the fitness of a tile.
void cm_init()
Initialize the CM data at the start of each game.
static void get_tax_rates(const struct player *pplayer, int rates[])
Get the national budget, see city.c.
static void init_tile_lattice(struct city *pcity, struct cm_state *state)
Create the lattice.
static int specialists_in_solution(const struct cm_state *state, const struct partial_solution *soln)
Return number of specialists used in partial solution.
static void begin_search(struct cm_state *state, const struct cm_parameter *parameter, bool negative_ok)
Set the parameter for the state.
static int min_food_surplus_for_fastest_growth(struct cm_state *state)
Find the minimum food surplus needed to grow in the fewest number of turns.
static int next_choice(struct cm_state *state, int oldchoice, bool negative_ok)
Return the next choice to make after oldchoice.
static void tile_type_destroy(struct cm_tile_type *type)
Free all the storage in the tile type (but don't free the type itself).
static struct cm_state * cm_state_init(struct city *pcity, const cm_parameter *param, bool negative_ok)
Initialize the state for the branch-and-bound algorithm.
static struct cm_fitness compute_fitness(const int surplus[], bool disorder, bool happy, const struct cm_parameter *parameter)
Compute the fitness of the given surplus (and disorder/happy status) according to the weights and min...
static void init_partial_solution(struct partial_solution *into, int ntypes, int idle, bool negative_ok)
Allocate and initialize an empty solution.
static void complete_solution(struct partial_solution *soln, const struct cm_state *state, const struct tile_type_vector *lattice)
Complete the solution by choosing tiles in order off the given tile lattice.
static bool take_child_choice(struct cm_state *state, bool negative_ok)
Go down from the current branch, if we can.
static bool tile_type_better(const struct cm_tile_type *a, const struct cm_tile_type *b)
Return TRUE if tile a is better or equal to tile b in all categories.
static const struct cm_tile_type * tile_type_get(const struct cm_state *state, int type)
Retrieve a tile type by index.
static Output_type_id compare_key
static struct cm_fitness evaluate_solution(struct cm_state *state, const struct partial_solution *soln)
Compute the fitness of the solution.
static int tile_type_vector_find_equivalent(const struct tile_type_vector *vec, const struct cm_tile_type *ptype)
If there is a tile type in the vector that is equivalent to the given type, return its index.
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Copy the parameter from the source to the destination field.
static void cm_find_best_solution(struct cm_state *state, const struct cm_parameter *const parameter, std::unique_ptr< cm_result > &result, bool negative_ok)
Run B&B until we find the best solution.
static bool choice_stack_empty(struct cm_state *state)
Handling the choice stack for the bb algorithm.
void cm_free()
Called at the end of a game to free any CM data.
static void tile_type_vector_free_all(struct tile_type_vector *vec)
Destroy and free all types in the vector, and the vector itself.
static bool prereqs_filled(const struct partial_solution *soln, int type, const struct cm_state *state)
True if all tiles better than this type have been used.
static void clean_lattice(struct tile_type_vector *lattice, const struct city *pcity)
Remove unreachable lattice nodes to speed up processing later.
void cm_init_parameter(struct cm_parameter *dest)
Initialize the parameter to sane default values.
static int tile_type_num_prereqs(const struct cm_tile_type *ptype)
Return the number of tile types that are better than this type.
void cm_query_result(struct city *pcity, const struct cm_parameter *param, std::unique_ptr< cm_result > &result, bool negative_ok)
Wrapper that actually runs the branch & bound, and returns the best solution.
static void copy_partial_solution(struct partial_solution *dst, const struct partial_solution *src, const struct cm_state *state)
Copy the source solution into the destination one (the destination solution must already be allocated...
static void cm_state_free(struct cm_state *state)
Release all the memory allocated by the state.
static void init_specialist_lattice_nodes(struct cm_state *state, const struct city *pcity)
Create lattice nodes for each type of specialist.
static int compare_tile_type_by_fitness(const void *va, const void *vb)
Sort by fitness.
static void destroy_partial_solution(struct partial_solution *into)
Free all storage associated with the solution.
static void convert_solution_to_result(struct cm_state *state, const struct partial_solution *soln, std::unique_ptr< cm_result > &result)
Convert the solution into a cm_result.
#define print_partial_solution(loglevel, soln, state)
int cm_result_citizens(const std::unique_ptr< cm_result > &result)
Count the total number of citizens in the result.
#define print_lattice(loglevel, lattice)
static bool tile_type_equal(const struct cm_tile_type *a, const struct cm_tile_type *b)
Return TRUE iff all categories of the two types are equal.
static void tile_type_init(struct cm_tile_type *type)
Set all production to zero and initialize the vectors for this tile type.
#define tile_type_vector_iterate(vector, var)
bool operator==(const struct cm_parameter &p1, const struct cm_parameter &p2)
static void add_worker(struct partial_solution *soln, int itype, const struct cm_state *state)
Add just one worker to the solution.
static bool choice_is_promising(struct cm_state *state, int newchoice, bool negative_ok)
A choice is unpromising if isn't better than the best in at least one way.
static struct cm_fitness worst_fitness()
Return a fitness struct that is the worst possible result we can represent.
static double compare_key_trade_bonus
static bool take_sibling_choice(struct cm_state *state, bool negative_ok)
Pick a sibling choice to the last choice.
void cm_result_from_main_map(std::unique_ptr< cm_result > &result, const struct city *pcity)
Copy the city's current setup into the cm result structure.
static void apply_solution(struct cm_state *state, const struct partial_solution *soln)
Evaluating a completed solution.
static void init_min_production(struct cm_state *state)
Initialize minimal production needed to be sufficient.
void cm_init_citymap()
Initialize the CM citymap data.
static void end_search(struct cm_state *state)
Clean up after a search.
static void compute_tile_production(const struct city *pcity, const struct tile *ptile, bool is_celebrating, struct cm_tile_type *out)
Compute the tile-type lattice.
static int compare_tile_type_by_stat(const void *va, const void *vb)
Compare by the production of type compare_key.
static int tile_type_num_tiles(const struct cm_tile_type *type)
Return the number of tiles of this type that can be worked.
static bool fitness_better(struct cm_fitness a, struct cm_fitness b)
Return TRUE iff fitness A is strictly better than fitness B.
static bool bb_next(struct cm_state *state, bool negative_ok)
The high-level algorithm is:
static void top_sort_lattice(struct tile_type_vector *lattice)
Topologically sort the lattice.
static void get_city_surplus(const struct city *pcity, int surplus[], bool *disorder, bool *happy)
Convert the city's surplus numbers into an array.
static const struct cm_tile * tile_get(const struct cm_tile_type *ptype, int j)
Retrieve a tile of a particular type by index.
int cm_result_workers(const std::unique_ptr< cm_result > &result)
Count the total number of workers in the result.
static void compute_max_stats_heuristic(const struct cm_state *state, const struct partial_solution *soln, int production[], int check_choice, bool negative_ok)
The heuristic: A partial solution cannot produce more food than the amount of food it currently gener...
std::unique_ptr< cm_result > cm_result_new(struct city *pcity)
Create a new cm_result.
static int last_choice(struct cm_state *state)
Return the last choice in the stack.
#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)
Compare functions to allow sorting lattice vectors.
static void remove_worker(struct partial_solution *soln, int itype, const struct cm_state *state)
Remove just one worker from the solution.
static void cm_result_copy(std::unique_ptr< cm_result > &result, const struct city *pcity, bool *workers_map)
Copy the city's current setup into the cm result structure.
#define CPUHOG_CM_MAX_LOOP
static void add_workers(struct partial_solution *soln, int itype, int number, const struct cm_state *state)
Update the solution to assign 'number' more workers on to tiles of the given type.
static void tile_type_lattice_add(struct tile_type_vector *lattice, const struct cm_tile_type *newtype, int tindex)
Add the tile [x,y], with production indicated by type, to the tile-type lattice.
void cm_init_emergency_parameter(struct cm_parameter *dest)
Initialize the parameter to sane default values that will always produce a result.
static void pop_choice(struct cm_state *state)
Remove a worker from the current solution, and pop once off the choice stack.
static int num_types(const struct cm_state *state)
Return the number of different tile types.
#define tile_type_vector_iterate_end
void cm_print_result(const std::unique_ptr< cm_result > &result)
Print debugging information about a full CM result.
void cm_print_city(const struct city *pcity)
Debugging routines.
static struct cm_tile_type * tile_type_dup(const struct cm_tile_type *oldtype)
Duplicate a tile type, except for the vectors - the vectors of the new tile type will be empty.
int cm_result_specialists(const std::unique_ptr< cm_result > &result)
Count the total number of specialists in the result.
int get_city_output_bonus(const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Returns the player effect bonus of an output.
enum output_type_id Output_type_id
struct government * government_of_player(const struct player *pplayer)
Return the government of a player.
#define fc_assert_ret(condition)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_base(level, message,...)
std::vector< city * > player_gov_centers(const struct player *pplayer)
Locate the player's government centers.
static bool player_is_cpuhog(const struct player *pplayer)
struct setting_list * level[OLEVELS_NUM]
const char * specialists_string(const citizens *specialist_list)
Return a string showing the number of specialists in the array.
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
Return the output for the specialist type with this output type.
#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]
struct partial_solution best
struct cm_parameter parameter
std::array< cached_waste, O_LAST > waste
std::vector< std::array< int, O_LAST > > specialist_outputs
int min_production[O_LAST]
struct tile_type_vector lattice
std::array< int, O_LAST > city_center_output
struct partial_solution current
struct tile_type_vector lattice_by_prod[O_LAST]
std::vector< city * > gov_centers
struct cm_fitness best_value
struct cm_state::@13 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,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
#define tile_worked(_tile)
Q_LOGGING_CATEGORY(tileset_category, "freeciv.tileset")
Functions for handling the tilespec files which describe the files and contents of tilesets.
void timer_destroy(civtimer *t)
Deletes timer.
double timer_read_seconds(civtimer *t)
Read value from timer.
civtimer * timer_new(enum timer_timetype type, enum timer_use use)
Allocate a new timer with specified "type" and "use".
void timer_start(civtimer *t)
Start timing, adding to previous accumulated time if timer has not been cleared.
void timer_stop(civtimer *t)
Stop timing, and accumulate time so far.