1 /**********************************************************************
2  *
3  *   FreeDoko a Doppelkopf-Game
4  *
5  *   Copyright (C) 2001 – 2018 by Diether Knof and Borg Enders
6  *
7  *   This program is free software; you can redistribute it and/or
8  *   modify it under the terms of the GNU General Public License as
9  *   published by the Free Software Foundation; either version 2 of
10  *   the License, or (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *   You can find this license in the file 'gpl.txt'.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  *   MA  02111-1307  USA
22  *
23  *  Contact:
24  *    Diether Knof dknof@posteo.de
25  *
26  ********************************************************************/
27 
28 #include "constants.h"
29 
30 #include "aiconfig_heuristic.h"
31 
32 
33 /** -> result
34  **
35  ** @param    heuristic   heuristic type
36  **
37  ** @return   the name of 'type'
38  **/
39 string
to_string(AiconfigHeuristic const heuristic)40 to_string(AiconfigHeuristic const heuristic)
41 {
42   switch(heuristic) {
43   case AiconfigHeuristic::error:
44     (void)_("AiConfig::Heuristic::error");
45     (void)_("AiConfig::Heuristic::Description::error");
46     return "error";
47   case AiconfigHeuristic::no_heuristic:
48     (void)_("AiConfig::Heuristic::no heuristic");
49     (void)_("AiConfig::Heuristic::Description::no heuristic");
50     return "no heuristic";
51   case AiconfigHeuristic::manual:
52     (void)_("AiConfig::Heuristic::manual");
53     (void)_("AiConfig::Heuristic::Description::manual");
54     return "manual";
55   case AiconfigHeuristic::bug_report:
56     (void)_("AiConfig::Heuristic::bug report");
57     (void)_("AiConfig::Heuristic::Description::bug report");
58     return "bug report";
59   case AiconfigHeuristic::only_one_valid_card:
60     (void)_("AiConfig::Heuristic::only one valid card");
61     (void)_("AiConfig::Heuristic::Description::only one valid card");
62     return "only one valid card";
63   case AiconfigHeuristic::play_to_marry:
64     (void)_("AiConfig::Heuristic::play to marry");
65     (void)_("AiConfig::Heuristic::Description::play to marry");
66     return "play to marry";
67   case AiconfigHeuristic::play_to_get_married:
68     (void)_("AiConfig::Heuristic::play to get married");
69     (void)_("AiConfig::Heuristic::Description::play to get married");
70     return "play to get married";
71   case AiconfigHeuristic::start_with_color_solo_ace:
72     (void)_("AiConfig::Heuristic::start with color solo ace");
73     (void)_("AiConfig::Heuristic::Description::start with color solo ace");
74     return "start with color solo ace";
75   case AiconfigHeuristic::start_with_color_single_ace:
76     (void)_("AiConfig::Heuristic::start with color single ace");
77     (void)_("AiConfig::Heuristic::Description::start with color single ace");
78     return "start with color single ace";
79   case AiconfigHeuristic::start_with_color_double_ace:
80     (void)_("AiConfig::Heuristic::start with color double ace");
81     (void)_("AiConfig::Heuristic::Description::start with color double ace");
82     return "start with color double ace";
83   case AiconfigHeuristic::jab_with_color_ace:
84     (void)_("AiConfig::Heuristic::jab with color ace");
85     (void)_("AiConfig::Heuristic::Description::jab with color ace");
86     return "jab with color ace";
87   case AiconfigHeuristic::choose_ten:
88     (void)_("AiConfig::Heuristic::choose ten");
89     (void)_("AiConfig::Heuristic::Description::choose ten");
90     return "choose ten";
91   case AiconfigHeuristic::choose_for_color_trick:
92     (void)_("AiConfig::Heuristic::choose for color trick");
93     (void)_("AiConfig::Heuristic::Description::choose for color trick");
94     return "choose for color trick";
95   case AiconfigHeuristic::jab_color_over_fox:
96     (void)_("AiConfig::Heuristic::jab color over fox");
97     (void)_("AiConfig::Heuristic::Description::jab color over fox");
98     return "jab color over fox";
99   case AiconfigHeuristic::start_with_color:
100     (void)_("AiConfig::Heuristic::start with color");
101     (void)_("AiConfig::Heuristic::Description::start with color");
102     return "start with color";
103   case AiconfigHeuristic::start_with_low_color:
104     (void)_("AiConfig::Heuristic::start with low color");
105     (void)_("AiConfig::Heuristic::Description::start with low color");
106     return "start with low color";
107   case AiconfigHeuristic::start_with_low_trump:
108     (void)_("AiConfig::Heuristic::start with low trump");
109     (void)_("AiConfig::Heuristic::Description::start with low trump");
110     return "start with low trump";
111   case AiconfigHeuristic::retry_color:
112     (void)_("AiConfig::Heuristic::retry color");
113     (void)_("AiConfig::Heuristic::Description::retry color");
114     return "retry color";
115   case AiconfigHeuristic::play_color_for_partner:
116     (void)_("AiConfig::Heuristic::play color for partner");
117     (void)_("AiConfig::Heuristic::Description::play color for partner");
118     return "play color for partner";
119   case AiconfigHeuristic::try_color_for_partner:
120     (void)_("AiConfig::Heuristic::try color for partner");
121     (void)_("AiConfig::Heuristic::Description::try color for partner");
122     return "try color for partner";
123   case AiconfigHeuristic::play_color_for_partner_ace:
124     (void)_("AiConfig::Heuristic::play color for partner ace");
125     (void)_("AiConfig::Heuristic::Description::play color for partner ace");
126     return "play color for partner ace";
127   case AiconfigHeuristic::play_bad_color:
128     (void)_("AiConfig::Heuristic::play bad color");
129     (void)_("AiConfig::Heuristic::Description::play bad color");
130     return "play bad color";
131   case AiconfigHeuristic::jab_color_trick_with_dulle:
132     (void)_("AiConfig::Heuristic::jab color trick with dulle");
133     (void)_("AiConfig::Heuristic::Description::jab color trick with dulle");
134     return "jab color trick with dulle";
135   case AiconfigHeuristic::save_dulle:
136     (void)_("AiConfig::Heuristic::save dulle");
137     (void)_("AiConfig::Heuristic::Description::save dulle");
138     return "save dulle";
139   case AiconfigHeuristic::pfund_in_first_color_run:
140     (void)_("AiConfig::Heuristic::pfund in first color run");
141     (void)_("AiConfig::Heuristic::Description::pfund in first color run");
142     return "pfund in first color run";
143   case AiconfigHeuristic::serve_color_trick:
144     (void)_("AiConfig::Heuristic::serve color trick");
145     (void)_("AiConfig::Heuristic::Description::serve color trick");
146     return "serve color trick";
147   case AiconfigHeuristic::serve_trump_trick:
148     (void)_("AiConfig::Heuristic::serve trump trick");
149     (void)_("AiConfig::Heuristic::Description::serve trump trick");
150     return "serve trump trick";
151   case AiconfigHeuristic::choose_pfund:
152     (void)_("AiConfig::Heuristic::choose pfund");
153     (void)_("AiConfig::Heuristic::Description::choose pfund");
154     return "choose pfund";
155   case AiconfigHeuristic::choose_pfund_poverty:
156     (void)_("AiConfig::Heuristic::choose pfund poverty");
157     (void)_("AiConfig::Heuristic::Description::choose pfund poverty");
158     return "choose pfund poverty";
159   case AiconfigHeuristic::choose_pfund_before_partner:
160     (void)_("AiConfig::Heuristic::choose pfund before partner");
161     (void)_("AiConfig::Heuristic::Description::choose pfund before partner");
162     return "choose pfund before partner";
163   case AiconfigHeuristic::jab_for_ace:
164     (void)_("AiConfig::Heuristic::jab for ace");
165     (void)_("AiConfig::Heuristic::Description::jab for ace");
166     return "jab for ace";
167   case AiconfigHeuristic::create_fehl:
168     (void)_("AiConfig::Heuristic::create fehl");
169     (void)_("AiConfig::Heuristic::Description::create fehl");
170     return "create fehl";
171   case AiconfigHeuristic::best_winning:
172     (void)_("AiConfig::Heuristic::best winning card");
173     (void)_("AiConfig::Heuristic::Description::best winning card");
174     return "best winning card";
175   case AiconfigHeuristic::low_high:
176     (void)_("AiConfig::Heuristic::play low high");
177     (void)_("AiConfig::Heuristic::Description::play low high");
178     return "play low high";
179   case AiconfigHeuristic::play_trump:
180     (void)_("AiConfig::Heuristic::play trump");
181     (void)_("AiConfig::Heuristic::Description::play trump");
182     return "play trump";
183   case AiconfigHeuristic::play_for_team:
184     (void)_("AiConfig::Heuristic::play for team");
185     (void)_("AiConfig::Heuristic::Description::play for team");
186     return "play for team";
187   case AiconfigHeuristic::jab_fox:
188     (void)_("AiConfig::Heuristic::jab fox");
189     (void)_("AiConfig::Heuristic::Description::jab fox");
190     return "jab fox";
191   case AiconfigHeuristic::jab_for_doppelkopf:
192     (void)_("AiConfig::Heuristic::jab for doppelkopf");
193     (void)_("AiConfig::Heuristic::Description::jab for doppelkopf");
194     return "jab for doppelkopf";
195   case AiconfigHeuristic::try_for_doppelkopf:
196     (void)_("AiConfig::Heuristic::try for doppelkopf");
197     (void)_("AiConfig::Heuristic::Description::try for doppelkopf");
198     return "try for doppelkopf";
199   case AiconfigHeuristic::play_for_partner_worries:
200     (void)_("AiConfig::Heuristic::play for partner worries");
201     (void)_("AiConfig::Heuristic::Description::play for partner worries");
202     return "play for partner worries";
203   case AiconfigHeuristic::partner_backhand_draw_trump:
204     (void)_("AiConfig::Heuristic::partner backhand draw trump");
205     (void)_("AiConfig::Heuristic::Description::partner backhand draw trump");
206     return "partner backhand draw trump";
207   case AiconfigHeuristic::draw_trump:
208     (void)_("AiConfig::Heuristic::draw trump");
209     (void)_("AiConfig::Heuristic::Description::draw trump");
210     return "draw trump";
211   case AiconfigHeuristic::play_to_jab_later:
212     (void)_("AiConfig::Heuristic::play to jab later");
213     (void)_("AiConfig::Heuristic::Description::play to jab later");
214     return "play to jab later";
215   case AiconfigHeuristic::play_highest_color_card_in_game:
216     (void)_("AiConfig::Heuristic::play highest color card in game");
217     (void)_("AiConfig::Heuristic::Description::play highest color card in game");
218     return "play highest color card in game";
219   case AiconfigHeuristic::jab_to_win:
220     (void)_("AiConfig::Heuristic::jab to win");
221     (void)_("AiConfig::Heuristic::Description::jab to win");
222     return "jab to win";
223   case AiconfigHeuristic::grab_trick:
224     (void)_("AiConfig::Heuristic::grab trick");
225     (void)_("AiConfig::Heuristic::Description::grab trick");
226     return "grab trick";
227   case AiconfigHeuristic::last_player_pass_small_trick:
228     (void)_("AiConfig::Heuristic::last player pass small trick");
229     (void)_("AiConfig::Heuristic::Description::last player pass small trick");
230     return "last player pass small trick";
231 
232   case AiconfigHeuristic::cannot_jab:
233     (void)_("AiConfig::Heuristic::cannot jab");
234     (void)_("AiConfig::Heuristic::Description::cannot jab");
235     return "cannot jab";
236 
237   case AiconfigHeuristic::poverty_special_play_pfund:
238     (void)_("AiConfig::Heuristic::poverty: special: play pfund");
239     (void)_("AiConfig::Heuristic::Description::poverty: special: play pfund");
240     return "poverty: special: play pfund";
241   case AiconfigHeuristic::poverty_special_give_no_points:
242     (void)_("AiConfig::Heuristic::poverty: special: give no points");
243     (void)_("AiConfig::Heuristic::Description::poverty: special: give no points");
244     return "poverty: special: give no points";
245   case AiconfigHeuristic::poverty_special_offer_pfund:
246     (void)_("AiConfig::Heuristic::poverty: special: offer pfund");
247     (void)_("AiConfig::Heuristic::Description::poverty: special: offer pfund");
248     return "poverty: special: offer pfund";
249   case AiconfigHeuristic::poverty_re_trump_color_trick_high:
250     (void)_("AiConfig::Heuristic::poverty: re: trump color trick high");
251     (void)_("AiConfig::Heuristic::Description::poverty: re: trump color trick high");
252     return "poverty: re: trump color trick high";
253   case AiconfigHeuristic::poverty_re_play_trump:
254     (void)_("AiConfig::Heuristic::poverty: re: play trump");
255     (void)_("AiConfig::Heuristic::Description::poverty: re: play trump");
256     return "poverty: re: play trump";
257   case AiconfigHeuristic::poverty_contra_play_color:
258     (void)_("AiConfig::Heuristic::poverty: contra: play color");
259     (void)_("AiConfig::Heuristic::Description::poverty: contra: play color");
260     return "poverty: contra: play color";
261   case AiconfigHeuristic::poverty_contra_trump_color_trick_high:
262     (void)_("AiConfig::Heuristic::poverty: contra: trump color trick high");
263     (void)_("AiConfig::Heuristic::Description::poverty: contra: trump color trick high");
264     return "poverty: contra: trump color trick high";
265   case AiconfigHeuristic::poverty_leave_to_partner:
266     (void)_("AiConfig::Heuristic::poverty: contra: leave to partner");
267     (void)_("AiConfig::Heuristic::Description::poverty: contra: leave to partner");
268     return "poverty: contra: leave to partner";
269   case AiconfigHeuristic::poverty_overjab_re:
270     (void)_("AiConfig::Heuristic::poverty: contra: overjab re");
271     (void)_("AiConfig::Heuristic::Description::poverty: contra: overjab re");
272     return "poverty: contra: overjab re";
273   case AiconfigHeuristic::poverty_best_winning_card:
274     (void)_("AiConfig::Heuristic::poverty: best winning card");
275     (void)_("AiConfig::Heuristic::Description::poverty: best winning card");
276     return "poverty: best winning card";
277 
278   case AiconfigHeuristic::play_color_in_solo:
279     (void)_("AiConfig::Heuristic::play color in solo");
280     (void)_("AiConfig::Heuristic::Description::play color in solo");
281     return "play color in solo";
282   case AiconfigHeuristic::picture_pull_down_color:
283     (void)_("AiConfig::Heuristic::picture pull down color");
284     (void)_("AiConfig::Heuristic::Description::picture pull down color");
285     return "picture pull down color";
286   case AiconfigHeuristic::picture_start_with_highest_color:
287     (void)_("AiConfig::Heuristic::picture start with highest color");
288     (void)_("AiConfig::Heuristic::Description::picture start with highest color");
289     return "picture start with highest color";
290   case AiconfigHeuristic::picture_get_last_trumps:
291     (void)_("AiConfig::Heuristic::picture get last trumps");
292     (void)_("AiConfig::Heuristic::Description::picture get last trumps");
293     return "picture get last trumps";
294   case AiconfigHeuristic::picture_draw_trumps:
295     (void)_("AiConfig::Heuristic::picture draw trumps");
296     (void)_("AiConfig::Heuristic::Description::picture draw trumps");
297     return "picture draw trumps";
298   case AiconfigHeuristic::picture_play_last_trumps:
299     (void)_("AiConfig::Heuristic::picture play last trumps");
300     (void)_("AiConfig::Heuristic::Description::picture play last trumps");
301     return "picture play last trumps";
302   case AiconfigHeuristic::picture_jab_color_trick_for_sure:
303     (void)_("AiConfig::Heuristic::picture jab color trick for sure");
304     (void)_("AiConfig::Heuristic::Description::picture jab color trick for sure");
305     return "picture jab color trick for sure";
306   case AiconfigHeuristic::meatless_start_with_best_color:
307     (void)_("AiConfig::Heuristic::meatless: start with best color");
308     (void)_("AiConfig::Heuristic::Description::meatless: start with best color");
309     return "meatless: start with best color";
310   case AiconfigHeuristic::meatless_retry_last_color:
311     (void)_("AiConfig::Heuristic::meatless: retry last color");
312     (void)_("AiConfig::Heuristic::Description::meatless: retry last color");
313     return "meatless: retry last color";
314   case AiconfigHeuristic::color_jab_for_ace:
315     (void)_("AiConfig::Heuristic::color: jab for ace");
316     (void)_("AiConfig::Heuristic::Description::color: jab for ace");
317     return "color: jab for ace";
318   case AiconfigHeuristic::color_low_high:
319     (void)_("AiConfig::Heuristic::color: play low high");
320     (void)_("AiConfig::Heuristic::Description::color: play low high");
321     return "color: play low high";
322   case AiconfigHeuristic::choose_best_card_in_last_tricks:
323     (void)_("AiConfig::Heuristic::choose best card in last tricks");
324     (void)_("AiConfig::Heuristic::Description::choose best card in last tricks");
325     return "choose best card in last tricks";
326   case AiconfigHeuristic::choose_best_card:
327     (void)_("AiConfig::Heuristic::choose best card");
328     (void)_("AiConfig::Heuristic::Description::choose best card");
329     return "choose best card";
330   } // switch(heuristic)
331 
332   return "";
333 }
334 
335 /** @return   whether 'heuristic' is a real heuristic
336  **/
337 bool
is_real(AiconfigHeuristic const heuristic)338 is_real(AiconfigHeuristic const heuristic)
339 {
340   switch (heuristic) {
341   case AiconfigHeuristic::error:
342   case AiconfigHeuristic::no_heuristic:
343   case AiconfigHeuristic::manual:
344   case AiconfigHeuristic::bug_report:
345   case AiconfigHeuristic::choose_best_card:
346     return false;
347   default:
348     return true;
349   }
350 }
351 
352 /** -> return
353  **
354  ** @param    h   the heuristic type
355  **
356  ** @return   whether 'h' is a general heuristic
357  **/
358 /** @return   whether the heuristic is a general heuristic
359  **/
360 bool
is_general(AiconfigHeuristic const heuristic)361 is_general(AiconfigHeuristic const heuristic)
362 {
363   return (    is_real(heuristic)
364           && !for_solo(heuristic)
365           && !for_poverty(heuristic) );
366 }
367 
368 /** @return   whether the heuristic was made for a poverty
369  **/
370 bool
for_poverty(AiconfigHeuristic const heuristic)371 for_poverty(AiconfigHeuristic const heuristic)
372 {
373   switch (heuristic) {
374   case AiconfigHeuristic::poverty_special_play_pfund:
375   case AiconfigHeuristic::poverty_special_give_no_points:
376   case AiconfigHeuristic::poverty_special_offer_pfund:
377   case AiconfigHeuristic::poverty_re_trump_color_trick_high:
378   case AiconfigHeuristic::poverty_re_play_trump:
379   case AiconfigHeuristic::poverty_contra_play_color:
380   case AiconfigHeuristic::poverty_contra_trump_color_trick_high:
381   case AiconfigHeuristic::poverty_leave_to_partner:
382   case AiconfigHeuristic::poverty_overjab_re:
383   case AiconfigHeuristic::poverty_best_winning_card:
384     return true;
385   default:
386     return false;
387   }; // switch(h)
388 }
389 
390 /** @return   whether the heuristic was made for a solo
391  **/
392 bool
for_solo(AiconfigHeuristic const heuristic)393 for_solo(AiconfigHeuristic const heuristic)
394 {
395   return (   for_color_solo(heuristic)
396           || for_picture_solo(heuristic)
397           || for_meatless_solo(heuristic));
398 }
399 
400 /** @return   whether the heuristic was made for a color solo
401  **/
402 bool
for_color_solo(AiconfigHeuristic const heuristic)403 for_color_solo(AiconfigHeuristic const heuristic)
404 {
405   switch (heuristic) {
406   case AiconfigHeuristic::best_winning:
407   case AiconfigHeuristic::color_jab_for_ace:
408   case AiconfigHeuristic::color_low_high:
409     return true;
410   default:
411     return false;
412   }; // switch(h)
413 #ifdef WORKAROUND
414   // g++ 4.0 -O3
415   return false;
416 #endif
417 }
418 
419 /** @return   whether the heuristic was made for a picture solo
420  **/
421 bool
for_picture_solo(AiconfigHeuristic const heuristic)422 for_picture_solo(AiconfigHeuristic const heuristic)
423 {
424   switch (heuristic) {
425   case AiconfigHeuristic::picture_pull_down_color:
426   case AiconfigHeuristic::picture_start_with_highest_color:
427   case AiconfigHeuristic::picture_get_last_trumps:
428   case AiconfigHeuristic::picture_draw_trumps:
429   case AiconfigHeuristic::picture_play_last_trumps:
430   case AiconfigHeuristic::picture_jab_color_trick_for_sure:
431     return true;
432   default:
433     return false;
434   }; // switch(h)
435 #ifdef WORKAROUND
436   // g++ 4.0 -O3
437   return false;
438 #endif
439 }
440 
441 /** @return   whether the heuristic was made for a meatless solo
442  **/
443 bool
for_meatless_solo(AiconfigHeuristic const heuristic)444 for_meatless_solo(AiconfigHeuristic const heuristic)
445 {
446   switch (heuristic) {
447   case AiconfigHeuristic::meatless_start_with_best_color:
448   case AiconfigHeuristic::meatless_retry_last_color:
449   case AiconfigHeuristic::picture_pull_down_color:
450   case AiconfigHeuristic::picture_start_with_highest_color:
451     return true;
452   default:
453     return false;
454   }; // switch(h)
455 #ifdef WORKAROUND
456   // g++ 4.0 -O3
457   return false;
458 #endif
459 }
460 
461 /** -> result
462  **
463  ** @param    name   name of the heuristic
464  **
465  ** @return   the heuristic according to the name
466  **/
467 AiconfigHeuristic
AiconfigHeuristic_from_name(string const & name)468 AiconfigHeuristic_from_name(string const& name)
469 {
470   for (auto const h : aiconfig_heuristic_list) {
471     if (name == to_string(h)) {
472       return h;
473     }
474   }
475 
476   return AiconfigHeuristic::error;
477 }
478 
479 /** write the name of the heuristic in the output stream
480  **/
operator <<(ostream & ostr,AiconfigHeuristic const heuristic)481 ostream& operator<<(ostream& ostr, AiconfigHeuristic const heuristic)
482 {
483   return (ostr << to_string(heuristic));
484 }
485 
486 /** @return   translation of the heuristic
487  **/
gettext(AiconfigHeuristic const heuristic)488 string gettext(AiconfigHeuristic const heuristic)
489 {
490   return gettext("AiConfig::Heuristic::" + to_string(heuristic));
491 }
492 
493 /** @return   translation of the heuristic description
494  **/
gettext_description(AiconfigHeuristic const heuristic)495 string gettext_description(AiconfigHeuristic const heuristic)
496 {
497   return gettext("AiConfig::Heuristic::Description::" + to_string(heuristic));
498 }
499