From a4850fb8ff131de40b58cf8c3ad87f271b72b32f Mon Sep 17 00:00:00 2001 From: Louis Moureaux Date: Sun, 24 Dec 2023 04:26:30 +0100 Subject: [PATCH] Implement CM allow_specialists Now that we have a UI to set allow_specialists, implement it. Do it by not including specialists in the list of possible citizen assignments. See #2058. --- common/aicore/cm.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/common/aicore/cm.cpp b/common/aicore/cm.cpp index 0919e2bafd..3a14a13977 100644 --- a/common/aicore/cm.cpp +++ b/common/aicore/cm.cpp @@ -1187,8 +1187,7 @@ static void sort_lattice_by_fitness(const struct cm_state *state, /** Create the lattice. */ -static void init_tile_lattice(struct city *pcity, - struct tile_type_vector *lattice) +static void init_tile_lattice(struct city *pcity, struct cm_state *state) { struct cm_tile_type type; struct tile *pcenter = city_tile(pcity); @@ -1203,21 +1202,23 @@ static void init_tile_lattice(struct city *pcity, continue; } else if (city_can_work_tile(pcity, ptile)) { compute_tile_production(pcity, ptile, &type); // clobbers type - tile_type_lattice_add(lattice, &type, + tile_type_lattice_add(&state->lattice, &type, ctindex); // copy type if needed } } city_tile_iterate_index_end; // Add all the specialists into the lattice. - init_specialist_lattice_nodes(lattice, pcity); + if (state->parameter.allow_specialists) { + init_specialist_lattice_nodes(&state->lattice, pcity); + } // Set the lattice_depth fields, and clean up unreachable nodes. - top_sort_lattice(lattice); - clean_lattice(lattice, pcity); + top_sort_lattice(&state->lattice); + clean_lattice(&state->lattice, pcity); // All done now. - print_lattice(LOG_LATTICE, lattice); + print_lattice(LOG_LATTICE, &state->lattice); } /** @@ -1830,12 +1831,16 @@ static bool bb_next(struct cm_state *state, bool negative_ok) /** Initialize the state for the branch-and-bound algorithm. */ -static struct cm_state *cm_state_init(struct city *pcity, bool negative_ok) +static struct cm_state *cm_state_init(struct city *pcity, + const cm_parameter *param, + bool negative_ok) { const int SCIENCE = 0, TAX = 1, LUXURY = 2; const struct player *pplayer = city_owner(pcity); int numtypes; auto *state = new cm_state; + state->parameter = *param; + int rates[3]; log_base(LOG_CM_STATE, "creating cm_state for %s (size %d)", @@ -1846,7 +1851,7 @@ static struct cm_state *cm_state_init(struct city *pcity, bool negative_ok) // create the lattice tile_type_vector_init(&state->lattice); - init_tile_lattice(pcity, &state->lattice); + init_tile_lattice(pcity, state); numtypes = tile_type_vector_size(&state->lattice); get_tax_rates(pplayer, rates); @@ -2085,7 +2090,7 @@ static void cm_find_best_solution(struct cm_state *state, void cm_query_result(struct city *pcity, const struct cm_parameter *param, std::unique_ptr &result, bool negative_ok) { - struct cm_state *state = cm_state_init(pcity, negative_ok); + struct cm_state *state = cm_state_init(pcity, param, negative_ok); /* Refresh the city. Otherwise the CM can give wrong results or just be * slower than necessary. Note that cities are often passed in in an