Freeciv-3.2: /fast/freeciv/nightly/S3_2/common/aicore/caravan.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
caravan.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 <math.h>
19
20/* utility */
21#include "log.h"
22
23/* common */
24#include "game.h"
25#include "traderoutes.h"
26
27/* aicore */
28#include "path_finding.h"
29#include "pf_tools.h"
30
31#include "caravan.h"
32
33/************************************************************************/
36 void caravan_parameter_init_default(struct caravan_parameter *parameter)
37{
38 parameter->horizon = FC_INFINITY;
39 parameter->discount = 0.95;
40 parameter->consider_windfall = TRUE;
41 parameter->consider_trade = TRUE;
42 parameter->consider_wonders = TRUE; /* see also init_from_unit */
43 parameter->account_for_broken_routes = TRUE;
44 parameter->allow_foreign_trade = FTL_NATIONAL_ONLY;
45 parameter->ignore_transit_time = FALSE;
46 parameter->convert_trade = FALSE;
47 parameter->callback = NULL;
48}
49
50/************************************************************************/
53 void caravan_parameter_init_from_unit(struct caravan_parameter *parameter,
54 const struct unit *caravan)
55{
56 caravan_parameter_init_default(parameter);
57 if (!unit_can_do_action(caravan, ACTION_TRADE_ROUTE)) {
58 parameter->consider_trade = FALSE;
59 }
60 if (!unit_can_do_action(caravan, ACTION_MARKETPLACE)
61 && !unit_can_do_action(caravan, ACTION_TRADE_ROUTE)) {
62 parameter->consider_windfall = FALSE;
63 }
64 if (!unit_can_do_action(caravan, ACTION_HELP_WONDER)) {
65 parameter->consider_wonders = FALSE;
66 }
67}
68
69/************************************************************************/
72 bool caravan_parameter_is_legal(const struct caravan_parameter *parameter)
73{
74 /* a discount > 1.0 means money later is worth more than money now,
75 which is ridiculous. */
76 if (parameter->discount > 1.0) {
77 return FALSE;
78 }
79
80 /* a negative discount doesn't converge */
81 if (parameter->discount < 0.0) {
82 return FALSE;
83 }
84
85 /* infinite horizon with no discount gives infinite reward. */
86 if (parameter->horizon == FC_INFINITY && parameter->discount == 1.0) {
87 return FALSE;
88 }
89
90 return TRUE;
91}
92
93/************************************************************************/
96 static const char *ftl_name(enum foreign_trade_limit ftl)
97{
98 switch (ftl) {
99 case FTL_NATIONAL_ONLY:
100 return "no";
101 case FTL_ALLIED:
102 return "allied";
103 case FTL_PEACEFUL:
104 return "peaceful";
105 case FTL_NONWAR:
106 return "anything but enemies";
107 }
108
109 return "<illegal>";
110}
111
112/************************************************************************/
115 void caravan_parameter_log_real(const struct caravan_parameter *parameter,
116 enum log_level level, const char *file,
117 const char *function, int line)
118{
119 do_log(file, function, line, FALSE, level,
120 "parameter {\n"
121 " horizon = %d\n"
122 " discount = %g\n"
123 " objective = <%s,%s,%s>\n"
124 " account-broken = %s\n"
125 " allow-foreign = %s\n"
126 " ignore-transit = %s\n"
127 " convert-trade = %s\n"
128 "}\n",
129 parameter->horizon,
130 parameter->discount,
131 parameter->consider_windfall ? "windfall" : "-",
132 parameter->consider_trade ? "trade" : "-",
133 parameter->consider_wonders ? "wonders" : "-",
134 parameter->account_for_broken_routes ? "yes" : "no",
135 ftl_name(parameter->allow_foreign_trade),
136 parameter->ignore_transit_time ? "yes" : "no",
137 parameter->convert_trade ? "yes" : "no");
138}
139
140
141/************************************************************************/
144 void caravan_result_init_zero(struct caravan_result *result)
145{
146 result->src = result->dest = NULL;
147 result->arrival_time = 0;
148 result->value = 0;
149 result->help_wonder = FALSE;
150 result->required_boat = FALSE;
151}
152
153/************************************************************************/
157 static void caravan_result_init(struct caravan_result *result,
158 const struct city *src,
159 const struct city *dest,
160 int arrival_time)
161{
162 result->src = src;
163 result->dest = dest;
164 result->arrival_time = arrival_time;
165
166 result->value = 0;
167 result->help_wonder = FALSE;
168 /* FIXME: required_boat field is never used. */
169 if ((src != NULL) && (dest != NULL)) {
170 if (tile_continent(src->tile) != tile_continent(dest->tile)) {
171 result->required_boat = TRUE;
172 } else {
173 result->required_boat = FALSE;
174 }
175 } else {
176 result->required_boat = FALSE;
177 }
178}
179
180/************************************************************************/
183 int caravan_result_compare(const struct caravan_result *a,
184 const struct caravan_result *b)
185{
186 if (a->value > b->value) {
187 return 1;
188 } else if (a->value < b->value) {
189 return -1;
190 } else {
191 /* faster time is better, so reverse-sort on time. */
192 return b->arrival_time - a->arrival_time ;
193 }
194}
195
196/************************************************************************/
204 typedef bool (*search_callback) (void *data, const struct city *pcity,
205 int arrival_turn, int arrival_moves_left);
206
207 static void caravan_search_from(const struct civ_map *nmap,
208 const struct unit *caravan,
209 const struct caravan_parameter *param,
210 struct tile *start_tile,
211 int turns_before, int moves_left_before,
212 bool omniscient,
213 search_callback callback,
214 void *callback_data)
215{
216 struct pf_map *pfm;
217 struct pf_parameter pfparam;
218 int end_time;
219
220 end_time = param->horizon - turns_before;
221
222 /* Initialize the pf run. */
223 pft_fill_unit_parameter(&pfparam, nmap, (struct unit *) caravan);
224 pfparam.start_tile = start_tile;
225 pfparam.moves_left_initially = moves_left_before;
226 pfparam.omniscience = omniscient;
227 pfm = pf_map_new(&pfparam);
228
229 /* For every tile in distance order:
230 quit if we've exceeded the maximum number of turns
231 otherwise, run the callback if we're on a city.
232 Do-while loop rather than while loop to make sure to process the
233 start tile.
234 */
235 pf_map_positions_iterate(pfm, pos, TRUE) {
236 struct city *pcity;
237
238 if (pos.turn > end_time) {
239 break;
240 }
241
242 pcity = tile_city(pos.tile);
243 if (pcity && callback(callback_data, pcity, turns_before + pos.turn,
244 pos.moves_left)) {
245 break;
246 }
247 } pf_map_positions_iterate_end;
248
249 pf_map_destroy(pfm);
250}
251
252/************************************************************************/
256 static double windfall_benefit(const struct unit *caravan,
257 const struct city *src,
258 const struct city *dest,
259 const struct caravan_parameter *param)
260{
261 if (!param->consider_windfall || !can_cities_trade(src, dest)) {
262 return 0;
263 } else {
264 bool can_establish = (unit_can_do_action(caravan, ACTION_TRADE_ROUTE)
265 && can_establish_trade_route(src, dest));
266 int bonus = get_caravan_enter_city_trade_bonus(src, dest,
267 unit_type_get(caravan),
268 NULL, can_establish);
269
270 /* when bonus goes to both sci and gold, double it */
271 if (TBONUS_BOTH == trade_route_settings_by_type
272 (cities_trade_route_type(src, dest))->bonus_type) {
273 bonus *= 2;
274 }
275
276 return bonus;
277 }
278}
279
280/****************************************************************************
281 Compute the change in the per-turn trade.
282****************************************************************************/
283
284/************************************************************************/
288 static int one_city_trade_benefit(const struct city *pcity,
289 const struct player *pplayer,
290 bool countloser, int newtrade)
291{
292 int losttrade = 0;
293
294 /* if the city is owned by someone else, we don't benefit from the
295 new trade (but we might still lose from a broken trade route) */
296 if (city_owner(pcity) != pplayer) {
297 newtrade = 0;
298 }
299
300 if (city_num_trade_routes(pcity) < max_trade_routes(pcity)) {
301 /* if the city can handle this route, we don't break any old routes */
302 losttrade = 0;
303 } else {
304 struct trade_route_list *would_remove = (countloser ? trade_route_list_new() : NULL);
305 int oldtrade = city_trade_removable(pcity, would_remove);
306
307 /* if we own the city, the trade benefit is only by how much
308 better we are than the old trade route */
309 if (city_owner(pcity) == pplayer) {
310 newtrade -= oldtrade;
311 }
312
313 /* if the cities that lost a trade route is one of ours, and if we
314 care about accounting for the lost trade, count it. */
315 if (countloser) {
316 trade_route_list_iterate(would_remove, plost) {
317 struct city *losercity = game_city_by_number(plost->partner);
318
319 if (city_owner(losercity) == pplayer) {
320 trade_routes_iterate(losercity, pback) {
321 if (pback->partner == pcity->id) {
322 losttrade += pback->value;
323 }
324 } trade_routes_iterate_end;
325 }
326 } trade_route_list_iterate_end;
327 trade_route_list_destroy(would_remove);
328 }
329 }
330
331 /* find the increase or decrease in trade we benefit from */
332 return newtrade - losttrade;
333}
334
335/************************************************************************/
340 static double trade_benefit(const struct player *caravan_owner,
341 const struct city *src,
342 const struct city *dest,
343 const struct caravan_parameter *param)
344{
345 /* do we care about trade at all? */
346 if (!param->consider_trade) {
347 return 0;
348 }
349
350 /* first, see if a new route is made. */
351 if (!can_cities_trade(src, dest) || !can_establish_trade_route(src, dest)) {
352 return 0;
353 }
354 if (max_trade_routes(src) <= 0 || max_trade_routes(dest) <= 0) {
355 /* Can't create new trade routes even by replacing old ones if
356 * there's no slots at all. */
357 return 0;
358 }
359
360 if (!param->convert_trade) {
361 bool countloser = param->account_for_broken_routes;
362 int newtrade = trade_base_between_cities(src, dest);
363
364 return one_city_trade_benefit(src, caravan_owner, countloser, newtrade)
365 + one_city_trade_benefit(dest, caravan_owner, countloser, newtrade);
366 } else {
367 /* Always fails. */
368 fc_assert_msg(!param->convert_trade,
369 "Unimplemented functionality: "
370 "using CM to calculate trade.");
371 return 0;
372 }
373}
374
375/************************************************************************/
382 static double wonder_benefit(const struct unit *caravan, int arrival_time,
383 const struct city *dest,
384 const struct caravan_parameter *param)
385{
386 int costwithout, costwith;
387 int shields_at_arrival;
388
389 if (!param->consider_wonders
390 /* TODO: Should helping an ally to build be considered when legal? */
391 || unit_owner(caravan) != city_owner(dest)
392 || !city_production_gets_caravan_shields(&dest->production)
393 /* TODO: Should helping to build a unit be considered when legal? */
394 || VUT_UTYPE == dest->production.kind
395 /* TODO: Should helping to build an improvement be considered when
396 * legal? */
397 || !is_wonder(dest->production.value.building)) {
398 return 0;
399 }
400
401 shields_at_arrival = dest->shield_stock
402 + arrival_time * dest->surplus[O_SHIELD];
403
404 costwithout = impr_buy_gold_cost(dest, dest->production.value.building,
405 shields_at_arrival);
406 costwith = impr_buy_gold_cost(dest, dest->production.value.building,
407 shields_at_arrival + unit_build_shield_cost_base(caravan));
408
409 fc_assert_ret_val(costwithout >= costwith, -1.0);
410 return costwithout - costwith;
411}
412
413/************************************************************************/
417 static double presentvalue(double payment, int term, double rate)
418{
419 return payment * pow(rate, term);
420}
421
422/************************************************************************/
426 static double perpetuity(double payment, double rate)
427{
428 return payment / (1.0 - rate);
429}
430
431/************************************************************************/
435 static double annuity(double payment, int term, double rate)
436{
437 return perpetuity(payment, rate) * (1.0 - 1.0 / pow(rate, term));
438}
439
440/************************************************************************/
443 static bool does_foreign_trade_param_allow(const struct caravan_parameter *param,
444 struct player *src, struct player *dest)
445{
446 switch (param->allow_foreign_trade) {
447 case FTL_NATIONAL_ONLY:
448 return (src == dest);
449 break;
450 case FTL_ALLIED:
451 return pplayers_allied(src, dest);
452 break;
453 case FTL_PEACEFUL:
454 return pplayers_in_peace(src, dest);
455 break;
456 case FTL_NONWAR:
457 return !pplayers_at_war(src, dest);
458 }
459
460 fc_assert(FALSE);
461 return FALSE;
462}
463
464/************************************************************************/
470 static bool get_discounted_reward(const struct unit *caravan,
471 const struct caravan_parameter *parameter,
472 struct caravan_result *result)
473{
474 double trade;
475 double windfall;
476 double wonder;
477 const struct city *src = result->src;
478 const struct city *dest = result->dest;
479 int arrival_time = result->arrival_time;
480 double discount = parameter->discount;
481 struct player *pplayer_src = city_owner(src);
482 struct player *pplayer_dest = city_owner(dest);
483 int cost = unit_build_shield_cost(src, caravan);
484 bool consider_wonder;
485 bool consider_trade;
486 bool consider_windfall;
487
488 /* if no foreign trade is allowed, just quit. */
489 if (!does_foreign_trade_param_allow(parameter, pplayer_src, pplayer_dest)) {
490 caravan_result_init_zero(result);
491 return FALSE;
492 }
493
494 consider_wonder = parameter->consider_wonders
495 && action_prob_possible(
496 action_speculate_unit_on_city(ACTION_HELP_WONDER,
497 caravan, src, city_tile(dest),
498 TRUE, dest));
499 consider_trade = parameter->consider_trade
500 && action_prob_possible(
501 action_speculate_unit_on_city(ACTION_TRADE_ROUTE,
502 caravan, src, city_tile(dest),
503 TRUE, dest));
504 consider_windfall = parameter->consider_windfall
505 && action_prob_possible(
506 action_speculate_unit_on_city(ACTION_MARKETPLACE,
507 caravan, src, city_tile(dest),
508 TRUE, dest));
509
510 if (!consider_wonder && !consider_trade && !consider_windfall) {
511 /* No caravan action is possible against this target. */
512 caravan_result_init_zero(result);
513
514 return FALSE;
515 }
516
517 if (consider_wonder) {
518 wonder = wonder_benefit(caravan, arrival_time, dest, parameter);
519 /* we want to aid for wonder building */
520 wonder *= 2;
521
522 wonder = presentvalue(wonder, arrival_time, discount);
523 } else {
524 wonder = -1.0;
525 }
526
527 if (consider_trade) {
528 trade = trade_benefit(pplayer_src, src, dest, parameter);
529 if (parameter->horizon == FC_INFINITY) {
530 trade = perpetuity(trade, discount);
531 } else {
532 trade = annuity(trade, parameter->horizon - arrival_time, discount);
533 }
534 trade = presentvalue(trade, arrival_time, discount);
535 } else {
536 trade = 0.0;
537 }
538
539 if (consider_windfall) {
540 windfall = windfall_benefit(caravan, src, dest, parameter);
541 windfall = presentvalue(windfall, arrival_time, discount);
542 } else {
543 windfall = 0.0;
544 }
545
546 if ((consider_trade
547 || (consider_windfall
548 && (!parameter->consider_trade /* can only enter marketplaces */
549 /* (FIXME: test any extra restrictions for trade routes) */
550 /* or the result is so big that we are still in plus */
551 /* (consider having produced IF_GOLD instead) */
552 || windfall
553 >= presentvalue(cost, -cost
554 / MAX(src->surplus[O_SHIELD], 2), discount)))
555 ) && trade + windfall >= wonder) {
556 result->value = trade + windfall;
557 result->help_wonder = FALSE;
558 } else if (consider_wonder) {
559 result->value = wonder;
560 result->help_wonder = TRUE;
561 } else {
562 caravan_result_init_zero(result);
563 return FALSE;
564 }
565
566 if (parameter->callback) {
567 parameter->callback(result, parameter->callback_data);
568 }
569
570 return TRUE;
571}
572
573/****************************************************************************
574 Functions to compute the benefit of moving the caravan to dest.
575****************************************************************************/
576
577/************************************************************************/
581 static void caravan_evaluate_notransit(const struct unit *caravan,
582 const struct city *dest,
583 const struct caravan_parameter *param,
584 struct caravan_result *result)
585{
586 const struct city *src = game_city_by_number(caravan->homecity);
587
588 caravan_result_init(result, src, dest, 0);
589 get_discounted_reward(caravan, param, result);
590}
591
592/************************************************************************/
596 struct cewt_data {
597 const struct unit *caravan;
598 struct caravan_result *result;
599 const struct caravan_parameter *param;
600};
601
602 static bool cewt_callback(void *vdata, const struct city *dest,
603 int arrival_time, int moves_left)
604{
605 struct cewt_data *data = vdata;
606
607 fc_assert_ret_val(data->result, FALSE);
608
609 if (dest == data->result->dest) {
610 data->result->arrival_time = arrival_time;
611 get_discounted_reward(data->caravan, data->param, data->result);
612 return TRUE;
613 } else {
614 return FALSE;
615 }
616}
617
618/************************************************************************/
622 static void caravan_evaluate_withtransit(const struct civ_map *nmap,
623 const struct unit *caravan,
624 const struct city *dest,
625 const struct caravan_parameter *param,
626 struct caravan_result *result,
627 bool omniscient)
628{
629 struct cewt_data data;
630
631 data.caravan = caravan;
632 data.param = param;
633 caravan_result_init(result, game_city_by_number(caravan->homecity),
634 dest, 0);
635 data.result = result;
636 caravan_search_from(nmap, caravan, param, unit_tile(caravan), 0,
637 caravan->moves_left, omniscient, cewt_callback, &data);
638}
639
640/************************************************************************/
643 void caravan_evaluate(const struct unit *caravan,
644 const struct city *dest,
645 const struct caravan_parameter *param,
646 struct caravan_result *result, bool omniscient)
647{
648 const struct civ_map *nmap = &(wld.map);
649
650 if (param->ignore_transit_time) {
651 caravan_evaluate_notransit(caravan, dest, param, result);
652 } else {
653 caravan_evaluate_withtransit(nmap, caravan, dest, param, result, omniscient);
654 }
655}
656
657
658/************************************************************************/
661 static void caravan_find_best_destination_notransit(const struct unit *caravan,
662 const struct caravan_parameter *param,
663 struct caravan_result *best)
664{
665 struct caravan_result current;
666 struct city *pcity = game_city_by_number(caravan->homecity);
667 struct player *src_owner = city_owner(pcity);
668
669 caravan_result_init(best, pcity, NULL, 0);
670 current = *best;
671
672 players_iterate(dest_owner) {
673 if (does_foreign_trade_param_allow(param, src_owner, dest_owner)) {
674 city_list_iterate(dest_owner->cities, dest) {
675 caravan_result_init(&current, pcity, dest, 0);
676 get_discounted_reward(caravan, param, &current);
677
678 if (caravan_result_compare(&current, best) > 0) {
679 *best = current;
680 }
681 } city_list_iterate_end;
682 }
683 } players_iterate_end;
684}
685
686/************************************************************************/
690 struct cfbdw_data {
691 const struct caravan_parameter *param;
692 const struct unit *caravan;
693 struct caravan_result *best;
694};
695
696 static bool cfbdw_callback(void *vdata, const struct city *dest,
697 int arrival_time, int moves_left)
698{
699 struct cfbdw_data *data = vdata;
700 struct caravan_result current;
701
702 caravan_result_init(&current, data->best->src, dest, arrival_time);
703
704 get_discounted_reward(data->caravan, data->param, &current);
705 if (caravan_result_compare(&current, data->best) > 0) {
706 *data->best = current;
707 }
708
709 return FALSE; /* don't stop. */
710}
711
712/************************************************************************/
715 static void caravan_find_best_destination_withtransit(
716 const struct civ_map *nmap,
717 const struct unit *caravan,
718 const struct caravan_parameter *param,
719 const struct city *src,
720 int turns_before,
721 int moves_left,
722 bool omniscient,
723 struct caravan_result *result)
724{
725 struct tile *start_tile;
726 struct cfbdw_data data;
727
728 data.param = param;
729 data.caravan = caravan;
730 data.best = result;
731 caravan_result_init(data.best, src, NULL, 0);
732
733 if (src->id != caravan->homecity) {
734 start_tile = src->tile;
735 } else {
736 start_tile = unit_tile(caravan);
737 }
738
739 caravan_search_from(nmap, caravan, param, start_tile, turns_before,
740 caravan->moves_left, omniscient, cfbdw_callback, &data);
741}
742
743/************************************************************************/
748 void caravan_find_best_destination(const struct civ_map *nmap,
749 const struct unit *caravan,
750 const struct caravan_parameter *parameter,
751 struct caravan_result *result, bool omniscient)
752{
753 if (parameter->ignore_transit_time) {
754 caravan_find_best_destination_notransit(caravan, parameter, result);
755 } else {
756 const struct city *src = game_city_by_number(caravan->homecity);
757
758 fc_assert(src != NULL);
759
760 caravan_find_best_destination_withtransit(nmap, caravan, parameter, src, 0,
761 caravan->moves_left, omniscient, result);
762 }
763}
764
765/************************************************************************/
768 static void caravan_optimize_notransit(const struct unit *caravan,
769 const struct caravan_parameter *param,
770 struct caravan_result *best)
771{
772 struct player *pplayer = unit_owner(caravan);
773
774 /* Iterate over all cities we own (since the caravan could change its
775 * home city); iterate over all cities we know about (places the caravan
776 * can go to); pick out the best trade route. */
777 city_list_iterate(pplayer->cities, src) {
778 players_iterate(dest_owner) {
779 if (does_foreign_trade_param_allow(param, pplayer, dest_owner)) {
780 city_list_iterate(dest_owner->cities, dest) {
781 struct caravan_result current;
782
783 caravan_result_init(&current, src, dest, 0);
784 get_discounted_reward(caravan, param, &current);
785 if (caravan_result_compare(&current, best) > 0) {
786 *best = current;
787 }
788 } city_list_iterate_end;
789 }
790 } players_iterate_end;
791 } city_list_iterate_end;
792}
793
794/****************************************************************************
795 Struct for the caravan_search invocation in
796 caravan_optimize_withtransit.
797****************************************************************************/
798 struct cowt_data {
799 const struct caravan_parameter *param;
800 const struct unit *caravan;
801 struct caravan_result *best;
802 bool omniscient;
803};
804
805/************************************************************************/
812 static bool cowt_callback(void *vdata, const struct city *pcity,
813 int arrival_time, int moves_left)
814{
815 struct cowt_data *data = vdata;
816 const struct unit *caravan = data->caravan;
817 struct caravan_result current;
818 const struct civ_map *nmap = &(wld.map);
819
820 caravan_result_init(&current, game_city_by_number(caravan->homecity),
821 pcity, arrival_time);
822
823 /* first, see what benefit we'd get from not changing home city */
824 get_discounted_reward(caravan, data->param, &current);
825 if (caravan_result_compare(&current, data->best) > 0) {
826 *data->best = current;
827 }
828
829 /* next, try changing home city (if we're allowed to) */
830 if (city_owner(pcity) == unit_owner(caravan)) {
831 caravan_find_best_destination_withtransit(
832 nmap, caravan, data->param, pcity, arrival_time, moves_left, data->omniscient,
833 &current);
834 if (caravan_result_compare(&current, data->best) > 0) {
835 *data->best = current;
836 }
837 }
838
839 return FALSE; /* don't stop searching */
840}
841
842/************************************************************************/
846 static void caravan_optimize_withtransit(const struct civ_map *nmap,
847 const struct unit *caravan,
848 const struct caravan_parameter *param,
849 struct caravan_result *result,
850 bool omniscient)
851{
852 struct cowt_data data;
853
854 data.param = param;
855 data.caravan = caravan;
856 data.best = result;
857 data.omniscient = omniscient;
858 caravan_result_init_zero(data.best);
859 caravan_search_from(nmap, caravan, param, unit_tile(caravan), 0,
860 caravan->moves_left, omniscient, cowt_callback, &data);
861}
862
863/************************************************************************/
868 void caravan_optimize_allpairs(const struct unit *caravan,
869 const struct caravan_parameter *param,
870 struct caravan_result *result, bool omniscient)
871{
872 const struct civ_map *nmap = &(wld.map);
873
874 if (param->ignore_transit_time) {
875 caravan_optimize_notransit(caravan, param, result);
876 } else {
877 caravan_optimize_withtransit(nmap, caravan, param, result, omniscient);
878 }
879}
action_prob_possible
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5823
action_speculate_unit_on_city
struct act_prob action_speculate_unit_on_city(const action_id act_id, const struct unit *actor, const struct city *actor_home, const struct tile *actor_tile, const bool omniscient_cheat, const struct city *target)
Definition actions.c:5575
wonder_benefit
static double wonder_benefit(const struct unit *caravan, int arrival_time, const struct city *dest, const struct caravan_parameter *param)
Definition caravan.c:382
perpetuity
static double perpetuity(double payment, double rate)
Definition caravan.c:426
caravan_find_best_destination
void caravan_find_best_destination(const struct civ_map *nmap, const struct unit *caravan, const struct caravan_parameter *parameter, struct caravan_result *result, bool omniscient)
Definition caravan.c:748
does_foreign_trade_param_allow
static bool does_foreign_trade_param_allow(const struct caravan_parameter *param, struct player *src, struct player *dest)
Definition caravan.c:443
search_callback
bool(* search_callback)(void *data, const struct city *pcity, int arrival_turn, int arrival_moves_left)
Definition caravan.c:204
caravan_search_from
static void caravan_search_from(const struct civ_map *nmap, const struct unit *caravan, const struct caravan_parameter *param, struct tile *start_tile, int turns_before, int moves_left_before, bool omniscient, search_callback callback, void *callback_data)
Definition caravan.c:207
caravan_parameter_is_legal
bool caravan_parameter_is_legal(const struct caravan_parameter *parameter)
Definition caravan.c:72
caravan_find_best_destination_notransit
static void caravan_find_best_destination_notransit(const struct unit *caravan, const struct caravan_parameter *param, struct caravan_result *best)
Definition caravan.c:661
caravan_evaluate_notransit
static void caravan_evaluate_notransit(const struct unit *caravan, const struct city *dest, const struct caravan_parameter *param, struct caravan_result *result)
Definition caravan.c:581
one_city_trade_benefit
static int one_city_trade_benefit(const struct city *pcity, const struct player *pplayer, bool countloser, int newtrade)
Definition caravan.c:288
caravan_optimize_withtransit
static void caravan_optimize_withtransit(const struct civ_map *nmap, const struct unit *caravan, const struct caravan_parameter *param, struct caravan_result *result, bool omniscient)
Definition caravan.c:846
caravan_result_init_zero
void caravan_result_init_zero(struct caravan_result *result)
Definition caravan.c:144
caravan_optimize_notransit
static void caravan_optimize_notransit(const struct unit *caravan, const struct caravan_parameter *param, struct caravan_result *best)
Definition caravan.c:768
annuity
static double annuity(double payment, int term, double rate)
Definition caravan.c:435
ftl_name
static const char * ftl_name(enum foreign_trade_limit ftl)
Definition caravan.c:96
caravan_evaluate_withtransit
static void caravan_evaluate_withtransit(const struct civ_map *nmap, const struct unit *caravan, const struct city *dest, const struct caravan_parameter *param, struct caravan_result *result, bool omniscient)
Definition caravan.c:622
cfbdw_callback
static bool cfbdw_callback(void *vdata, const struct city *dest, int arrival_time, int moves_left)
Definition caravan.c:696
caravan_result_compare
int caravan_result_compare(const struct caravan_result *a, const struct caravan_result *b)
Definition caravan.c:183
caravan_find_best_destination_withtransit
static void caravan_find_best_destination_withtransit(const struct civ_map *nmap, const struct unit *caravan, const struct caravan_parameter *param, const struct city *src, int turns_before, int moves_left, bool omniscient, struct caravan_result *result)
Definition caravan.c:715
caravan_parameter_log_real
void caravan_parameter_log_real(const struct caravan_parameter *parameter, enum log_level level, const char *file, const char *function, int line)
Definition caravan.c:115
caravan_evaluate
void caravan_evaluate(const struct unit *caravan, const struct city *dest, const struct caravan_parameter *param, struct caravan_result *result, bool omniscient)
Definition caravan.c:643
get_discounted_reward
static bool get_discounted_reward(const struct unit *caravan, const struct caravan_parameter *parameter, struct caravan_result *result)
Definition caravan.c:470
trade_benefit
static double trade_benefit(const struct player *caravan_owner, const struct city *src, const struct city *dest, const struct caravan_parameter *param)
Definition caravan.c:340
cowt_callback
static bool cowt_callback(void *vdata, const struct city *pcity, int arrival_time, int moves_left)
Definition caravan.c:812
caravan_parameter_init_default
void caravan_parameter_init_default(struct caravan_parameter *parameter)
Definition caravan.c:36
windfall_benefit
static double windfall_benefit(const struct unit *caravan, const struct city *src, const struct city *dest, const struct caravan_parameter *param)
Definition caravan.c:256
presentvalue
static double presentvalue(double payment, int term, double rate)
Definition caravan.c:417
cewt_callback
static bool cewt_callback(void *vdata, const struct city *dest, int arrival_time, int moves_left)
Definition caravan.c:602
caravan_parameter_init_from_unit
void caravan_parameter_init_from_unit(struct caravan_parameter *parameter, const struct unit *caravan)
Definition caravan.c:53
caravan_result_init
static void caravan_result_init(struct caravan_result *result, const struct city *src, const struct city *dest, int arrival_time)
Definition caravan.c:157
caravan_optimize_allpairs
void caravan_optimize_allpairs(const struct unit *caravan, const struct caravan_parameter *param, struct caravan_result *result, bool omniscient)
Definition caravan.c:868
caravan.h
foreign_trade_limit
foreign_trade_limit
Definition caravan.h:29
FTL_ALLIED
@ FTL_ALLIED
Definition caravan.h:31
FTL_NATIONAL_ONLY
@ FTL_NATIONAL_ONLY
Definition caravan.h:30
FTL_NONWAR
@ FTL_NONWAR
Definition caravan.h:33
FTL_PEACEFUL
@ FTL_PEACEFUL
Definition caravan.h:32
city_production_gets_caravan_shields
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1852
city_list_iterate
#define city_list_iterate(citylist, pcity)
Definition city.h:508
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_owner
#define city_owner(_pcity_)
Definition city.h:563
city_list_iterate_end
#define city_list_iterate_end
Definition city.h:510
incite_cost
char * incite_cost
Definition comments.c:74
cost
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 cost
Definition dialogs_g.h:74
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
wld
struct world wld
Definition game.c:63
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:107
game.h
pos
static struct tile * pos
Definition finddlg.c:53
impr_buy_gold_cost
int impr_buy_gold_cost(const struct city *pcity, const struct impr_type *pimprove, int shields_in_stock)
Definition improvement.c:306
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:343
do_log
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
log.h
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_level
log_level
Definition log.h:28
pf_map_new
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Definition path_finding.c:3182
pf_map_destroy
void pf_map_destroy(struct pf_map *pfm)
Definition path_finding.c:3206
path_finding.h
pf_map_positions_iterate_end
#define pf_map_positions_iterate_end
Definition path_finding.h:612
pf_map_positions_iterate
#define pf_map_positions_iterate(ARG_pfm, NAME_pos, COND_from_start)
Definition path_finding.h:605
pft_fill_unit_parameter
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:840
pf_tools.h
pplayers_at_war
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
pplayers_allied
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
pplayers_in_peace
bool pplayers_in_peace(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1426
players_iterate_end
#define players_iterate_end
Definition player.h:537
players_iterate
#define players_iterate(_pplayer)
Definition player.h:532
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
FC_INFINITY
#define FC_INFINITY
Definition shared.h:36
MAX
#define MAX(x, y)
Definition shared.h:54
callback
Definition gui_main.c:2404
caravan_parameter
Definition caravan.h:61
caravan_parameter::horizon
int horizon
Definition caravan.h:65
caravan_parameter::consider_trade
bool consider_trade
Definition caravan.h:86
caravan_parameter::convert_trade
bool convert_trade
Definition caravan.h:116
caravan_parameter::consider_windfall
bool consider_windfall
Definition caravan.h:85
caravan_parameter::callback
void(* callback)(const struct caravan_result *result, void *data)
Definition caravan.h:124
caravan_parameter::allow_foreign_trade
enum foreign_trade_limit allow_foreign_trade
Definition caravan.h:99
caravan_parameter::consider_wonders
bool consider_wonders
Definition caravan.h:87
caravan_parameter::ignore_transit_time
bool ignore_transit_time
Definition caravan.h:108
caravan_parameter::discount
double discount
Definition caravan.h:77
caravan_parameter::account_for_broken_routes
bool account_for_broken_routes
Definition caravan.h:93
caravan_parameter::callback_data
void * callback_data
Definition caravan.h:125
caravan_result
Definition caravan.h:51
caravan_result::src
const struct city * src
Definition caravan.h:52
caravan_result::dest
const struct city * dest
Definition caravan.h:53
caravan_result::arrival_time
int arrival_time
Definition caravan.h:54
caravan_result::help_wonder
bool help_wonder
Definition caravan.h:57
caravan_result::required_boat
bool required_boat
Definition caravan.h:58
caravan_result::value
double value
Definition caravan.h:56
cewt_data
Definition caravan.c:596
cewt_data::caravan
const struct unit * caravan
Definition caravan.c:597
cewt_data::param
const struct caravan_parameter * param
Definition caravan.c:599
cewt_data::result
struct caravan_result * result
Definition caravan.c:598
cfbdw_data
Definition caravan.c:690
cfbdw_data::best
struct caravan_result * best
Definition caravan.c:693
cfbdw_data::caravan
const struct unit * caravan
Definition caravan.c:692
cfbdw_data::param
const struct caravan_parameter * param
Definition caravan.c:691
city
Definition city.h:320
city::surplus
int surplus[O_LAST]
Definition city.h:355
city::id
int id
Definition city.h:326
city::production
struct universal production
Definition city.h:396
city::bonus
int bonus[O_LAST]
Definition city.h:363
city::tile
struct tile * tile
Definition city.h:322
city::shield_stock
int shield_stock
Definition city.h:368
civ_map
Definition map_types.h:71
cowt_data
Definition caravan.c:798
cowt_data::param
const struct caravan_parameter * param
Definition caravan.c:799
cowt_data::best
struct caravan_result * best
Definition caravan.c:801
cowt_data::caravan
const struct unit * caravan
Definition caravan.c:800
cowt_data::omniscient
bool omniscient
Definition caravan.c:802
pf_map
Definition path_finding.c:78
pf_parameter
Definition path_finding.h:357
pf_parameter::start_tile
struct tile * start_tile
Definition path_finding.h:359
player
Definition player.h:247
player::cities
struct city_list * cities
Definition player.h:279
tile
Definition tile.h:50
unit
Definition unit.h:138
unit::moves_left
int moves_left
Definition unit.h:150
unit::homecity
int homecity
Definition unit.h:146
universal::kind
enum universals_n kind
Definition fc_types.h:903
universal::value
universals_u value
Definition fc_types.h:902
world::map
struct civ_map map
Definition world_object.h:38
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
bool
#define bool
Definition support.h:71
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_continent
#define tile_continent(_tile)
Definition tile.h:92
can_cities_trade
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
Definition traderoutes.c:214
cities_trade_route_type
enum trade_route_type cities_trade_route_type(const struct city *pcity1, const struct city *pcity2)
Definition traderoutes.c:58
trade_base_between_cities
int trade_base_between_cities(const struct city *pc1, const struct city *pc2)
Definition traderoutes.c:322
city_num_trade_routes
int city_num_trade_routes(const struct city *pcity)
Definition traderoutes.c:383
trade_route_settings_by_type
struct trade_route_settings * trade_route_settings_by_type(enum trade_route_type type)
Definition traderoutes.c:201
max_trade_routes
unsigned max_trade_routes(const struct city *pcity)
Definition traderoutes.c:48
city_trade_removable
int city_trade_removable(const struct city *pcity, struct trade_route_list *would_remove)
Definition traderoutes.c:231
can_establish_trade_route
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
Definition traderoutes.c:275
get_caravan_enter_city_trade_bonus
int get_caravan_enter_city_trade_bonus(const struct city *pc1, const struct city *pc2, const struct unit_type *ut, struct goods_type *pgood, const bool establish_trade)
Definition traderoutes.c:467
traderoutes.h
trade_route_list_iterate
#define trade_route_list_iterate(trade_route_list, proute)
Definition traderoutes.h:95
trade_routes_iterate_end
#define trade_routes_iterate_end
Definition traderoutes.h:134
trade_route_list_iterate_end
#define trade_route_list_iterate_end
Definition traderoutes.h:97
trade_routes_iterate
#define trade_routes_iterate(c, proute)
Definition traderoutes.h:130
universals_u::building
const struct impr_type * building
Definition fc_types.h:717
unit_can_do_action
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:361
unit_tile
#define unit_tile(_pu)
Definition unit.h:390
unit_owner
#define unit_owner(_pu)
Definition unit.h:389
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
unit_build_shield_cost
int unit_build_shield_cost(const struct city *pcity, const struct unit *punit)
Definition unittype.c:1476
unit_build_shield_cost_base
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1484