Freeciv-3.4
Loading...
Searching...
No Matches
cm.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdlib.h>
19#include <string.h>
20
21/* utility */
22#include "fcintl.h"
23#include "log.h"
24#include "mem.h"
25#include "shared.h"
26#include "support.h"
27#include "timing.h"
28
29/* common */
30#include "city.h"
31#include "game.h"
32#include "government.h"
33#include "map.h"
34#include "specialist.h"
35
36#include "cm.h"
37
38/*
39 * Terms used
40 * ==========
41 *
42 * Stats: food, shields, trade, luxury, science, and gold.
43 * Production: amount of stats you get directly from farming tiles or
44 * having specialists.
45 * Surplus: amount of stats you get, taking buildings, taxes, disorder, and
46 * any other effects into account.
47 *
48 * Happy State: disorder (unhappy), content (!unhappy && !happy) and
49 * happy (happy)
50 *
51 * Tile type: usually, many tiles produce the same f/s/t. So we bin the
52 * tiles into tile types. Specialists are also a 'tile type.'
53 *
54 * Unlike the original CM code, which used a dynamic programming approach,
55 * this code uses a branch-and-bound approach. The DP approach allowed
56 * caching, but it was hard to guarantee the correctness of the cache, so
57 * it was usually tossed and recomputed.
58 *
59 * The B&B approach also allows a very simple greedy search, whereas the DP
60 * approach required a lot of pre-computing. And, it appears to be very
61 * slightly faster. It evaluates about half as many solutions, but each
62 * candidate solution is more expensive due to the lack of caching.
63 *
64 * We use highly specific knowledge about how the city computes its stats
65 * in two places:
66 * - setting the min_production array. Ideally the city should tell us.
67 * - computing the weighting for tiles. Ditto.
68 */
69
70
71/*****************************************************************************
72 Defines, structs, globals, forward declarations
73*****************************************************************************/
74
75/* If this is uncommented, research loop runs without limit on iterations. */
76/* #define CM_LOOP_NO_LIMIT */
77
78/* Maximal iterations before the search loop is stopped, or until warning is
79 * printed if CM_LOOP_NO_LIMIT is defined. */
80#define CM_MAX_LOOP 27500
81
82#define CPUHOG_CM_MAX_LOOP (CM_MAX_LOOP * 4)
83
84#ifdef DEBUG_TIMERS
85#define GATHER_TIME_STATS
86#endif
87#ifdef FREECIV_DEBUG
88#define CM_DEBUG
89#endif
90
91/* Whether to print every query, or just at cm_free ; matters only
92 if GATHER_TIME_STATS is on */
93#define PRINT_TIME_STATS_EVERY_QUERY
94
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
101
102#ifdef GATHER_TIME_STATS
103static struct {
104 struct one_perf {
105 struct timer *wall_timer;
106 int query_count;
107 int apply_count;
108 const char *name;
109 } greedy, opt;
110
111 struct one_perf *current;
113
114static void print_performance(struct one_perf *counts);
115#endif /* GATHER_TIME_STATS */
116
117/* Fitness of a solution. */
119 int weighted; /* weighted sum */
120 bool sufficient; /* false => doesn't meet constraints */
121};
122
123
124/*
125 * We have a cyclic structure here, so we need to forward-declare the
126 * structs
127 */
128struct cm_tile_type;
129struct cm_tile;
130
131/*
132 * A tile. Has a pointer to the type, and the x/y coords.
133 * Used mostly just for converting to cm_result.
134 */
135struct cm_tile {
136 const struct cm_tile_type *type;
137 int index; /* city map index; only valid if !is_specialist */
138};
139
140/* define the tile_vector as array<cm_tile> */
141#define SPECVEC_TAG tile
142#define SPECVEC_TYPE struct cm_tile
143#include "specvec.h"
144
145/* define the tile_type_vector as array <cm_tile_type*> */
146#define SPECVEC_TAG tile_type
147#define SPECVEC_TYPE struct cm_tile_type *
148#include "specvec.h"
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) { \
152 var = *var##p; \
153 {
154#define tile_type_vector_iterate_end }} VECTOR_ITERATE_END; }
155
156/*
157 * A tile type.
158 * Holds the production (a hill produces 1/0/0);
159 * Holds a list of which tiles match this (all the hills and tundra);
160 * Holds a list of other types that are strictly better
161 * (grassland 2/0/0, plains 1/1/0, but not gold mine 0/1/6).
162 * Holds a list of other types that are strictly worse
163 * (the grassland and plains hold a pointer to the hill).
164 *
165 * Specialists are special types; is_specialist is set, and the tile
166 * vector is empty. We can never run out of specialists.
167 */
170 double estimated_fitness; /* weighted sum of production */
172 Specialist_type_id spec; /* valid only if is_specialist */
173 struct tile_vector tiles; /* valid only if !is_specialist */
176 int lattice_index; /* index in state->lattice */
177 int lattice_depth; /* depth = sum(#tiles) over all better types */
178};
179
180
181/*
182 * A partial solution.
183 * Has the count of workers assigned to each lattice position, and
184 * a count of idle workers yet unassigned.
185 */
187 /* indices for these two match the lattice indices */
188 int *worker_counts; /* number of workers on each type */
189 int *prereqs_filled; /* number of better types filled up */
190
191 int production[O_LAST]; /* raw production, cached for the heuristic */
192 int idle; /* number of idle workers */
193};
194
195/*
196 * State of the search.
197 * This holds all the information needed to do the search, all in one
198 * struct, in order to clean up the function calls.
199 */
200struct cm_state {
201 /* input from the caller */
203 /*mutable*/ struct city *pcity;
204
205 /* the tile lattice */
208
209 /* the best known solution, and its fitness */
212
213 /* hard constraints on production: any solution with less production than
214 * this fails to satisfy the constraints, so we can stop investigating
215 * this branch. A solution with more production than this may still
216 * fail (for being unhappy, for instance). */
218
219 /* needed luxury to be content, this includes effects by specialists */
221
222 /* the current solution we're examining. */
224
225 /*
226 * Where we are in the search. When we add a worker to the current
227 * partial solution, we also push the tile type index on the stack.
228 */
229 struct {
230 int *stack;
231 int size;
233
234 bool *workers_map; /* placement of the workers within the city map */
235};
236
237
238/* return #fields + specialist types */
239static int num_types(const struct cm_state *state);
240
241
242/* debugging functions */
243#ifdef CM_DEBUG
244static void real_print_tile_type(enum log_level level, const char *file,
245 const char *function, int line,
246 const struct cm_tile_type *ptype,
247 const char *prefix);
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__, \
251 ptype, prefix); \
252 }
253
254static void real_print_lattice(enum log_level level, const char *file,
255 const char *function, int line,
256 const struct tile_type_vector *lattice);
257#define print_lattice(loglevel, lattice) \
258 if (log_do_output_for_level(loglevel)) { \
259 real_print_lattice(loglevel, __FILE__, __FUNCTION__, __FC_LINE__, \
260 lattice); \
261 }
262
264 const char *file,
265 const char *function, int line,
266 const struct partial_solution *soln,
267 const struct cm_state *state);
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); \
272 }
273
274#else
275#define print_tile_type(loglevel, ptype, prefix)
276#define print_lattice(loglevel, lattice)
277#define print_partial_solution(loglevel, soln, state)
278#endif /* CM_DEBUG */
279
280static void cm_result_copy(struct cm_result *result,
281 const struct city *pcity, bool *workers_map);
282
283static double estimate_fitness(const struct cm_state *state,
284 const int production[]);
285static bool choice_is_promising(struct cm_state *state, int newchoice,
286 bool negative_ok);
287
288/************************************************************************/
293void cm_init(void)
294{
295 /* In the B&B algorithm there's not really anything to initialize. */
296#ifdef GATHER_TIME_STATS
297 memset(&performance, 0, sizeof(performance));
298
299 performance.greedy.wall_timer = timer_new(TIMER_USER, TIMER_ACTIVE,
300 "cm.greedy");
301 performance.greedy.name = "greedy";
302
304 "cm.opt");
305 performance.opt.name = "opt";
306#endif /* GATHER_TIME_STATS */
307}
308
309/************************************************************************/
315{
316 /* In the B&B algorithm there's not really anything to initialize. */
317}
318
319/************************************************************************/
323{
324 /* The B&B algorithm doesn't have city caches so there's nothing to do. */
325}
326
327/************************************************************************/
330void cm_free(void)
331{
332#ifdef GATHER_TIME_STATS
335
336 timer_destroy(performance.greedy.wall_timer);
337 timer_destroy(performance.opt.wall_timer);
338 memset(&performance, 0, sizeof(performance));
339#endif /* GATHER_TIME_STATS */
340}
341
342/************************************************************************/
346{
347 struct cm_result *result;
348
349 /* Initialise all values */
350 result = fc_calloc(1, sizeof(*result));
353 result->worker_positions
355 sizeof(*result->worker_positions));
356
357 /* Test if the city pointer is valid; the cm_result struct can be
358 * returned as it uses the maximal possible value for the size of
359 * 'worker_positions' (= city_map_tiles(CITY_MAP_MAX_RADIUS_SQ))*/
360 fc_assert_ret_val(pcity != nullptr, result);
361
362 return result;
363}
364
365/************************************************************************/
368void cm_result_destroy(struct cm_result *result)
369{
370 if (result != nullptr) {
371 if (result->worker_positions != nullptr) {
372 FC_FREE(result->worker_positions);
373 }
374 FC_FREE(result);
375 }
376}
377
378/****************************************************************************
379 Functions of tile-types.
380****************************************************************************/
381
382/************************************************************************/
385static void tile_type_init(struct cm_tile_type *type)
386{
387 memset(type, 0, sizeof(*type));
388 tile_vector_init(&type->tiles);
389 tile_type_vector_init(&type->better_types);
390 tile_type_vector_init(&type->worse_types);
391}
392
393/************************************************************************/
397static struct cm_tile_type *tile_type_dup(const struct cm_tile_type *oldtype)
398{
399 struct cm_tile_type *newtype = fc_malloc(sizeof(*newtype));
400
401 memcpy(newtype, oldtype, sizeof(*oldtype));
402 tile_vector_init(&newtype->tiles);
403 tile_type_vector_init(&newtype->better_types);
404 tile_type_vector_init(&newtype->worse_types);
405
406 return newtype;
407}
408
409/************************************************************************/
413{
414 /* The call to vector_free() will magically free all the tiles in the
415 * vector. */
416 tile_vector_free(&type->tiles);
417 tile_type_vector_free(&type->better_types);
418 tile_type_vector_free(&type->worse_types);
419}
420
421/************************************************************************/
426{
428 /* Destroy all data in the type, and free the type itself. */
430 free(type);
432
434}
435
436/************************************************************************/
441static bool tile_type_equal(const struct cm_tile_type *a,
442 const struct cm_tile_type *b)
443{
446 return FALSE;
447 }
449
450 if (a->is_specialist != b->is_specialist) {
451 return FALSE;
452 }
453
454 return TRUE;
455}
456
457/************************************************************************/
465static int tile_type_better(const struct cm_tile_type *a,
466 const struct cm_tile_type *b)
467{
468 int ret = 0;
469
472 if (ret > 0) {
473 return 0;
474 }
475 ret = -1;
476 } else if (b->production[stat_index] < a->production[stat_index]) {
477 if (ret < 0) {
478 return 0;
479 }
480 ret = 1;
481 }
483
484 if (a->is_specialist && !b->is_specialist) {
485 /* If A is a specialist and B isn't, and all of A's production is at
486 * least as good as B's, then A is better because it doesn't tie up
487 * the map tile. */
488 if (ret < 0) {
489 return 0;
490 }
491 return 1;
492 } else if (!a->is_specialist && b->is_specialist) {
493 /* Vice versa. */
494 if (ret > 0) {
495 return 0;
496 }
497 return -1;
498 }
499
500 return ret;
501}
502
503/************************************************************************/
510 const struct tile_type_vector *vec,
511 const struct cm_tile_type *ptype)
512{
513 int i;
514
515 for (i = 0; i < vec->size; i++) {
516 if (tile_type_equal(vec->p[i], ptype)) {
517 return i;
518 }
519 }
520
521 return -1;
522}
523
524/************************************************************************/
529static int tile_type_num_tiles(const struct cm_tile_type *type)
530{
531 if (type->is_specialist) {
532 return FC_INFINITY;
533 } else {
534 return tile_vector_size(&type->tiles);
535 }
536}
537
538/************************************************************************/
544static int tile_type_num_prereqs(const struct cm_tile_type *ptype)
545{
546 return ptype->better_types.size;
547}
548
549/************************************************************************/
554static const struct cm_tile_type *tile_type_get(const struct cm_state *state,
555 int type)
556{
557 /* Sanity check the index. */
558 fc_assert_ret_val(0 <= type, nullptr);
559 fc_assert_ret_val(state->lattice.size > type, nullptr);
560
561 return state->lattice.p[type];
562}
563
564/************************************************************************/
571static const struct cm_tile *tile_get(const struct cm_tile_type *ptype, int j)
572{
573 fc_assert_ret_val(!ptype->is_specialist, nullptr);
574 fc_assert_ret_val(0 <= j, nullptr);
575 fc_assert_ret_val(j < ptype->tiles.size, nullptr);
576
577 return &ptype->tiles.p[j];
578}
579
580
581/****************************************************************************
582 Functions on the cm_fitness struct.
583****************************************************************************/
584
585/************************************************************************/
588static bool fitness_better(struct cm_fitness a, struct cm_fitness b)
589{
590 if (a.sufficient != b.sufficient) {
591 return a.sufficient;
592 }
593 return a.weighted > b.weighted;
594}
595
596/************************************************************************/
601{
602 struct cm_fitness f;
603
605 f.weighted = -FC_INFINITY;
606 return f;
607}
608
609/************************************************************************/
613static struct cm_fitness compute_fitness(const int surplus[],
614 bool disorder, bool happy,
615 const struct cm_parameter *parameter)
616{
617 struct cm_fitness fitness;
618
620 fitness.weighted = 0;
621
623 fitness.weighted += surplus[stat_index] * parameter->factor[stat_index];
624 if (surplus[stat_index] < parameter->minimal_surplus[stat_index]) {
625 fitness.sufficient = FALSE;
626 }
628
629 if (happy) {
630 fitness.weighted += parameter->happy_factor;
631 } else if (parameter->require_happy) {
632 fitness.sufficient = FALSE;
633 }
634
635 if (disorder && !parameter->allow_disorder) {
636 fitness.sufficient = FALSE;
637 }
638
639 return fitness;
640}
641
642/****************************************************************************
643 Handle struct partial_solution.
644 - perform a deep copy
645 - convert to city
646 - convert to cm_result
647****************************************************************************/
648
649/************************************************************************/
653 int ntypes, int idle, bool negative_ok)
654{
655 into->worker_counts = fc_calloc(ntypes, sizeof(*into->worker_counts));
656 into->prereqs_filled = fc_calloc(ntypes, sizeof(*into->prereqs_filled));
657 if (negative_ok) {
659 into->production[otype] = -FC_INFINITY;
661 } else {
662 memset(into->production, 0, sizeof(into->production));
663 }
664 into->idle = idle;
665}
666
667/************************************************************************/
672{
673 free(into->worker_counts);
674 free(into->prereqs_filled);
675}
676
677/************************************************************************/
682 const struct partial_solution *src,
683 const struct cm_state *state)
684{
686 sizeof(*dst->worker_counts) * num_types(state));
688 sizeof(*dst->prereqs_filled) * num_types(state));
689 memcpy(dst->production, src->production, sizeof(dst->production));
690 dst->idle = src->idle;
691}
692
693
694/****************************************************************************
695 Evaluating a completed solution.
696****************************************************************************/
697
698/************************************************************************/
701static void apply_solution(struct cm_state *state,
702 const struct partial_solution *soln)
703{
704 struct city *pcity = state->pcity;
706 const struct civ_map *nmap = &(wld.map);
707#ifndef FREECIV_NDEBUG
708 int citizen_count = 0;
709#endif
710
711#ifdef GATHER_TIME_STATS
712 performance.current->apply_count++;
713#endif
714
715 fc_assert_ret(0 == soln->idle);
716
717 /* Clear all specialists, and remove all workers from fields (except
718 * the city center). Don't touch superspecialists. */
719 memset(&pcity->specialists, 0,
720 sizeof(pcity->specialists[0]) * normal_specialist_count());
721
722 city_map_iterate(city_radius_sq, cindex, x, y) {
723 if (is_free_worked_index(cindex)) {
724 state->workers_map[cindex] = TRUE;
725 } else {
726 state->workers_map[cindex] = FALSE;
727 }
729
730 /* Now for each tile type, find the right number of such tiles and set them
731 * as worked. For specialists we just increase the number of specialists
732 * of that type. */
733 for (i = 0 ; i < num_types(state); i++) {
734 int nworkers = soln->worker_counts[i];
735 const struct cm_tile_type *type;
736
737 if (nworkers == 0) {
738 /* No citizens of this type. */
739 continue;
740 }
741#ifndef FREECIV_NDEBUG
743#endif
744
745 type = tile_type_get(state, i);
746
747 if (type->is_specialist) {
748 /* Just increase the number of specialists. */
749 pcity->specialists[type->spec] += nworkers;
750 } else {
751 int j;
752
753 /* Place citizen workers onto the citymap tiles. */
754 for (j = 0; j < nworkers; j++) {
755 const struct cm_tile *cmtile = tile_get(type, j);
756
757 state->workers_map[cmtile->index] = TRUE;
758 }
759 }
760 }
761
762 /* Finally we must refresh the city to reset all the precomputed fields. */
764
766}
767
768/************************************************************************/
773static void get_city_surplus(const struct city *pcity,
774 int surplus[],
775 bool *disorder, bool *happy)
776{
778 surplus[o] = pcity->surplus[o];
780
781 *disorder = city_unhappy(pcity);
782 *happy = city_happy(pcity);
783}
784
785/************************************************************************/
789 const struct partial_solution *soln)
790{
791 struct city *pcity = state->pcity;
792 int surplus[O_LAST];
793 bool disorder, happy;
794
795 /* apply and evaluate the solution, backup is done in find_best_solution */
796 apply_solution(state, soln);
797 get_city_surplus(pcity, surplus, &disorder, &happy);
798
799 /* if this solution is not content, we have an estimate on min. luxuries */
800 if (disorder) {
801 /* We have to consider the influence of each specialist in this
802 solution possibly 'hiding' a potential unhappy citizen who
803 could require luxuries.
804 Since we know the city is in disorder, we can discount most
805 effects that make citizens content, since they clearly weren't
806 sufficient.
807 This may not be sufficient luxury to make the city content (due
808 to military unhappiness etc), but certainly no less will do.
809 (Specialists may also be making angry citizens content, requiring
810 additional luxuries, but we don't try to consider that here; this
811 just means we might explore some solutions unnecessarily.) */
814
815 state->min_luxury = surplus[O_LUXURY]
817 + 1;
818 }
819
820 return compute_fitness(surplus, disorder, happy, &state->parameter);
821}
822
823/************************************************************************/
827static void convert_solution_to_result(struct cm_state *state,
828 const struct partial_solution *soln,
829 struct cm_result *result)
830{
831 struct cm_fitness fitness;
832
833 if (soln->idle != 0) {
834 /* If there are unplaced citizens it's not a real solution, so the
835 * result is invalid. */
836 result->found_a_valid = FALSE;
837 return;
838 }
839
840 /* apply and evaluate the solution, backup is done in find_best_solution */
841 apply_solution(state, soln);
842 cm_result_copy(result, state->pcity, state->workers_map);
843
844 /* result->found_a_valid should be only true if it matches the
845 * parameter; figure out if it does */
846 fitness = compute_fitness(result->surplus, result->disorder,
847 result->happy, &state->parameter);
848 result->found_a_valid = fitness.sufficient;
849}
850
851/****************************************************************************
852 Compare functions to allow sorting lattice vectors.
853****************************************************************************/
854
855/************************************************************************/
863 const struct cm_tile_type *b)
864{
865 if (a == b) {
866 return 0;
867 }
868
869 /* Least depth first */
870 if (a->lattice_depth != b->lattice_depth) {
871 return a->lattice_depth - b->lattice_depth;
872 }
873
874 /* With equal depth, break ties arbitrarily, more production first. */
878 }
880
881 /* If we get here, then we have two copies of identical types, an error */
883 return 0;
884}
885
886/************************************************************************/
892static int compare_tile_type_by_fitness(const void *va, const void *vb)
893{
894 struct cm_tile_type * const *a = va;
895 struct cm_tile_type * const *b = vb;
896 double diff;
897
898 if (*a == *b) {
899 return 0;
900 }
901
902 /* To avoid double->int roundoff problems, we call a result non-zero only
903 * if it's larger than 0.5. */
904 diff = (*b)->estimated_fitness - (*a)->estimated_fitness;
905 if (diff > 0.5) {
906 return 1; /* return value is int; don't round down! */
907 }
908 if (diff < -0.5) {
909 return -1;
910 }
911
913}
914
917
918/************************************************************************/
924static int compare_tile_type_by_stat(const void *va, const void *vb)
925{
926 struct cm_tile_type * const *a = va;
927 struct cm_tile_type * const *b = vb;
928
929 if (*a == *b) {
930 return 0;
931 }
932
933 /* Consider the influence of trade on science, luxury, gold
934 for compute_max_stats_heuristics, which uses these sorted arrays,
935 it is essential, that the sorting is correct, else promising
936 branches get pruned */
937 double valuea = (*a)->production[compare_key] +
938 compare_key_trade_bonus * (*a)->production[O_TRADE];
939 double valueb = (*b)->production[compare_key] +
940 compare_key_trade_bonus * (*b)->production[O_TRADE];
941
942 /* Most production of what we care about goes first */
943 /* Double compare is ok, both values are calculated in the same way
944 and should only be considered equal, if equal in compare_key
945 and O_TRADE */
946 if (valuea != valueb) {
947 /* b-a so we sort big numbers first */
948 return valueb - valuea;
949 }
950
952}
953
954/****************************************************************************
955 Compute the tile-type lattice.
956****************************************************************************/
957
958/************************************************************************/
962static void compute_tile_production(const struct city *pcity,
963 const struct tile *ptile,
964 struct cm_tile_type *out)
965{
967
969 out->production[o] = city_tile_output(pcity, ptile, is_celebrating, o);
971}
972
973/************************************************************************/
980static void tile_type_lattice_add(struct tile_type_vector *lattice,
981 const struct cm_tile_type *newtype,
982 int tindex)
983{
984 struct cm_tile_type *type;
985 int i;
986
988 if (i >= 0) {
989 /* We already have this type of tile; use it. */
990 type = lattice->p[i];
991 } else {
992 /* This is a new tile type; add it to the lattice. */
994
995 /* Link up to the types we dominate, and those that dominate us */
998
999 if (cmp > 0) {
1000 tile_type_vector_append(&type->better_types, other);
1001 tile_type_vector_append(&other->worse_types, type);
1002 } else if (cmp < 0) {
1003 tile_type_vector_append(&other->better_types, type);
1004 tile_type_vector_append(&type->worse_types, other);
1005 }
1007
1008 /* Insert into the list */
1009 type->lattice_index = lattice->size;
1010 tile_type_vector_append(lattice, type);
1011 }
1012
1013 /* Finally, add the tile to the tile type. */
1014 if (!type->is_specialist) {
1015 struct cm_tile tile;
1016
1017 tile.type = type;
1018 tile.index = tindex;
1019
1020 tile_vector_append(&type->tiles, tile);
1021 }
1022}
1023
1024/*
1025 * Add the specialist types to the lattice.
1026 */
1027
1028/************************************************************************/
1033 const struct city *pcity)
1034{
1035 struct cm_tile_type type;
1036
1038 type.is_specialist = TRUE;
1039
1040 /* for each specialist type, create a tile_type that has as production
1041 * the bonus for the specialist (if the city is allowed to use it) */
1044 type.spec = i;
1045 output_type_iterate(output) {
1046 type.production[output] = get_specialist_output(pcity, i, output);
1048
1049 tile_type_lattice_add(lattice, &type, 0);
1050 }
1052}
1053
1054/************************************************************************/
1061static void top_sort_lattice(struct tile_type_vector *lattice)
1062{
1063 if (lattice->size > 0) {
1064 int i;
1065 bool marked[lattice->size];
1066 bool will_mark[lattice->size];
1067 struct tile_type_vector vectors[2];
1068 struct tile_type_vector *current, *next;
1069
1070 memset(marked, 0, sizeof(marked));
1071 memset(will_mark, 0, sizeof(will_mark));
1072
1075 current = &vectors[0];
1076 next = &vectors[1];
1077
1078 /* Fill up 'next' */
1080 if (tile_type_num_prereqs(ptype) == 0) {
1082 }
1084
1085 /* While we have nodes to process: mark the nodes whose prereqs have
1086 * all been visited. Then, store all the new nodes on the frontier. */
1087 while (next->size != 0) {
1088 /* What was the next frontier is now the current frontier */
1089 struct tile_type_vector *vtmp = current;
1090
1091 current = next;
1092 next = vtmp;
1093 next->size = 0; /* Clear out the contents */
1094
1095 /* Look over the current frontier and process everyone */
1097 /* See if all prereqs were marked. If so, decide to mark this guy,
1098 and put all the descendents on 'next'. */
1099 bool can_mark = TRUE;
1100 int sumdepth = 0;
1101
1102 if (will_mark[ptype->lattice_index]) {
1103 continue; /* We've already been processed */
1104 }
1105 tile_type_vector_iterate(&ptype->better_types, better) {
1106 if (!marked[better->lattice_index]) {
1107 can_mark = FALSE;
1108 break;
1109 } else {
1110 sumdepth += tile_type_num_tiles(better);
1111 if (sumdepth >= FC_INFINITY) {
1112 /* If this is the case, then something better could
1113 always be used, and the same holds for our children */
1115 can_mark = TRUE;
1116 break;
1117 }
1118 }
1120 if (can_mark) {
1121 /* Mark and put successors on the next frontier */
1122 will_mark[ptype->lattice_index] = TRUE;
1123 tile_type_vector_iterate(&ptype->worse_types, worse) {
1126
1127 /* This is what we spent all this time computing. */
1128 ptype->lattice_depth = sumdepth;
1129 }
1131
1132 /* Now, actually mark everyone and get set for next loop */
1133 for (i = 0; i < lattice->size; i++) {
1134 marked[i] = marked[i] || will_mark[i];
1135 will_mark[i] = FALSE;
1136 }
1137 }
1138
1141 }
1142}
1143
1144/************************************************************************/
1160static void clean_lattice(struct tile_type_vector *lattice,
1161 const struct city *pcity)
1162{
1163 int i, j; /* i is the index we read, j is the index we write */
1164 struct tile_type_vector tofree;
1165 bool forced_loop = FALSE;
1166
1167 /* We collect the types we want to remove and free them in one fell
1168 swoop at the end, in order to avoid memory errors. */
1170
1171 /* forced_loop is workaround for what seems like gcc optimization
1172 * bug.
1173 * This applies to -O2 optimization on some distributions. */
1174 if (lattice->size > 0) {
1175 forced_loop = TRUE;
1176 }
1177 for (i = 0, j = 0; i < lattice->size || forced_loop; i++) {
1178 struct cm_tile_type *ptype = lattice->p[i];
1180
1182
1183 if (ptype->lattice_depth >= csize) {
1185 } else {
1186 /* Remove links to children that are being removed. */
1187
1188 int ci, cj; /* 'c' for 'child'; read from ci, write to cj */
1189
1190 lattice->p[j] = ptype;
1191 lattice->p[j]->lattice_index = j;
1192 j++;
1193
1194 for (ci = 0, cj = 0; ci < ptype->worse_types.size; ci++) {
1195 const struct cm_tile_type *ptype2 = ptype->worse_types.p[ci];
1196
1197 if (ptype2->lattice_depth < csize) {
1198 ptype->worse_types.p[cj] = ptype->worse_types.p[ci];
1199 cj++;
1200 }
1201 }
1202 ptype->worse_types.size = cj;
1203 }
1204 }
1205 lattice->size = j;
1206
1208}
1209
1210/************************************************************************/
1215static void sort_lattice_by_fitness(const struct cm_state *state,
1216 struct tile_type_vector *lattice)
1217{
1218 int i;
1219
1220 /* compute fitness */
1222 ptype->estimated_fitness = estimate_fitness(state, ptype->production);
1224
1225 /* sort by it */
1226 qsort(lattice->p, lattice->size, sizeof(*lattice->p),
1228
1229 /* fix the lattice indices */
1230 for (i = 0; i < lattice->size; i++) {
1231 lattice->p[i]->lattice_index = i;
1232 }
1233
1234 log_base(LOG_LATTICE, "sorted lattice:");
1235 print_lattice(LOG_LATTICE, lattice);
1236}
1237
1238/************************************************************************/
1241static void init_tile_lattice(struct city *pcity,
1242 struct tile_type_vector *lattice)
1243{
1244 struct cm_tile_type type;
1245 struct tile *pcenter = city_tile(pcity);
1246 const struct civ_map *nmap = &(wld.map);
1247
1248 /* Add all the fields into the lattice */
1249 tile_type_init(&type); /* Init just once */
1250
1252 ctindex) {
1253 if (is_free_worked(pcity, ptile)) {
1254 continue;
1255 } else if (city_can_work_tile(pcity, ptile)) {
1256 compute_tile_production(pcity, ptile, &type); /* Clobbers type */
1257 tile_type_lattice_add(lattice, &type, ctindex); /* Copy type if needed */
1258 }
1260
1261 /* Add all the specialists into the lattice. */
1263
1264 /* Set the lattice_depth fields, and clean up unreachable nodes. */
1265 top_sort_lattice(lattice);
1266 clean_lattice(lattice, pcity);
1267
1268 /* All done now. */
1269 print_lattice(LOG_LATTICE, lattice);
1270}
1271
1272
1273/****************************************************************************
1274
1275 Handling the choice stack for the bb algorithm.
1276
1277****************************************************************************/
1278
1279
1280/************************************************************************/
1283static bool choice_stack_empty(struct cm_state *state)
1284{
1285 return state->choice.size == 0;
1286}
1287
1288/************************************************************************/
1291static int last_choice(struct cm_state *state)
1292{
1294
1295 return state->choice.stack[state->choice.size - 1];
1296}
1297
1298/************************************************************************/
1303static int num_types(const struct cm_state *state)
1304{
1305 return tile_type_vector_size(&state->lattice);
1306}
1307
1308/************************************************************************/
1315 int itype, int number,
1316 const struct cm_state *state)
1317{
1318 const struct cm_tile_type *ptype = tile_type_get(state, itype);
1319 int newcount;
1320 int old_worker_count = soln->worker_counts[itype];
1321
1322 if (number == 0) {
1323 return;
1324 }
1325
1326 /* update the number of idle workers */
1327 newcount = soln->idle - number;
1328 fc_assert_ret(newcount >= 0);
1330 soln->idle = newcount;
1331
1332 /* update the worker counts */
1333 newcount = soln->worker_counts[itype] + number;
1334 fc_assert_ret(newcount >= 0);
1336 soln->worker_counts[itype] = newcount;
1337
1338 /* update prereqs array: if we are no longer full but we were,
1339 * we need to decrement the count, and vice-versa. */
1341 fc_assert_ret(number < 0);
1342 tile_type_vector_iterate(&ptype->worse_types, other) {
1343 soln->prereqs_filled[other->lattice_index]--;
1344 fc_assert_ret(soln->prereqs_filled[other->lattice_index] >= 0);
1346 } else if (soln->worker_counts[itype] == tile_type_num_tiles(ptype)) {
1347 fc_assert_ret(number > 0);
1348 tile_type_vector_iterate(&ptype->worse_types, other) {
1349 soln->prereqs_filled[other->lattice_index]++;
1350 fc_assert_ret(soln->prereqs_filled[other->lattice_index]
1353 }
1354
1355 /* update production */
1357 newcount = soln->production[stat_index] + number * ptype->production[stat_index];
1358 soln->production[stat_index] = newcount;
1360}
1361
1362/************************************************************************/
1366 int itype, const struct cm_state *state)
1367{
1368 add_workers(soln, itype, 1, state);
1369}
1370
1371/************************************************************************/
1375 int itype, const struct cm_state *state)
1376{
1377 add_workers(soln, itype, -1, state);
1378}
1379
1380/************************************************************************/
1384static void pop_choice(struct cm_state *state)
1385{
1387 remove_worker(&state->current, last_choice(state), state);
1388 state->choice.size--;
1389}
1390
1391/************************************************************************/
1394static bool prereqs_filled(const struct partial_solution *soln, int type,
1395 const struct cm_state *state)
1396{
1397 const struct cm_tile_type *ptype = tile_type_get(state, type);
1399
1400 return soln->prereqs_filled[type] == prereqs;
1401}
1402
1403/************************************************************************/
1412static int next_choice(struct cm_state *state, int oldchoice, bool negative_ok)
1413{
1414 int newchoice;
1415
1416 for (newchoice = oldchoice + 1;
1417 newchoice < num_types(state); newchoice++) {
1418 const struct cm_tile_type *ptype = tile_type_get(state, newchoice);
1419
1420 if (!ptype->is_specialist && (state->current.worker_counts[newchoice]
1421 == tile_vector_size(&ptype->tiles))) {
1422 /* we've already used all these tiles */
1423 continue;
1424 }
1425 if (!prereqs_filled(&state->current, newchoice, state)) {
1426 /* we could use a strictly better tile instead */
1427 continue;
1428 }
1430 /* heuristic says we can't beat the best going this way */
1431 log_base(LOG_PRUNE_BRANCH, "--- pruning branch ---");
1434 " + worker on ");
1435 log_base(LOG_PRUNE_BRANCH, "--- branch pruned ---");
1436 continue;
1437 }
1438 break;
1439 }
1440
1441 /* returns num_types if no next choice was available. */
1442 return newchoice;
1443}
1444
1445
1446/************************************************************************/
1450static bool take_sibling_choice(struct cm_state *state, bool negative_ok)
1451{
1452 int oldchoice = last_choice(state);
1453 int newchoice;
1454
1455 /* need to remove first, to run the heuristic */
1456 remove_worker(&state->current, oldchoice, state);
1458
1459 if (newchoice == num_types(state)) {
1460 /* add back in so the caller can then remove it again. */
1461 add_worker(&state->current, oldchoice, state);
1462 return FALSE;
1463 } else {
1464 add_worker(&state->current, newchoice, state);
1465 state->choice.stack[state->choice.size-1] = newchoice;
1466 /* choice.size is unchanged */
1467 return TRUE;
1468 }
1469}
1470
1471/************************************************************************/
1478static bool take_child_choice(struct cm_state *state, bool negative_ok)
1479{
1480 int oldchoice, newchoice;
1481
1482 if (state->current.idle == 0) {
1483 return FALSE;
1484 }
1485
1486 if (state->choice.size == 0) {
1487 oldchoice = 0;
1488 } else {
1489 oldchoice = last_choice(state);
1490 }
1491
1492 /* oldchoice-1 because we can use oldchoice again */
1494
1495 /* did we fail? */
1496 if (newchoice == num_types(state)) {
1497 return FALSE;
1498 }
1499
1500 /* now push the new choice on the choice stack */
1501 add_worker(&state->current, newchoice, state);
1502 state->choice.stack[state->choice.size] = newchoice;
1503 state->choice.size++;
1504
1505 return TRUE;
1506}
1507
1508/************************************************************************/
1513 const struct cm_state *state,
1514 const struct tile_type_vector *lattice)
1515{
1516 int last_worker_choice = -1;
1517 int i;
1518
1519 if (soln->idle == 0) {
1520 return;
1521 }
1522
1523 /* find the last worker type added (-1 if none) */
1524 for (i = 0; i < num_types(state); i++) {
1525 if (soln->worker_counts[i] != 0) {
1527 }
1528 }
1529
1530 /* While there are idle workers, pick up the next-best kind of tile,
1531 * and assign the workers to the tiles.
1532 * Respect lexicographic order and prerequisites. */
1534 int used = soln->worker_counts[ptype->lattice_index];
1535 int total = tile_type_num_tiles(ptype);
1536 int touse;
1537
1538 if (ptype->lattice_index < last_worker_choice) {
1539 /* lex-order: we can't use ptype (some other branch
1540 will check this combination, or already did) */
1541 continue;
1542 }
1543 if (!prereqs_filled(soln, ptype->lattice_index, state)) {
1544 /* don't bother using this tile before all better tiles are used */
1545 continue;
1546 }
1547
1548 touse = total - used;
1549 if (touse > soln->idle) {
1550 touse = soln->idle;
1551 }
1552 add_workers(soln, ptype->lattice_index, touse, state);
1553
1554 if (soln->idle == 0) {
1555 /* nothing left to do here */
1556 return;
1557 }
1559}
1560
1561/************************************************************************/
1564static int specialists_in_solution(const struct cm_state *state,
1565 const struct partial_solution *soln)
1566{
1567 int count = 0;
1568 int i;
1569
1570 for (i = 0 ; i < num_types(state); i++) {
1571 if (soln->worker_counts[i] > 0 && tile_type_get(state, i)->is_specialist) {
1572 count += soln->worker_counts[i];
1573 }
1574 }
1575
1576 return count;
1577}
1578
1579/************************************************************************/
1589static void compute_max_stats_heuristic(const struct cm_state *state,
1590 const struct partial_solution *soln,
1591 int production[],
1592 int check_choice, bool negative_ok)
1593{
1594 struct partial_solution solnplus; /* Will be soln, plus some tiles */
1595 const struct civ_map *nmap = &(wld.map);
1596
1597 /* Production is whatever the solution produces, plus the
1598 most possible of each kind of production the idle workers could
1599 produce */
1600
1601 if (soln->idle == 1) {
1602 /* Then the total solution is soln + this new worker. So we know the
1603 production exactly, and can shortcut the later code. */
1604 const struct cm_tile_type *ptype = tile_type_get(state, check_choice);
1605
1606 memcpy(production, soln->production, sizeof(soln->production));
1608 production[stat_index] += ptype->production[stat_index];
1610
1611 } else {
1612
1613 /* Initialize solnplus here, after the shortcut check */
1615 city_size_get(state->pcity),
1616 negative_ok);
1617
1619 /* compute the solution that has soln, then the check_choice,
1620 then complete it with the best available tiles for the stat. */
1624
1627
1629
1630 }
1631
1632 /* We found the basic production, however, bonus, taxes,
1633 * free production, tithes, trade routes are missing.
1634 * We add free production, and have the city.c code do the rest */
1635
1636 struct city *pcity = state->pcity;
1637 struct tile *pcenter = city_tile(pcity);
1639
1641 int base = production[stat_index];
1642
1644 if (is_free_worked(pcity, ptile)) {
1646 }
1648 pcity->citizen_base[stat_index] = base;
1650
1652 memcpy(production, pcity->prod, sizeof(pcity->prod));
1653}
1654
1655/************************************************************************/
1661static bool choice_is_promising(struct cm_state *state, int newchoice,
1662 bool negative_ok)
1663{
1664 int production[O_LAST];
1665 bool beats_best = FALSE;
1666
1667 /* this computes an upper bound (componentwise) for the current branch,
1668 if it is worse in every component than the best, or still insufficient,
1669 then we can prune the whole branch */
1670 compute_max_stats_heuristic(state, &state->current, production, newchoice,
1671 negative_ok);
1672
1674 if (production[stat_index] < state->min_production[stat_index]) {
1675 log_base(LOG_PRUNE_BRANCH, "--- pruning: insufficient %s (%d < %d)",
1677 state->min_production[stat_index]);
1678 return FALSE;
1679 }
1680 if (production[stat_index] > state->best.production[stat_index]
1681 && state->parameter.factor[stat_index] > 0 ) {
1682 beats_best = TRUE;
1683 /* may still fail to meet min at another production type, so
1684 * don't short-circuit */
1685 }
1687
1688 /* If we don't get the city content, we assume using every idle worker
1689 as specialist and the maximum producible luxury already computed.
1690 If this is less than the amount of luxury we calculated in
1691 evaluate_solution() (where min_luxury is set), when we observed the
1692 city in disorder, then this is clearly not worth pursuing.
1693 (Since we're comparing to evaluate_solution()'s calculation, we
1694 don't need to take effects, angry citizens etc into account here
1695 either.)
1696 FIXME: this heuristic will break in rulesets where specialists can
1697 influence happiness other than by direct production of luxury. */
1698 {
1703 int max_luxury = production[O_LUXURY]
1705
1706 if (max_luxury < state->min_luxury ) {
1707 log_base(LOG_PRUNE_BRANCH, "--- pruning: disorder (%d + %d*%d < %d)",
1708 production[O_LUXURY],
1711 state->min_luxury);
1712 return FALSE;
1713 }
1714 }
1715 if (!beats_best) {
1716 log_base(LOG_PRUNE_BRANCH, "--- pruning: best is better in all important ways");
1717 }
1718
1719 return beats_best;
1720}
1721
1722/************************************************************************/
1725static void init_min_production(struct cm_state *state)
1726{
1727 struct city *pcity = state->pcity;
1728
1730 state->min_production[o] = pcity->usage[o] + state->parameter.minimal_surplus[o];
1732
1733 /* We could get a minimum on luxury if we knew how many luxuries were
1734 * needed to make us content. */
1735}
1736
1737/************************************************************************/
1740static void get_tax_rates(const struct player *pplayer, int rates[])
1741{
1742 const int SCIENCE = 0, TAX = 1, LUXURY = 2;
1743
1744 if (game.info.changable_tax) {
1745 rates[SCIENCE] = pplayer->economic.science;
1746 rates[LUXURY] = pplayer->economic.luxury;
1747 rates[TAX] = 100 - rates[SCIENCE] - rates[LUXURY];
1748 } else {
1752 }
1753
1754 /* ANARCHY */
1756 rates[SCIENCE] = 0;
1757 rates[LUXURY] = 100;
1758 rates[TAX] = 0;
1759 }
1760}
1761
1762/************************************************************************/
1770static double estimate_fitness(const struct cm_state *state,
1771 const int production[])
1772{
1773 const int SCIENCE = 0, TAX = 1, LUXURY = 2;
1774 const struct city *pcity = state->pcity;
1775 const struct player *pplayer = city_owner(pcity);
1776 int rates[3];
1777 double estimates[O_LAST];
1778 double sum = 0;
1779 int trade;
1780
1782 estimates[stat_index] = production[stat_index];
1784
1785 /* bonus to trade is applied before calculating taxes, see city.c */
1786 trade = estimates[O_TRADE] * pcity->bonus[O_TRADE] / 100.0;
1787
1788 get_tax_rates(pplayer, rates);
1789
1790 /* sci/lux/gold get benefit from the tax rates (in percentage) */
1792 += rates[SCIENCE] * trade / 100.0;
1794 += rates[LUXURY] * trade / 100.0;
1796 += rates[TAX] * trade / 100.0;
1797
1798 /* now add in the bonuses from building effects (in percentage) */
1800 estimates[stat_index] *= pcity->bonus[stat_index] / 100.0;
1802
1803 /* finally, sum it all up, weighted by the parameter, but give additional
1804 * weight to luxuries to take account of disorder/happy constraints */
1808 sum += estimates[O_LUXURY];
1809
1810 return sum;
1811}
1812
1813/************************************************************************/
1825static bool bb_next(struct cm_state *state, bool negative_ok)
1826{
1827 /* if no idle workers, then look at our solution. */
1828 if (state->current.idle == 0) {
1829 struct cm_fitness value = evaluate_solution(state, &state->current);
1830
1832 if (fitness_better(value, state->best_value)) {
1833 log_base(LOG_BETTER_LEAF, "-> replaces previous best");
1834 copy_partial_solution(&state->best, &state->current, state);
1835 state->best_value = value;
1836 }
1837 }
1838
1839 /* try to move to a child branch, if we can. If not (including if we're
1840 at a leaf), then move to a sibling. */
1841 if (!take_child_choice(state, negative_ok)) {
1842 /* keep trying to move to a sibling branch, or popping out a level if
1843 we're stuck (fully examined the current branch) */
1844 while ((!choice_stack_empty(state))
1845 && !take_sibling_choice(state, negative_ok)) {
1846 pop_choice(state);
1847 }
1848
1849 /* if we popped out all the way, we're done */
1850 if (choice_stack_empty(state)) {
1851 return TRUE;
1852 }
1853 }
1854
1855 /* if we didn't detect that we were done, we aren't */
1856 return FALSE;
1857}
1858
1859/************************************************************************/
1862static struct cm_state *cm_state_init(struct city *pcity, bool negative_ok)
1863{
1864 const int SCIENCE = 0, TAX = 1, LUXURY = 2;
1865 const struct player *pplayer = city_owner(pcity);
1866 int numtypes;
1867 struct cm_state *state = fc_malloc(sizeof(*state));
1868 int rates[3];
1870
1871 log_base(LOG_CM_STATE, "creating cm_state for %s (size %d)",
1873
1874 /* copy the arguments */
1875 state->pcity = pcity;
1876
1877 /* create the lattice */
1881
1882 get_tax_rates(pplayer, rates);
1883
1884 /* For the heuristic, make sorted copies of the lattice */
1886 int lsize = tile_type_vector_size(&state->lattice);
1887
1888 if (lsize > 0) {
1892 /* Calculate effect of 1 trade production on interesting production */
1893 switch (stat_index) {
1894 case O_SCIENCE:
1895 compare_key_trade_bonus = rates[SCIENCE] * pcity->bonus[O_TRADE] / 100.0;
1896 break;
1897 case O_LUXURY:
1898 compare_key_trade_bonus = rates[LUXURY] * pcity->bonus[O_TRADE] / 100.0;
1899 break;
1900 case O_GOLD:
1901 compare_key_trade_bonus = rates[TAX] * pcity->bonus[O_TRADE] / 100.0;
1902 break;
1903 default:
1905 break;
1906 }
1908 sizeof(*state->lattice_by_prod[stat_index].p),
1910 }
1912
1913 state->min_luxury = - FC_INFINITY;
1914
1915 /* We have no best solution yet, so its value is the worst possible. */
1917 state->best_value = worst_fitness();
1918
1919 /* Initialize the current solution and choice stack to empty */
1921 state->choice.stack = fc_malloc(csize * sizeof(*state->choice.stack));
1922 state->choice.size = 0;
1923
1924 /* Initialize workers map */
1926 sizeof(state->workers_map));
1927
1928 return state;
1929}
1930
1931/************************************************************************/
1935{
1936 struct city *pcity = state->pcity;
1938 citizens city_size = city_size_get(pcity);
1939 int max_surplus = -game.info.food_cost * city_size;
1941 citizens workers = city_size;
1942 int food_needed = city_granary_size(city_size) - pcity->food_stock;
1943 int min_turns;
1944 const struct civ_map *nmap = &(wld.map);
1945
1946 city_map_iterate(city_radius_sq, cindex, x, y) {
1947 struct tile *ptile = city_map_to_tile(nmap, pcity->tile, city_radius_sq, x, y);
1948 if (!ptile) {
1949 continue;
1950 }
1951 if (is_free_worked_index(cindex)) {
1953 }
1955
1956 if (max_surplus <= 0) {
1957 return max_surplus;
1958 }
1959
1960 if (food_needed <= 0) {
1961 return 0;
1962 }
1963
1965 int num = tile_vector_size(&ptype->tiles);
1966
1967 if (ptype->is_specialist || workers < num) {
1968 max_surplus += workers * ptype->production[O_FOOD];
1969 break;
1970 }
1971 max_surplus += num * ptype->production[O_FOOD];
1972 workers -= num;
1974
1975 /* min_turns will always be positive because if food_needed or
1976 * max_surplus are non-positive, this function returns earlier. */
1978
1979 return (food_needed + min_turns - 1) / min_turns;
1980}
1981
1982/************************************************************************/
1986static void begin_search(struct cm_state *state,
1987 const struct cm_parameter *parameter,
1988 bool negative_ok)
1989{
1990#ifdef GATHER_TIME_STATS
1991 timer_start(performance.current->wall_timer);
1992 performance.current->query_count++;
1993#endif /* GATHER_TIME_STATS */
1994
1995 /* copy the parameter and sort the main lattice by it */
1996 cm_copy_parameter(&state->parameter, parameter);
1997 sort_lattice_by_fitness(state, &state->lattice);
1998
1999 if (parameter->max_growth) {
2002 }
2003
2004 init_min_production(state);
2005
2006 /* Clear out the old solution */
2007 state->best_value = worst_fitness();
2009 init_partial_solution(&state->current, num_types(state),
2010 city_size_get(state->pcity),
2011 negative_ok);
2012 state->choice.size = 0;
2013}
2014
2015/************************************************************************/
2019static void end_search(struct cm_state *state)
2020{
2021#ifdef GATHER_TIME_STATS
2022 timer_stop(performance.current->wall_timer);
2023
2024#ifdef PRINT_TIME_STATS_EVERY_QUERY
2026#endif /* PRINT_TIME_STATS_EVERY_QUERY */
2027
2028 performance.current = nullptr;
2029#endif /* GATHER_TIME_STATS */
2030}
2031
2032/************************************************************************/
2035static void cm_state_free(struct cm_state *state)
2036{
2043
2044 FC_FREE(state->choice.stack);
2045 FC_FREE(state->workers_map);
2046 FC_FREE(state);
2047}
2048
2049/************************************************************************/
2052static void cm_find_best_solution(struct cm_state *state,
2053 const struct cm_parameter *const parameter,
2054 struct cm_result *result, bool negative_ok)
2055{
2056 int loop_count = 0;
2057 int max_count;
2058 struct city backup;
2059
2060#ifdef GATHER_TIME_STATS
2061 performance.current = &performance.opt;
2062#endif
2063
2064 begin_search(state, parameter, negative_ok);
2065
2066 /* Make a backup of the city to restore at the very end */
2067 memcpy(&backup, state->pcity, sizeof(backup));
2068
2069 if (player_is_cpuhog(city_owner(state->pcity))) {
2071 } else {
2073 }
2074
2075 result->aborted = FALSE;
2076
2077 /* search until we find a feasible solution */
2078 while (!bb_next(state, negative_ok)) {
2079 /* Limit the number of loops. */
2080 loop_count++;
2081
2082 if (loop_count == max_count + 1) {
2083#ifdef FREECIV_TESTMATIC
2084 /* This happens at a rate inversely proportional to the number of needed iterations
2085 * https://osdn.net/projects/freeciv/ticket/44438
2086 * we mostly find solutions in less than 100 iteration
2087 * 33% in less than 24 iterations
2088 * 66% in less than 100
2089 * 99% in less than 1800
2090 * extremely rarely 10 000+
2091 * it is not a bug it is normal, so just silent this warning
2092 */
2093 log_base(
2094 LOG_DEBUG,
2095 "Did not find a cm solution in %d iterations for %s.",
2096 max_count, city_name_get(state->pcity));
2097#endif /* FREECIV_TESTMATIC */
2098
2099#ifndef CM_LOOP_NO_LIMIT
2100 result->aborted = TRUE;
2101 break;
2102#endif /* CM_LOOP_NO_LIMIT */
2103 }
2104 }
2105
2106#ifdef CM_LOOP_NO_LIMIT
2107 if (loop_count > max_count) {
2108 log_warn("It took %d iterations to finish.", loop_count);
2109 }
2110#endif /* CM_LOOP_NO_LIMIT */
2111
2112 /* convert to the caller's format */
2113 convert_solution_to_result(state, &state->best, result);
2114
2115 memcpy(state->pcity, &backup, sizeof(backup));
2116
2117 end_search(state);
2118}
2119
2120/************************************************************************/
2125 const struct cm_parameter *param,
2126 struct cm_result *result, bool negative_ok)
2127{
2128 struct cm_state *state = cm_state_init(pcity, negative_ok);
2129 const struct civ_map *nmap = &(wld.map);
2130
2131 /* Refresh the city. Otherwise the CM can give wrong results or just be
2132 * slower than necessary. Note that cities are often passed in in an
2133 * unrefreshed state (which should probably be fixed). */
2135
2136 cm_find_best_solution(state, param, result, negative_ok);
2137 cm_state_free(state);
2138}
2139
2140/************************************************************************/
2143bool cm_are_parameter_equal(const struct cm_parameter *const p1,
2144 const struct cm_parameter *const p2)
2145{
2147 if (p1->minimal_surplus[i] != p2->minimal_surplus[i]) {
2148 return FALSE;
2149 }
2150 if (p1->factor[i] != p2->factor[i]) {
2151 return FALSE;
2152 }
2154 if (p1->require_happy != p2->require_happy) {
2155 return FALSE;
2156 }
2157 if (p1->allow_disorder != p2->allow_disorder) {
2158 return FALSE;
2159 }
2160 if (p1->allow_specialists != p2->allow_specialists) {
2161 return FALSE;
2162 }
2163 if (p1->happy_factor != p2->happy_factor) {
2164 return FALSE;
2165 }
2166 if (p1->max_growth != p2->max_growth) {
2167 return FALSE;
2168 }
2169
2170 return TRUE;
2171}
2172
2173/************************************************************************/
2177 const struct cm_parameter *const src)
2178{
2179 memcpy(dest, src, sizeof(struct cm_parameter));
2180}
2181
2182/************************************************************************/
2186{
2188 dest->minimal_surplus[stat_index] = 0;
2189 dest->factor[stat_index] = 1;
2191
2192 dest->happy_factor = 1;
2193 dest->require_happy = FALSE;
2194 dest->allow_disorder = FALSE;
2195 dest->allow_specialists = TRUE;
2196 dest->max_growth = FALSE;
2197}
2198
2199/************************************************************************/
2204{
2207 dest->factor[stat_index] = 1;
2209
2210 dest->happy_factor = 1;
2211 dest->require_happy = FALSE;
2212 dest->allow_disorder = TRUE;
2213 dest->allow_specialists = TRUE;
2214 dest->max_growth = FALSE;
2215}
2216
2217/************************************************************************/
2220int cm_result_workers(const struct cm_result *result)
2221{
2222 int count = 0;
2223
2224 city_map_iterate(result->city_radius_sq, cindex, x, y) {
2225 if (is_free_worked_index(cindex)) {
2226 continue;
2227 }
2228
2229 if (result->worker_positions[cindex]) {
2230 count++;
2231 }
2233
2234 return count;
2235}
2236
2237/************************************************************************/
2240int cm_result_specialists(const struct cm_result *result)
2241{
2242 int count = 0;
2243
2245 count += result->specialists[spec];
2247
2248 return count;
2249}
2250
2251/************************************************************************/
2254int cm_result_citizens(const struct cm_result *result)
2255{
2256 return cm_result_workers(result) + cm_result_specialists(result);
2257}
2258
2259/************************************************************************/
2264 const struct city *pcity)
2265{
2266 cm_result_copy(result, pcity, nullptr);
2267}
2268
2269/************************************************************************/
2274static void cm_result_copy(struct cm_result *result,
2275 const struct city *pcity, bool *workers_map)
2276{
2277 struct tile *pcenter = city_tile(pcity);
2278 const struct civ_map *nmap = &(wld.map);
2279
2280 /* Clear worker positions */
2281 memset(result->worker_positions, 0,
2282 sizeof(*result->worker_positions)
2283 * city_map_tiles(result->city_radius_sq));
2284
2286 if (workers_map == nullptr) {
2287 /* Use the main map */
2288 struct city *pwork = tile_worked(ptile);
2289
2290 result->worker_positions[ctindex] = (pwork != nullptr && pwork == pcity);
2291 } else {
2292 result->worker_positions[ctindex] = workers_map[ctindex];
2293 }
2295
2296 /* Copy the specialist counts */
2298 result->specialists[spec] = pcity->specialists[spec];
2300
2301 /* Find the surplus production numbers */
2303 &result->disorder, &result->happy);
2304
2305 /* This is a valid result, in a sense */
2306 result->found_a_valid = TRUE;
2307}
2308
2309/************************************************************************/
2312#ifdef CM_DEBUG
2313static void snprint_production(char *buffer, size_t bufsz,
2314 const int production[])
2315{
2316 fc_snprintf(buffer, bufsz, "[%d %d %d %d %d %d]",
2320}
2321
2322/************************************************************************/
2325static void real_print_tile_type(enum log_level level, const char *file,
2326 const char *function, int line,
2327 const struct cm_tile_type *ptype,
2328 const char *prefix)
2329{
2330 char prodstr[256];
2331
2332 snprint_production(prodstr, sizeof(prodstr), ptype->production);
2333 do_log(file, function, line, FALSE, level,
2334 "%s%s fitness %g depth %d, idx %d; %d tiles", prefix,
2335 prodstr, ptype->estimated_fitness, ptype->lattice_depth,
2336 ptype->lattice_index, tile_type_num_tiles(ptype));
2337}
2338
2339/************************************************************************/
2342static void real_print_lattice(enum log_level level, const char *file,
2343 const char *function, int line,
2344 const struct tile_type_vector *lattice)
2345{
2346 do_log(file, function, line, FALSE, level,
2347 "lattice has %u terrain types", (unsigned) lattice->size);
2351}
2352
2353/************************************************************************/
2357 const char *file,
2358 const char *function, int line,
2359 const struct partial_solution *soln,
2360 const struct cm_state *state)
2361{
2362 int i;
2363 int last_type = 0;
2364 char buf[256];
2365
2366 if (soln->idle != 0) {
2367 do_log(file, function, line, FALSE, level,
2368 "** partial solution has %d idle workers", soln->idle);
2369 } else {
2370 do_log(file, function, line, FALSE, level, "** completed solution:");
2371 }
2372
2373 snprint_production(buf, sizeof(buf), soln->production);
2374 do_log(file, function, line, FALSE, level, "production: %s", buf);
2375
2376 do_log(file, function, line, FALSE, level, "tiles used:");
2377 for (i = 0; i < num_types(state); i++) {
2378 if (soln->worker_counts[i] != 0) {
2379 fc_snprintf(buf, sizeof(buf), " %d tiles of type ",
2380 soln->worker_counts[i]);
2382 tile_type_get(state, i), buf);
2383 }
2384 }
2385
2386 for (i = 0; i < num_types(state); i++) {
2387 if (soln->worker_counts[i] != 0) {
2388 last_type = i;
2389 }
2390 }
2391
2392 do_log(file, function, line, FALSE, level, "tiles available:");
2393 for (i = last_type; i < num_types(state); i++) {
2394 const struct cm_tile_type *ptype = tile_type_get(state, i);
2395
2396 if (soln->prereqs_filled[i] == tile_type_num_prereqs(ptype)
2397 && soln->worker_counts[i] < tile_type_num_tiles(ptype)) {
2399 tile_type_get(state, i), " ");
2400 }
2401 }
2402}
2403
2404#endif /* CM_DEBUG */
2405
2406#ifdef GATHER_TIME_STATS
2407/************************************************************************/
2410static void print_performance(struct one_perf *counts)
2411{
2412 double s, ms;
2413 double q;
2414 int queries, applies;
2415
2416 s = timer_read_seconds(counts->wall_timer);
2417 ms = 1000.0 * s;
2418
2419 queries = counts->query_count;
2420 q = queries;
2421
2422 applies = counts->apply_count;
2423
2425 "CM-%s: overall=%fs queries=%d %fms / query, %d applies",
2426 counts->name, s, queries, ms / q, applies);
2427}
2428#endif /* GATHER_TIME_STATS */
2429
2430/************************************************************************/
2433void cm_print_city(const struct city *pcity)
2434{
2435 struct tile *pcenter = city_tile(pcity);
2436 const struct civ_map *nmap = &(wld.map);
2437
2438 log_test("cm_print_city(city %d=\"%s\")", pcity->id, city_name_get(pcity));
2439 log_test(" size=%d, specialists=%s",
2441
2442 log_test(" workers at:");
2444 cindex) {
2445 struct city *pwork = tile_worked(ptile);
2446
2447 if (pwork != nullptr && pwork == pcity) {
2448 int cx, cy;
2449
2450 city_tile_index_to_xy(&cx, &cy, cindex,
2452 log_test(" {%2d,%2d} (%4d,%4d)", cx, cy, TILE_XY(ptile));
2453 }
2455
2456 log_test(" food = %3d (%+3d)",
2457 pcity->prod[O_FOOD], pcity->surplus[O_FOOD]);
2458 log_test(" shield = %3d (%+3d)",
2459 pcity->prod[O_SHIELD], pcity->surplus[O_SHIELD]);
2460 log_test(" trade = %3d", pcity->surplus[O_TRADE]);
2461
2462 log_test(" gold = %3d (%+3d)",
2463 pcity->prod[O_GOLD], pcity->surplus[O_GOLD]);
2464 log_test(" luxury = %3d", pcity->prod[O_LUXURY]);
2465 log_test(" science = %3d", pcity->prod[O_SCIENCE]);
2466}
2467
2468/************************************************************************/
2471void cm_print_result(const struct cm_result *result)
2472{
2474 sizeof(*city_map_data));
2475
2476 log_test("cm_print_result(result=%p)", (void *) result);
2477 log_test(" found_a_valid=%d disorder=%d happy=%d",
2478 result->found_a_valid, result->disorder, result->happy);
2479
2480 city_map_iterate(result->city_radius_sq, cindex, x, y) {
2481 if (is_free_worked_index(cindex)) {
2482 city_map_data[cindex] = 2;
2483 } else if (result->worker_positions[cindex]) {
2484 city_map_data[cindex] = 1;
2485 } else {
2486 city_map_data[cindex] = 0;
2487 }
2489 log_test("workers map (2: free worked; 1: worker; 0: not used):");
2492
2493 log_test(" (workers/specialists) %d/%s", cm_result_workers(result),
2495
2497 log_test(" %10s surplus=%d", get_output_name(i), result->surplus[i]);
2499}
bool base_city_celebrating(const struct city *pcity)
Definition city.c:1637
bool is_free_worked(const struct city *pcity, const struct tile *ptile)
Definition city.c:3641
int city_granary_size(int city_size)
Definition city.c:2132
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)
Definition city.c:305
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Definition city.c:1065
bool city_tile_index_to_xy(int *city_map_x, int *city_map_y, int city_tile_index, int city_radius_sq)
Definition city.c:101
citizens player_content_citizens(const struct player *pplayer)
Definition city.c:2186
void citylog_map_data(enum log_level level, int radius_sq, int *map_data)
Definition city.c:411
bool city_unhappy(const struct city *pcity)
Definition city.c:1626
void set_city_production(struct city *pcity)
Definition city.c:2953
const char * get_output_name(Output_type_id output)
Definition city.c:629
void city_refresh_from_main_map(const struct civ_map *nmap, struct city *pcity, bool *workers_map)
Definition city.c:3201
bool city_happy(const struct city *pcity)
Definition city.c:1614
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
citizens city_specialists(const struct city *pcity)
Definition city.c:3343
static int cmp(int v1, int v2)
Definition city.c:325
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
Definition city.c:1283
int city_map_tiles(int city_radius_sq)
Definition city.c:171
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1456
#define city_tile(_pcity_)
Definition city.h:564
#define city_tile_iterate_index(_nmap, _radius_sq, _city_tile, _tile, _index)
Definition city.h:199
#define CITY_MAP_MAX_RADIUS_SQ
Definition city.h:84
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_tile_iterate_index_end
Definition city.h:207
#define output_type_iterate(output)
Definition city.h:846
#define city_owner(_pcity_)
Definition city.h:563
#define city_tile_iterate(_nmap, _radius_sq, _city_tile, _tile)
Definition city.h:228
#define city_map_iterate_end
Definition city.h:175
#define city_map_iterate(_radius_sq, _index, _x, _y)
Definition city.h:171
#define city_tile_iterate_end
Definition city.h:236
#define is_free_worked_index(city_tile_index)
Definition city.h:881
#define city_map_tiles_from_city(_pcity)
Definition city.h:125
#define output_type_iterate_end
Definition city.h:852
void cm_init_citymap(void)
Definition cm.c:314
static void convert_solution_to_result(struct cm_state *state, const struct partial_solution *soln, struct cm_result *result)
Definition cm.c:827
static void sort_lattice_by_fitness(const struct cm_state *state, struct tile_type_vector *lattice)
Definition cm.c:1215
static double estimate_fitness(const struct cm_state *state, const int production[])
Definition cm.c:1770
static void get_tax_rates(const struct player *pplayer, int rates[])
Definition cm.c:1740
static int specialists_in_solution(const struct cm_state *state, const struct partial_solution *soln)
Definition cm.c:1564
static void begin_search(struct cm_state *state, const struct cm_parameter *parameter, bool negative_ok)
Definition cm.c:1986
static int min_food_surplus_for_fastest_growth(struct cm_state *state)
Definition cm.c:1934
static int next_choice(struct cm_state *state, int oldchoice, bool negative_ok)
Definition cm.c:1412
static void tile_type_destroy(struct cm_tile_type *type)
Definition cm.c:412
#define LOG_TIME_STATS
Definition cm.c:95
static struct cm_fitness compute_fitness(const int surplus[], bool disorder, bool happy, const struct cm_parameter *parameter)
Definition cm.c:613
static void init_partial_solution(struct partial_solution *into, int ntypes, int idle, bool negative_ok)
Definition cm.c:652
static void complete_solution(struct partial_solution *soln, const struct cm_state *state, const struct tile_type_vector *lattice)
Definition cm.c:1512
static const struct cm_tile * tile_get(const struct cm_tile_type *ptype, int j)
Definition cm.c:571
static struct cm_fitness worst_fitness(void)
Definition cm.c:600
static bool take_child_choice(struct cm_state *state, bool negative_ok)
Definition cm.c:1478
static void compute_tile_production(const struct city *pcity, const struct tile *ptile, struct cm_tile_type *out)
Definition cm.c:962
void cm_clear_cache(struct city *pcity)
Definition cm.c:322
static const struct cm_tile_type * tile_type_get(const struct cm_state *state, int type)
Definition cm.c:554
#define LOG_LATTICE
Definition cm.c:97
static Output_type_id compare_key
Definition cm.c:915
static struct cm_fitness evaluate_solution(struct cm_state *state, const struct partial_solution *soln)
Definition cm.c:788
static int tile_type_vector_find_equivalent(const struct tile_type_vector *vec, const struct cm_tile_type *ptype)
Definition cm.c:509
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2176
static bool choice_stack_empty(struct cm_state *state)
Definition cm.c:1283
static void tile_type_vector_free_all(struct tile_type_vector *vec)
Definition cm.c:425
static struct cm_state * cm_state_init(struct city *pcity, bool negative_ok)
Definition cm.c:1862
static struct cm_tile_type * tile_type_dup(const struct cm_tile_type *oldtype)
Definition cm.c:397
static bool prereqs_filled(const struct partial_solution *soln, int type, const struct cm_state *state)
Definition cm.c:1394
static void clean_lattice(struct tile_type_vector *lattice, const struct city *pcity)
Definition cm.c:1160
void cm_init_parameter(struct cm_parameter *dest)
Definition cm.c:2185
static int tile_type_num_prereqs(const struct cm_tile_type *ptype)
Definition cm.c:544
static void copy_partial_solution(struct partial_solution *dst, const struct partial_solution *src, const struct cm_state *state)
Definition cm.c:681
static void cm_state_free(struct cm_state *state)
Definition cm.c:2035
static int compare_tile_type_by_fitness(const void *va, const void *vb)
Definition cm.c:892
struct cm_result * cm_result_new(struct city *pcity)
Definition cm.c:345
static void destroy_partial_solution(struct partial_solution *into)
Definition cm.c:671
int cm_result_specialists(const struct cm_result *result)
Definition cm.c:2240
#define print_partial_solution(loglevel, soln, state)
Definition cm.c:277
void cm_result_from_main_map(struct cm_result *result, const struct city *pcity)
Definition cm.c:2263
#define print_lattice(loglevel, lattice)
Definition cm.c:276
static bool tile_type_equal(const struct cm_tile_type *a, const struct cm_tile_type *b)
Definition cm.c:441
static void tile_type_init(struct cm_tile_type *type)
Definition cm.c:385
static void cm_result_copy(struct cm_result *result, const struct city *pcity, bool *workers_map)
Definition cm.c:2274
#define tile_type_vector_iterate(vector, var)
Definition cm.c:149
#define LOG_REACHED_LEAF
Definition cm.c:98
static void add_worker(struct partial_solution *soln, int itype, const struct cm_state *state)
Definition cm.c:1365
static bool choice_is_promising(struct cm_state *state, int newchoice, bool negative_ok)
Definition cm.c:1661
bool cm_are_parameter_equal(const struct cm_parameter *const p1, const struct cm_parameter *const p2)
Definition cm.c:2143
static double compare_key_trade_bonus
Definition cm.c:916
static void init_tile_lattice(struct city *pcity, struct tile_type_vector *lattice)
Definition cm.c:1241
static bool take_sibling_choice(struct cm_state *state, bool negative_ok)
Definition cm.c:1450
static void cm_find_best_solution(struct cm_state *state, const struct cm_parameter *const parameter, struct cm_result *result, bool negative_ok)
Definition cm.c:2052
static void apply_solution(struct cm_state *state, const struct partial_solution *soln)
Definition cm.c:701
static void init_min_production(struct cm_state *state)
Definition cm.c:1725
void cm_result_destroy(struct cm_result *result)
Definition cm.c:368
void cm_print_result(const struct cm_result *result)
Definition cm.c:2471
static void end_search(struct cm_state *state)
Definition cm.c:2019
static int compare_tile_type_by_stat(const void *va, const void *vb)
Definition cm.c:924
static int tile_type_num_tiles(const struct cm_tile_type *type)
Definition cm.c:529
static bool fitness_better(struct cm_fitness a, struct cm_fitness b)
Definition cm.c:588
void cm_query_result(struct city *pcity, const struct cm_parameter *param, struct cm_result *result, bool negative_ok)
Definition cm.c:2124
static bool bb_next(struct cm_state *state, bool negative_ok)
Definition cm.c:1825
static void top_sort_lattice(struct tile_type_vector *lattice)
Definition cm.c:1061
static void get_city_surplus(const struct city *pcity, int surplus[], bool *disorder, bool *happy)
Definition cm.c:773
#define LOG_BETTER_LEAF
Definition cm.c:99
static void compute_max_stats_heuristic(const struct cm_state *state, const struct partial_solution *soln, int production[], int check_choice, bool negative_ok)
Definition cm.c:1589
static int last_choice(struct cm_state *state)
Definition cm.c:1291
#define print_tile_type(loglevel, ptype, prefix)
Definition cm.c:275
static int compare_tile_type_by_lattice_order(const struct cm_tile_type *a, const struct cm_tile_type *b)
Definition cm.c:862
static void remove_worker(struct partial_solution *soln, int itype, const struct cm_state *state)
Definition cm.c:1374
#define CPUHOG_CM_MAX_LOOP
Definition cm.c:82
void cm_init(void)
Definition cm.c:293
static int tile_type_better(const struct cm_tile_type *a, const struct cm_tile_type *b)
Definition cm.c:465
static void init_specialist_lattice_nodes(struct tile_type_vector *lattice, const struct city *pcity)
Definition cm.c:1032
static void add_workers(struct partial_solution *soln, int itype, int number, const struct cm_state *state)
Definition cm.c:1314
int cm_result_citizens(const struct cm_result *result)
Definition cm.c:2254
static void tile_type_lattice_add(struct tile_type_vector *lattice, const struct cm_tile_type *newtype, int tindex)
Definition cm.c:980
void cm_init_emergency_parameter(struct cm_parameter *dest)
Definition cm.c:2203
static void pop_choice(struct cm_state *state)
Definition cm.c:1384
#define LOG_PRUNE_BRANCH
Definition cm.c:100
static int num_types(const struct cm_state *state)
Definition cm.c:1303
#define tile_type_vector_iterate_end
Definition cm.c:154
#define LOG_CM_STATE
Definition cm.c:96
#define CM_MAX_LOOP
Definition cm.c:80
void cm_print_city(const struct city *pcity)
Definition cm.c:2433
int cm_result_workers(const struct cm_result *result)
Definition cm.c:2220
void cm_free(void)
Definition cm.c:330
struct timer * wall_timer
Definition cma_core.c:92
char * incite_cost
Definition comments.c:76
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2966
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
unsigned char citizens
Definition fc_types.h:248
int Specialist_type_id
Definition fc_types.h:235
@ O_SHIELD
Definition fc_types.h:102
@ O_FOOD
Definition fc_types.h:102
@ O_TRADE
Definition fc_types.h:102
@ O_SCIENCE
Definition fc_types.h:102
@ O_LUXURY
Definition fc_types.h:102
@ O_GOLD
Definition fc_types.h:102
@ O_LAST
Definition fc_types.h:102
enum output_type_id Output_type_id
Definition fc_types.h:238
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct government * government_of_player(const struct player *pplayer)
Definition government.c:116
GType type
Definition repodlgs.c:1313
static const int bufsz
Definition helpdlg.c:70
const char * name
Definition inputfile.c:127
void do_log(const char *file, const char *function, int line, bool print_from_where, enum log_level level, const char *message,...)
Definition log.c:514
#define fc_assert_ret(condition)
Definition log.h:192
#define log_warn(message,...)
Definition log.h:106
#define log_test
Definition log.h:137
#define fc_assert(condition)
Definition log.h:177
#define LOG_TEST
Definition log.h:140
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_base(level, message,...)
Definition log.h:95
log_level
Definition log.h:29
@ LOG_DEBUG
Definition log.h:35
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
static bool player_is_cpuhog(const struct player *pplayer)
Definition player.h:580
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
Specialist_type_id normal_specialist_count(void)
Definition specialist.c:79
const char * specialists_string(const citizens *specialist_list)
Definition specialist.c:252
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
Definition specialist.c:270
#define specialist_type_iterate_end
Definition specialist.h:85
#define specialist_type_iterate(sp)
Definition specialist.h:79
#define normal_specialist_type_iterate(sp)
Definition specialist.h:89
#define normal_specialist_type_iterate_end
Definition specialist.h:95
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
Definition city.h:318
int surplus[O_LAST]
Definition city.h:353
int city_radius_sq
Definition city.h:373
struct universal production
Definition city.h:394
bool happy
Definition city.h:462
struct packet_game_info info
Definition game.h:89
struct government * government_during_revolution
Definition game.h:94
int weighted
Definition cm.c:119
bool sufficient
Definition cm.c:120
bool allow_disorder
Definition cm.h:44
int factor[O_LAST]
Definition cm.h:47
bool max_growth
Definition cm.h:42
bool allow_specialists
Definition cm.h:45
bool require_happy
Definition cm.h:43
int minimal_surplus[O_LAST]
Definition cm.h:41
int happy_factor
Definition cm.h:48
Definition cm.h:52
bool found_a_valid
Definition cm.h:54
bool disorder
Definition cm.h:54
bool aborted
Definition cm.h:53
int surplus[O_LAST]
Definition cm.h:56
bool happy
Definition cm.h:54
bool * worker_positions
Definition cm.h:59
int city_radius_sq
Definition cm.h:58
citizens specialists[SP_MAX]
Definition cm.h:60
Definition cm.c:200
int size
Definition cm.c:231
struct partial_solution best
Definition cm.c:210
struct cm_parameter parameter
Definition cm.c:202
struct cm_state::@16 choice
int min_production[O_LAST]
Definition cm.c:217
struct tile_type_vector lattice
Definition cm.c:206
struct partial_solution current
Definition cm.c:223
struct tile_type_vector lattice_by_prod[O_LAST]
Definition cm.c:207
struct cm_fitness best_value
Definition cm.c:211
bool * workers_map
Definition cm.c:234
int min_luxury
Definition cm.c:220
struct city * pcity
Definition cm.c:203
int * stack
Definition cm.c:230
int production[O_LAST]
Definition cm.c:169
Specialist_type_id spec
Definition cm.c:172
struct tile_type_vector better_types
Definition cm.c:174
struct tile_vector tiles
Definition cm.c:173
bool is_specialist
Definition cm.c:171
int lattice_depth
Definition cm.c:177
int lattice_index
Definition cm.c:176
struct tile_type_vector worse_types
Definition cm.c:175
double estimated_fitness
Definition cm.c:170
Definition cm.c:135
const struct cm_tile_type * type
Definition cm.c:136
int index
Definition cm.c:137
int production[O_LAST]
Definition cm.c:191
int * worker_counts
Definition cm.c:188
int * prereqs_filled
Definition cm.c:189
struct player_economic economic
Definition player.h:284
Definition tile.h:50
int index
Definition tile.h:51
Definition timing.c:81
int id
Definition unit.h:147
struct tile * tile
Definition unit.h:142
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define bool
Definition support.h:71
#define tile_worked(_tile)
Definition tile.h:119
#define TILE_XY(ptile)
Definition tile.h:43
void timer_destroy(struct timer *t)
Definition timing.c:208
void timer_start(struct timer *t)
Definition timing.c:263
void timer_stop(struct timer *t)
Definition timing.c:305
struct timer * timer_new(enum timer_timetype type, enum timer_use use, const char *name)
Definition timing.c:160
double timer_read_seconds(struct timer *t)
Definition timing.c:379
@ TIMER_ACTIVE
Definition timing.h:46
@ TIMER_USER
Definition timing.h:42