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 "trickweighting.h"
31 
32 #include "virtual_games_interface.h"
33 #include "ai.h"
34 #include "../../party/party.h"
35 #include "../../party/rule.h"
36 #include "../../game/game.h"
37 #include "../../game/exception.h"
38 #include "../../card/trick.h"
39 #include "../../misc/preferences.h"
40 #include "../../ui/ui.h"
41 
42 #ifdef BENDERS
43 #ifndef RELEASE
44 // whether to print some weighting informations
45 #define PLAYERCHECK 10
46 
47 // Playernumber for which to produce output
48 unsigned playerCheck;
49 #endif
50 #endif
51 
52 
53 /** @return   whether the opposite team can win the trick
54  **/
55 bool
oppositeTeamCanWinTrick(Trick const & trick,VirtualGamesInterface const & hi)56 oppositeTeamCanWinTrick(Trick const& trick,
57                         VirtualGamesInterface const& hi)
58 {
59   if (trick.winnerplayer().team() != hi.team())
60     return true;
61 
62   // take a look if all players coming in this trick of other team can still win the trick
63   for (auto i = trick.actcardno(); i < hi.game().playerno(); ++i) {
64     auto const& player = trick.player_of_card(i);
65     if (hi.guessed_opposite_team(player)) {
66       auto const& hand = hi.handofplayer(player);
67       if (hand.higher_card_exists(trick.winnercard()))
68         return true;
69     }
70   }
71   return false;
72 } // bool oppositeTeamCanWinTrick ( Trick t, HeuristicInterface hi )
73 
74 /** Modification for dulle and swines
75  **/
76 int
modi_dulle_swines(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)77 TrickWeighting::modi_dulle_swines(VirtualGamesInterface const& vgi,
78                                       Trick const& trick,
79                                       Team const team,
80                                       HandCard const& card,
81                                       Team const winnerteam,
82                                       Ai const& ai)
83 {
84   int modi = 0;
85 
86   if( !card.istrump() )
87     return modi;
88 
89   if (!(   card.isswine()
90         || card.ishyperswine()
91         || card.isdulle()))
92     return modi;
93 
94   // have played a very high card
95 
96   auto const& hand = ai.hand();
97   auto const& game = ai.game();
98   auto const& swines = game.swines();
99   auto const& cards = game.cards();
100 
101   // 2005-08-06: swines in the last three tricks
102   // modi -= 29; // previous values: 23,14,21,24, 29, 33, 35,31
103   modi -= (31 - std::max(static_cast<int>(cards.count_played()) - 9 , 0));
104   // previous: 34, 31 (Reference 92672)
105   // previous: no()-12
106 
107   if( trick.startcard().istrump() )
108     modi -= 11; // reference
109 
110   if (  (static_cast<int>(trick.points()) - card.value()
111          < ai.value(Aiconfig::Type::limitqueen)))
112     modi-= 4;
113 
114   if (maybe_to_team(winnerteam) != team)
115     modi -= 26;
116 
117   if (maybe_to_team(winnerteam) == team) {
118     if (    // review Reference 260689
119         trick.startplayer().no() == vgi.no() )  // serving with a high trump and something potential higher is still out there
120     {
121       if (    hand.count_swines() +
122           hand.count_hyperswines() +
123           hand.count( Card::dulle ) != hand.count_trumps() ) {
124         modi -= 10; // reference
125       }
126 
127       //high trump serving is generally not a good choice
128       if (!(is_solo(vgi.game().type())
129             && (vgi.game().players().soloplayer() == ai)))
130         modi -= 19; // reference 274918
131     }
132   }
133 
134   if(   (vgi.no() != trick.winnerplayer().no())
135      && !(  trick.cardno_of_player( card.player() ) == 3
136           && trick.winnerplayer().team() == vgi.team() )
137     ) {
138     modi -= (36 - std::max(static_cast<int>(cards.count_played()) - 13, 0));
139     modi += trick.points()/2;
140 
141     if( trick.cardno_of_player( trick.winnerplayer() )
142        < trick.cardno_of_player( card.player() )
143        || !trick.jabs_cards_before(  card.player() ))
144       modi -= 16; // previously 9, 12
145   }
146 
147   // not for all three cards
148 
149   if (  ! card.isdulle()) // so that a dulle is prefered to a swine
150     modi -= 8;  //previous values: 2, 7,9
151 
152   if (  trick.startplayer().no() == vgi.no() )
153   {
154     // previous: 12, 18
155     modi -= 30;  // 23: 002645, 30:
156     if (    hand.count_swines() +
157         hand.count_hyperswines() +
158         hand.count(Card::dulle) == hand.count_trumps() )
159     {
160 
161       if( card.isdulle()
162          && (!swines.swines_announced()
163              || ai.teamofplayer(swines.swines_owner()) == ai.team() )
164          && (!swines.hyperswines_announced()
165              || ai.teamofplayer(swines.hyperswines_owner()) == ai.team()) )
166       {
167         modi += 10;
168       }
169       if (  card.isswine()
170           && (   !swines.hyperswines_announced()
171               || ai.teamofplayer(swines.hyperswines_owner()) == ai.team())) {
172         modi += 30;
173       }
174       if (card.ishyperswine()) {
175         modi += 50;
176       }
177 
178     } else {
179       if( is_solo( vgi.game().type() )  // reference 246985
180          && vgi.is_soloplayer() ) //2do no higher card still in game
181         modi += 21;
182     }
183   }
184 
185 
186   if (  trick.cardno_of_player(card.player()) == 1
187       && vgi.game().cards().count_played(Card::dulle) == 0 //2do before trick
188       && card.isdulle()
189       && vgi.game().second_dulle_over_first() )
190     modi -= 5;
191 
192   if (  trick.cardno_of_player(card.player()) == 0
193       && vgi.game().cards().count_played(Card::dulle) == 0 //2do before trick
194       && card.isdulle()
195       && vgi.game().second_dulle_over_first() )
196     modi -= 1; // reference 197840
197 
198   // depending on data in the trick
199 
200   Trick t(trick.startplayer());
201   for (unsigned i = 0; i < trick.cardno_of_player(card.player()); ++i) {
202     t.add(trick.card( i ));
203   }
204 
205   if(  trick.cardno_of_player(card.player()) == 2
206      && card.isdulle()
207      && swines.swines_announced()  //2do extend to hyperswine, do same for swine hyperswine
208      && trick.cardno_of_player(swines.swines_owner()) == 3 ) {
209     // swine behind dulle
210     modi -= 15;  // reference 176246
211   }
212 
213   if(  trick.cardno_of_player(card.player()) == 1
214      && card.isdulle()
215      && swines.swines_announced()  //2do extend to hyperswine, do same for swine hyperswine
216      && trick.cardno_of_player(swines.swines_owner()) >1 ) {
217     // swine behind dulle
218     modi -= 3;  // reference 010523
219   }
220 
221 
222   if(  card.isdulle()
223      && swines.swines_announced()  //2do extend to hyperswine, do same for swine hyperswine
224      && trick.cardno_of_player(swines.swines_owner()) < trick.cardno_of_player(card.player())) {
225     // swines in game, but before player with dulle
226     modi +=13; // reference 088597, 114803
227   }
228 
229   if (trick.cardno_of_player(card.player()) == 3) {
230     modi -= 21; // previous 18, 20, 24
231 
232     if (t.winnerplayer().team() == vgi.team()) { // reference 43530
233       modi -= 9; // previous
234     }
235 
236     if (t.winnerplayer().team() != vgi.team()) { // reference
237       modi -= 19; // previous
238     }
239   }
240 
241 
242 
243   if ( ai.value(Aiconfig::Type::limithigh).less(t.winnercard()) // !oppositeTeamCanWinTrick( t, vgi ) ) 2do XXX
244     && t.winnerplayer().team() == team ) {
245       modi -= 26;
246       if( is_solo( vgi.game().type() )
247          && !vgi.is_soloplayer())
248         modi -= 4;
249     }
250 
251 
252   if ( ( card.possible_swine() //2do for a swine possible_swine should return false?
253         && !card.isswine() )
254       || (  card.possible_hyperswine()
255           && !card.ishyperswine()))
256     modi += 9;
257 
258 
259   // only for soli
260   if( is_solo( vgi.game().type() )
261      && vgi.is_soloplayer())
262     modi += 3;
263 
264 #ifdef PLAYERCHECK
265   if (vgi.no() == playerCheck) {
266 
267     COUT <<"MDS"<< modi << "\t";
268 
269   }
270 #endif
271   return modi;
272 }
273 
274 
275 /** Modification for a queen
276  **/
277 int
modi_queen(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)278 TrickWeighting::modi_queen(VirtualGamesInterface const& vgi,
279                            Trick const& trick,
280                            Team const team,
281                            HandCard const& card,
282                            Team const winnerteam,
283                            Ai const& ai)
284 {
285   if (card.value() != Card::queen)
286     return 0;
287   if (!card.istrump())
288     return 0;
289 
290   int modi = 0;
291   Player const& ai_virt = trick.game().player(ai.no());
292 
293   modi -= 4; // previous 2, 3
294   // 4: Reference 188872
295 
296   if (
297       (static_cast<int>(trick.points()) - card.value()
298        < ai.value(Aiconfig::Type::limitqueen)))
299     modi-= 4;
300 
301   if ( trick.cardno_of_player(card.player()) == 3 )
302   {
303     modi -= 13; // previous 11, 13, 17, 14
304     // 13 reference 043530
305 
306     Trick t( trick.startplayer());
307     t.add(trick.card( 0 ));
308     t.add(trick.card( 1 ));
309     t.add(trick.card( 2 ));
310 
311     if (t.winnerplayer().team() == vgi.team()) {
312       modi -= 7; // previous
313 
314     }
315   }
316 
317   if (is_solo(vgi.game().type())
318       && (vgi.game().players().soloplayer().no() == ai.no())
319       && vgi.trump_card_limit().less(card)
320       && card.less(ai.cards_information().highest_remaining_trump_of_others()))
321     modi -= 8; // reference 246985
322 
323 
324 
325   if(   (  vgi.no() != trick.winnerplayer().no()
326          && !(  trick.cardno_of_player( card.player() ) == 3
327               && trick.winnerplayer().team() == vgi.team() )
328         )
329 
330     )
331   {
332     modi -= (36 - std::max(static_cast<int>(ai.game().cards().count_played()) - 13, 0));
333     modi += trick.points()/2;
334 
335     if( trick.cardno_of_player( trick.winnerplayer() )
336        < trick.cardno_of_player( card.player() )
337        || !trick.jabs_cards_before(  card.player() ))
338       modi -= 18; // previously 9, 12, 16
339     // 18 261053
340   }
341 
342   if (   card == Card::spade_queen ) {
343     if( vgi.no() != trick.winnerplayer().no() ) {
344       modi -= 3; // reference
345     }
346   }
347 
348   if ( is_solo(vgi.game().type())
349       && Card::diamond_queen == card )
350     modi += 1; // reference 126305
351 
352   if (   card == Card::club_queen ) {
353     if( vgi.no() != trick.winnerplayer().no() ) {
354       modi -= 5; // reference 156330
355     }
356 
357     if( vgi.game().teaminfo().get(ai) != ai.team() ) {
358       modi += 3; // previous 1
359     } else {
360       modi -= 4; // previous 2, 3
361     }
362 
363     // show your own team.
364     if (    vgi.game().teaminfo().get(ai) != ai.team()
365         && ai.hand().count_trumps() <= 3 + (ai.hand().has_swines()?0:ai.hand().count_trump_aces())
366         && vgi.game().tricks().remaining_no() - 1 > ai.hand().count_trumps()
367         && (trick.cardno_of_player(trick.winnerplayer())
368             > trick.cardno_of_player(card.player())
369             && trick.jabs_cards_before( card.player() ))
370        )
371     {
372       modi += 4; // previous
373       if (  vgi.game().cards().count_played(Card::club_queen) == 0
374           && vgi.game().announcements().last(ai.team()).announcement == Announcement::noannouncement
375          )
376         modi += 12; // previous
377     }
378 
379     if(    trick.cardno_of_player(ai_virt) == 3
380        && trick.winnerplayer().team() != vgi.team() )
381     {
382       modi -= 3; // reference 234467
383     }
384 
385     if(    trick.cardno_of_player(ai_virt) == 0 )
386       modi -= 12; // reference 168423
387   }
388 
389 
390 #ifdef PLAYERCHECK
391   if (vgi.no() == playerCheck) {
392     COUT <<"MQ"<< modi << "\t";
393   }
394 #endif
395   return modi;
396 }
397 
398 /** Modification for a jack
399  **/
400 int
modi_jack(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)401 TrickWeighting::modi_jack(VirtualGamesInterface const& vgi,
402                           Trick const& trick,
403                           Team const team,
404                           HandCard const& card,
405                           Team const winnerteam,
406                           Ai const& ai)
407 {
408   int modi = 0;
409 
410   if (!card.istrump()) {
411     return modi;
412   }
413 
414   if( card.value() != Card::jack )
415     return modi;
416 
417   if (  trick.cardno_of_player(card.player()) == 3 )
418     modi -= 2;
419 
420   if (  trick.cardno_of_player(card.player()) == 1 )
421     modi += 14; // reference 028089
422 
423   if (  trick.cardno_of_player(card.player()) == 0 )
424     modi += 22; //reference 114558
425 
426   if( trick.startcard().istrump()
427      && trick.cardno_of_player(card.player()) !=0 )
428     modi += 5; //reference 099840
429 
430 
431   // force enemy with a jack to play a queen
432   if (   vgi.no() != trick.winnerplayer().no()
433       && (trick.cardno_of_player(trick.winnerplayer())
434           > trick.cardno_of_player(card.player())
435           && trick.jabs_cards_before( card.player() ) )
436       && (trick.winnercard().value() == Card::queen)
437       && (ai.team() != winnerteam)
438       && trick.winnercard().istrump() )
439     modi += 1;
440 
441   Trick t( trick.startplayer());
442   for(unsigned i = 0; i == trick.cardno_of_player(card.player()); i++ )
443   {
444     t.add(trick.card( i ));
445   }
446 
447   if (   vgi.no() != trick.winnerplayer().no() ) // playing jack and not winning trick
448   {
449     modi -= 6; // reference 133381
450 
451   }
452 
453   // save charlie in endgame for extra point
454   if(    card == Card::charlie
455      && vgi.game().rule()(Rule::Type::extrapoint_charlie)
456      && vgi.game().tricks().remaining_no() -1 == ai.hand().count_trumps())
457     modi -= 23; // reference 71916
458 
459 #ifdef PLAYERCHECK
460   if (vgi.no() == playerCheck) {
461 
462     COUT <<"MJ"<< modi << "\t";
463 
464   }
465 #endif
466   return modi;
467 }
468 
469 /** modification for a fox
470  **/
modi_fox(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)471 int TrickWeighting::modi_fox(VirtualGamesInterface const& vgi,
472                              Trick const& trick,
473                              Team const team,
474                              HandCard const& card,
475                              Team const winnerteam,
476                              Ai const& ai)
477 {
478   int modi = 0;
479 
480   Player const& ai_virt = trick.game().player(ai.no());
481 
482   // calculations for fox in trick
483   if (   vgi.no() != trick.winnerplayer().no()
484       && (trick.cardno_of_player(trick.winnerplayer())
485           > trick.cardno_of_player(card.player())
486           && trick.jabs_cards_before( card.player() ) )
487       && ai.value(Aiconfig::Type::limithigh).less(trick.winnercard())
488       && ai.team() != winnerteam )
489   {
490     for (unsigned c = 0; c < trick.actcardno(); c++)
491     {
492       if (trick.card(c).isfox() )
493         modi += 11;
494     }
495 
496   }
497 
498   if ((  (vgi.no() != trick.startplayer().no())
499        || card.istrump())
500      ) {
501     for (unsigned c = 0; c < trick.actcardno(); c++) {
502       // test, whether the fox has been brought home
503 
504       if (trick.card(c).isfox() )
505       {
506 
507         if( (vgi.game().type() != GameType::poverty)
508            || !vgi.is_soloplayer())
509         {
510           unsigned fact = 25;
511           if(   ai.value(Aiconfig::Type::hands_known)
512              || ai.value(Aiconfig::Type::trusting) )
513           {
514             fact += 10;
515             if( card.isfox() )
516               fact += 5;
517           }
518           if( !card.isfox() )
519             fact += 5;
520 
521           bool allmyteam = true;
522 
523           // take a look if all players coming in this trick are of mine team
524           for( unsigned i = trick.cardno_of_player(ai_virt); i < vgi.game().playerno(); i++ )
525             allmyteam = allmyteam && ( ai.team() == ai.teaminfo( trick.player_of_card( i ) ) );
526 
527           if (    card.isfox()
528               && !trick.startcard().istrump()
529               && ai.color_runs( trick.startcard().color() ) > 0
530               && !allmyteam
531               && oppositeTeamCanWinTrick( trick, vgi ))
532           {
533             fact -= 21;
534           }
535 
536 
537 
538           modi += fact * ((team == winnerteam)
539                           ? +1
540                           : -1);
541 
542         } else { // fox from above neutralized.
543           if ( card.isfox() )
544             modi += 30 * ((team != winnerteam)
545                           ? +1
546                           : 0);
547         }
548       }
549     } // for (c < trick.actcardno())
550   } // if (  (vgi.no() != trick.startplayer().no()) || card.istrump())
551 
552 
553   // own fox
554   if( !card.isfox() )
555   {
556 #ifdef PLAYERCHECK
557     if (vgi.no() == playerCheck) {
558 
559       COUT <<"MFA"<< modi << "\t";
560 
561     }
562 #endif
563     return modi;
564   }
565 
566   // to play a fox it must be worth it
567   {
568     modi -= 12; // previous 7, 16 (ref 208166)
569   }
570 
571   if (  (vgi.no() != trick.startplayer().no())) {
572 
573     if (maybe_to_team(winnerteam) == team)
574     {
575       if (  winnerteam == team
576           && ai.value(Aiconfig::Type::limithigh).less(trick.winnercard())
577          )
578         modi += 30; // fox home
579 
580     }
581   }
582 
583   // bad style to play fox as first card
584   if( trick.startplayer().no() == vgi.no() )
585   {
586     modi -= 90; // previous
587   }
588 
589   if( trick.cardno_of_player(card.player()) == 3
590      && maybe_to_team(winnerteam) != team )
591   {
592     modi -= 6; // previous
593 
594     if( ai.hand().count_trumps() <= 3 )
595       modi += 2; // reference
596   }
597 
598   if( trick.cardno_of_player(card.player()) == 3
599      && winnerteam != team )
600   {// reference 93822
601     modi -= 35; // previous
602 
603   }
604 
605   if( trick.cardno_of_player(card.player()) == 3
606      && winnerteam == team )
607   {
608     modi += 5; // previous
609   }
610 
611 #ifdef PLAYERCHECK
612   if (vgi.no() == playerCheck) {
613 
614     COUT <<"MFB"<< modi << "\t";
615 
616   }
617 #endif
618 
619   return modi;
620 }
621 
622 /** Modification for a meatless solo
623  **/
624 int
modi_soli_meat_less(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)625 TrickWeighting::modi_soli_meat_less(VirtualGamesInterface const& vgi,
626                                     Trick const& trick,
627                                     Team const team,
628                                     HandCard const& card,
629                                     Team const winnerteam,
630                                     Ai const& ai)
631 {
632   int modi = 0;
633 
634   if ( vgi.game().type() != GameType::solo_meatless)
635     return modi;
636   if (   ai.no() != vgi.game().players().soloplayer().no()
637       && vgi.no() != trick.winnerplayer().no()
638       && ai.hand().count(card.color(), vgi.game()) > 0
639       && ai.hand().count(card.color(), vgi.game()) < 3
640       && (   ai.hand().count(Card(card.color(),Card::ace)) > 0
641           || ai.hand().count(Card(card.color(),Card::ten)) > 0
642           || card.value() == Card::ace || card.value() == Card::ten )
643      )
644   { // prevent non soloplayer from blank playing of cards
645     modi -= 12;
646   }
647 
648   if (   ai.no() != vgi.game().players().soloplayer().no()
649       && vgi.no() != trick.winnerplayer().no()
650       && (card.value() == Card::ace || card.value() == Card::ten) )
651     modi -=3;  // reference 004655
652 
653 
654 #ifdef PLAYERCHECK
655   if (vgi.no() == playerCheck) {
656 
657     COUT <<"MSM"<< modi << "\t";
658 
659   }
660 #endif
661 
662   return modi;
663 }
664 
665 /** Modification for a marriage
666  **/
667 int
modi_marriage(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)668 TrickWeighting::modi_marriage(VirtualGamesInterface const& vgi,
669                               Trick const& trick,
670                               Team const team,
671                               HandCard const& card,
672                               Team const winnerteam,
673                               Ai const& ai)
674 {
675   if (vgi.game().type() != GameType::marriage)
676     return 0;
677 
678   int modi = 0;
679 
680   if (   (vgi.game().marriage().selector() != MarriageSelector::team_set)
681       && (card.value() >= 10) )
682     modi -= 9;
683 
684   if (trick.cardno_of_player(card.player()) == 0) {
685     switch (vgi.game().marriage().selector()) {
686     case MarriageSelector::silent:
687     case MarriageSelector::team_set:
688       // the marriage is determined
689       break;
690     case MarriageSelector::first_color:
691     case MarriageSelector::first_foreign:
692       if (!card.istrump()) {
693         modi -= 5;
694       }
695       break;
696     case MarriageSelector::first_trump:
697       if (card.istrump()) {
698         modi -= 5;
699       }
700       break;
701     case MarriageSelector::first_club:
702       if (   !card.istrump()
703           && card.color() == Card::club ) {
704         modi -= 5;
705       }
706       break;
707     case MarriageSelector::first_spade:
708       if (   !card.istrump()
709           && card.color() == Card::spade) {
710         modi -= 5;
711       }
712       break;
713     case MarriageSelector::first_heart:
714       if ( !card.istrump()
715           && card.color() == Card::heart ) {
716         modi -= 5;
717       }
718       break;
719     } // switch (this->game().marriage().selector())
720   } // if !(marriage && !card is trickstartcard())
721 
722 #ifdef PLAYERCHECK
723   if (vgi.no() == playerCheck) {
724     COUT <<"MM"<< modi << "\t";
725   }
726 #endif
727   return modi;
728 }
729 
730 /** Modification for special points
731  **/
732 int
modi_special_points(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)733 TrickWeighting::modi_special_points(VirtualGamesInterface const& vgi,
734                                     Trick const& trick,
735                                     Team const team,
736                                     HandCard const& card,
737                                     Team const winnerteam,
738                                     Ai const& ai)
739 {
740   int modi = 0;
741 
742   Game const& virt_game = trick.game();
743 
744   // create the teams-vector
745   vector<Team> teams;
746   for (auto const& player : virt_game.players()) {
747     // determine team of player from ai out of virtual game
748     auto const t = ai.teamofplayer(player);
749     if (t != Team::unknown)
750       teams.push_back(maybe_to_team(t));
751     else
752       teams.push_back(opposite(maybe_to_team(ai.team())));
753   } // for (player)
754 
755   if (  (vgi.no() != trick.startplayer().no())
756       || card.istrump()) {
757 
758     if (maybe_to_team(winnerteam) == team) {
759       auto const spv = trick.specialpoints(teams);
760       modi += (30 * sum(spv, winnerteam, trick.startplayer().game()));
761     } else {
762       auto const spv = trick.specialpoints(teams);
763       modi -= (30 * sum(spv, winnerteam, trick.startplayer().game()));
764     }
765 
766   } // if (  (vgi.no() != trick.startplayer().no()) || card.istrump())
767 #ifdef PLAYERCHECK
768   if (vgi.no() == playerCheck) {
769 
770     COUT <<"MSP"<< modi << "\t";
771 
772   }
773 #endif
774   return modi;
775 }
776 
777 /** Modification for no trump
778  **/
779 int
modi_no_trump(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)780 TrickWeighting::modi_no_trump(VirtualGamesInterface const& vgi,
781                               Trick const& trick,
782                               Team const team,
783                               HandCard const& card,
784                               Team const winnerteam,
785                               Ai const& ai)
786 {
787   int modi = 0;
788   if (card.istrump () )
789     return modi;
790 
791   Player const& ai_virt = trick.game().player(ai.no());
792 
793 
794   if(  vgi.no() != trick.winnerplayer().no()
795      && is_solo( vgi.game().type() )
796      && ( trick.cardno_of_player( trick.winnerplayer() ) > trick.cardno_of_player( trick.game().players().soloplayer() ) )
797      && !trick.card_of_player( trick.game().players().soloplayer() ).less( vgi.trump_card_limit() )
798     )
799   {
800     modi -= card.value();
801   }
802 
803   if( is_solo( vgi.game().type() )
804      && trick.cardno_of_player( trick.game().players().soloplayer() ) == 0 )
805   {
806     modi += card.value();
807     if ( card.value() >= 10 )
808       modi += 3;
809   }
810 
811   if( is_solo( vgi.game().type() )
812      && trick.cardno_of_player(ai_virt) == 0 )
813   {
814     // last card with small value to serve a trick
815     if(   ai.hand().count( card.color() ) == 0
816        && card.value() < 10 )
817       modi += 34; // reference 64029
818   }
819 
820   // game nears it end, no real sense to keep non trump carts any longer, better to hold trumps
821   if (    trick.cardno_of_player(ai_virt) == 0
822       && vgi.game().tricks().remaining_no() < 4 )
823   {
824     modi += 23; // reference 058753
825 
826   }
827 
828   if (    trick.cardno_of_player(ai_virt) == 0
829       && vgi.game().tricks().remaining_no() < 5 )
830   {
831 
832     if ( vgi.team() == Team::re
833         &&  vgi.game().type() != GameType::marriage
834         && ai.cards_information().played(Card::club_queen)+ai.hand().count_club_queens()<2)
835       modi += 3;  // reference 043205
836   }
837 
838   if(  vgi.no() != trick.winnerplayer().no()
839      && is_solo( vgi.game().type() )
840      && ( trick.cardno_of_player( trick.winnerplayer() ) > trick.cardno_of_player( trick.game().players().soloplayer() ) )
841      && trick.card_of_player( trick.game().players().soloplayer() ).less( vgi.trump_card_limit() )
842     )
843     modi += card.value();
844 
845 
846 
847   // prefer color cards a little bit
848   if(    card.value() == Card::nine
849      && trick.winnerplayer().team() != vgi.team() )
850   {
851     modi += 8; // previous: 6
852     if( trick.cardno_of_player(ai_virt) == 0 )
853       modi +=10; // reference 203953
854   }
855   if(    card.value() == Card::king
856      && trick.winnerplayer().team() != vgi.team() )
857     modi += 8;
858 
859   if( vgi.game().announcements().last( trick.winnerplayer().team() ).announcement != Announcement::noannouncement
860      && trick.winnerplayer().team() != vgi.team() )
861   {
862     // preserve trumps against announcement
863     modi += 6;  //reference 006877
864   }
865 
866   if ( card.value() == Card::ace )
867   {
868 
869     modi -= 2 - vgi.color_runs( card.color() );
870   }
871 
872   if( card.value() == Card::jack )
873     modi +=1; // good choice if not trump
874   // reference 112599
875 
876   if( is_solo( vgi.game().type() )
877      && vgi.team() == Team::contra )
878     modi -=  2* ai.hand().count( card.color() ); // reference  137807
879 
880 
881   if (  vgi.no() != trick.winnerplayer().no()
882       && winnerteam != team
883       && trick.startcard().color() != card.color()
884       && !trick.startcard().istrump() )
885   {
886     modi -= 9; //previous 6, 16, 14, 8
887     // 9 : Reference 001236
888 
889     if(    trick.cardno_of_player(ai_virt) == 3
890        && card.value() >= 10 ) // reference 234467
891       modi -= 29;
892 
893   }
894 
895   if(    trick.cardno_of_player(ai_virt) == 0
896      && card.value() == Card::nine
897      && vgi.color_runs( trick.startcard().color() ) > 0)
898   { modi+=7; } //reference 272170
899 
900   bool allmyteam=true;
901 
902   for( unsigned i = trick.cardno_of_player(ai_virt);
903       i < ai.game().playerno();
904       i++ )
905     allmyteam=allmyteam && ( ai.team() == ::maybe_to_team( vgi.teamofplayer( trick.player_of_card(i) ) ) );
906 
907   if(  !trick.startcard().istrump()
908      && vgi.color_runs( trick.startcard().color() ) > 0
909      && card.color() != trick.startcard().color()
910      && !allmyteam)
911     modi -= card.value()+2; //+2 reference 133381
912 
913   if( (ai.hand().count_trumps() - 1 <= (vgi.game().tricks().remaining_no() + 1) / 2 ) )
914   {
915     // reference 61146
916     modi += 6;
917     //if fox is still on hand, protect fox.
918     if( ai.hand().count_trump_aces() > 0 && ai.hand().count_swines() == 0 )
919     {
920       modi += 6; //reference 052672
921       if( ai.hand().count_trumps() == 2 )
922         modi += 15; // reference 076221
923     }
924   }
925 
926   if (  vgi.color_runs( card.color() ) == 0
927       && card.value() == Card::ace
928       && ai.team() == winnerteam
929      )
930   {
931     modi += 2;
932 
933   }
934 
935   if( is_solo( vgi.game().type() )
936      && trick.cardno_of_player(trick.game().players().soloplayer()) > trick.cardno_of_player(card.player())
937      && vgi.color_runs( card.color() ) == 0
938      && card.value() == Card::ace
939     )
940   {
941     modi += 22; // reference 9751
942   }
943 
944 #ifdef PLAYERCHECK
945   if (vgi.no() == playerCheck) {
946 
947     COUT <<"MNT"<< modi << "\t";
948 
949   }
950 #endif
951   return modi;
952 }
953 
954 /** Modification for a picture solo
955  **/
956 int
modi_picture_soli(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)957 TrickWeighting::modi_picture_soli(VirtualGamesInterface const& vgi,
958                                   Trick const& trick,
959                                   Team const team,
960                                   HandCard const& card,
961                                   Team const winnerteam,
962                                   Ai const& ai)
963 {
964   int modi = 0;
965 
966   if(  (   vgi.game().type() == GameType::solo_king
967         || vgi.game().type() == GameType::solo_king_jack
968         || vgi.game().type() == GameType::solo_king_queen
969         || vgi.game().type() == GameType::solo_koehler)
970      && card.value() == Card::king  )
971   {
972     if( vgi.no() != trick.winnerplayer().no() )
973     {
974       modi -= (36 - std::max(static_cast<int>(ai.game().cards().count_played()) - 13, 0));
975       modi += trick.points()/2;
976 
977       if( trick.cardno_of_player( trick.winnerplayer() )
978          < trick.cardno_of_player( card.player() )
979          || !trick.jabs_cards_before( card.player() ) )
980         modi -= 4;
981     } else
982       if(     trick.cardno_of_player( card.player() ) == 3
983          && trick.points() < 16 )  // reference 131296
984       {
985         modi -= 25;
986       }
987   }
988 
989   if( card.istrump()
990      && (   vgi.no() != trick.winnerplayer().no()
991          || trick.winnercardno() != 3)
992      && trick.cardno_of_player(card.player()) == 3 ) {
993     if (   vgi.game().type() != GameType::solo_king
994         && vgi.game().type() != GameType::solo_queen_jack
995         && vgi.game().type() != GameType::solo_king_jack
996         && vgi.game().type() != GameType::solo_king_queen
997         && vgi.game().type() != GameType::solo_koehler
998         && (   card.value() == Card::jack
999             || card.value() == Card::queen)
1000        ) { // a king is better, but has two points more
1001       modi -= 3;
1002     }
1003   }
1004 
1005   if(  (   vgi.game().type()==GameType::solo_king
1006         || vgi.game().type()==GameType::solo_king_jack
1007         || vgi.game().type()==GameType::solo_king_queen
1008         || vgi.game().type()==GameType::solo_koehler )
1009      && card.value() == Card::king )
1010     modi -= 2;
1011 
1012 
1013   if(  card.istrump()
1014      && (    vgi.game().type()==GameType::solo_king
1015          ||  vgi.game().type()==GameType::solo_queen
1016          ||  vgi.game().type()==GameType::solo_jack
1017         )
1018     )
1019     modi -= 4;
1020 
1021 #ifdef PLAYERCHECK
1022   if (vgi.no() == playerCheck) {
1023 
1024     COUT <<"MPS"<< modi << "\t";
1025 
1026   }
1027 #endif
1028   return modi;
1029 }
1030 
1031 /** Modification for other trump
1032  **/
1033 int
modi_other_trumps(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)1034 TrickWeighting::modi_other_trumps(VirtualGamesInterface const& vgi,
1035                                   Trick const& trick,
1036                                   Team const team,
1037                                   HandCard const& card,
1038                                   Team const winnerteam,
1039                                   Ai const& ai)
1040 {
1041   int modi = 0;
1042   Game const& virt_game = trick.game();
1043   Player const& ai_virt = virt_game.player(ai.no());
1044 
1045   if( !card.istrump () )
1046     return modi;
1047 
1048   if (   trick.startcard().istrump()
1049       // ToDo: solo
1050       && !card.less(Card::diamond_queen)
1051       && (static_cast<int>(trick.points()) >= ai.value(Aiconfig::Type::limitqueen)) ) {
1052     modi += 2;
1053   }
1054 
1055   if (is_solo(vgi.game().type())) {
1056     modi -= 2;
1057     if  (   vgi.is_soloplayer()
1058          && card.value() == 0) {
1059       modi -= 12;
1060     }
1061   }
1062 
1063   if(  (   vgi.no() != trick.winnerplayer().no()
1064         || trick.winnercardno() != 3)
1065      && trick.cardno_of_player(card.player()) == 3 ) {
1066     modi -= 5; // previous -2
1067   }
1068 
1069 
1070   // have played a high card
1071   if (   (   ai.value(Aiconfig::Type::limithigh).less(card)
1072           || ai.value(Aiconfig::Type::limithigh) == card)
1073       && (static_cast<int>(trick.points()) - card.value()
1074           < ai.value(Aiconfig::Type::limitqueen) ) )
1075   {
1076     modi -= 3;
1077     if ((2 * ai.hand().count_ge(ai.value(Aiconfig::Type::limithigh))
1078          < ai.hand().count_trumps())
1079         && (ai.hand().count_ge(ai.value(Aiconfig::Type::limithigh))
1080             < 3))
1081       modi -= 13; // previous: 18
1082   }
1083 
1084   if (   !trick.startcard().istrump()
1085       && (trick.cardno_of_player(card.player()) < 3)
1086       && card.less(ai.value(Aiconfig::Type::limithigh))
1087       && (static_cast<int>(trick.points()) >= ai.value(Aiconfig::Type::limitqueen))
1088       && trick.jabs_cards_before(card.player()) ) {
1089     modi -= 3;
1090     if ( vgi.color_runs( trick.startcard().color() ) > 0 )
1091       modi -= 6;
1092 
1093     if (   is_solo(vgi.game().type())
1094         && trick.cardno_of_player(trick.game().players().soloplayer()) > trick.cardno_of_player(card.player()) )
1095       modi -= 7; // reference 197069
1096   }
1097 
1098   if(   (card.value() == Card::ten)
1099      && (!card.isdulle()) ) {
1100     modi -= 10; // reference 246985
1101   }
1102 
1103   if(   (card.value() == Card::ace)
1104      && !card.is_special() ) {
1105     modi -= 9; // reference 246985
1106   }
1107 
1108   if(   (card.value() == Card::king)
1109      &&  (winnerteam != team) ) {
1110     modi -= 14; // reference 256027
1111   }
1112 
1113   if(   (card.value() == Card::nine)
1114      && !card.is_special()
1115      && trick.winnercardno() == 3
1116      && trick.cardno_of_player(card.player()) == 3 )
1117     modi -= 3; // reference 064027_1
1118 
1119 
1120   if ( virt_game.cards().next_higher_card(card).value() != card.value() //2do nect_higher_card_still_in_game compar reference 260689
1121      && (trick.cardno_of_player(trick.winnerplayer())
1122          > trick.cardno_of_player(card.player()))
1123      && trick.jabs_cards_before( card.player() ))
1124   { // a higher card in value is needed to jab my card
1125     // for example a queen to jab my jack
1126     modi += 1;
1127   }
1128 
1129 
1130   bool allmyteam=true;
1131 
1132   for( unsigned i = trick.cardno_of_player(ai_virt);
1133       i < ai.game().playerno();
1134       i++ )
1135     allmyteam=allmyteam && ( ai.team() == ::maybe_to_team( vgi.teamofplayer( trick.player_of_card(i) ) ) );
1136 
1137   if(   card.less( ai.value(Aiconfig::Type::limithigh) )
1138      && !trick.startcard().istrump()
1139      && (trick.cardno_of_player(trick.winnerplayer())
1140          > trick.cardno_of_player(card.player())
1141          && trick.jabs_cards_before( card.player() ) )
1142      && !(    trick.islastcard()
1143           || allmyteam )
1144     ) {
1145     modi -= card.value() * std::min(vgi.color_runs( trick.startcard().color() ),
1146                                     2u);
1147   }
1148 
1149   if (  (vgi.no() == trick.startplayer().no()))
1150   {
1151     modi -= 2;
1152 
1153     if( ai.hand().count_trumps() == ai.hand().cardsnumber()
1154        && card.value() < 3 )
1155       modi +=5; // Reference 012664
1156 
1157     if( (card.value() == Card::king)
1158        && (winnerteam == team) )
1159       modi += 8;
1160   }
1161 
1162   { // the player has overjabbed his partner without need
1163     if (trick.winnerplayer() == ai) {
1164       Trick const t2 = trick.before_player(ai);
1165       if (  (::maybe_to_team(t2.winnerplayer().team()) == ai.team())
1166           && (vgi.trump_card_limit().less(t2.winnercard()))
1167          ) {
1168         modi -= 8;
1169       }
1170     }
1171   } // the player has overjabbed his partner without need
1172 
1173 #ifdef PLAYERCHECK
1174   if (vgi.no() == playerCheck) {
1175     COUT <<"MOT"<< modi << "\t";
1176   }
1177 #endif
1178   return modi;
1179 }
1180 
1181 /** Modification for a forced trump
1182  **/
1183 int
modi_force_trump(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)1184 TrickWeighting::modi_force_trump(VirtualGamesInterface const& vgi,
1185                                  Trick const& trick,
1186                                  Team const team,
1187                                  HandCard const& card,
1188                                  Team const winnerteam,
1189                                  Ai const& ai)
1190 {
1191   int modi = 0;
1192 
1193   // force enemy to play high card
1194   if (   vgi.no() != trick.winnerplayer().no()
1195       && (trick.cardno_of_player(trick.winnerplayer())
1196           > trick.cardno_of_player(card.player())
1197           && trick.jabs_cards_before( card.player() ) )
1198       && ai.value(Aiconfig::Type::limithigh).less(trick.winnercard())
1199       && ai.team() != winnerteam )
1200   {
1201 
1202     bool bIsForceTrump = true;
1203     // ToDo: start with
1204     for (unsigned c = trick.cardno_of_player(card.player()) + 1; c < trick.actcardno(); c++)
1205     {
1206       if (!trick.card(c).less(card))
1207         bIsForceTrump = false;
1208     } // for(c)
1209     if ( bIsForceTrump )
1210       modi += 27;
1211   }
1212 
1213 #ifdef PLAYERCHECK
1214   if (vgi.no() == playerCheck) {
1215 
1216     COUT <<"MFT"<< modi << "\t";
1217 
1218   }
1219 #endif
1220   return modi;
1221 }
1222 
1223 /** Modification for a poverty
1224  **/
1225 int
modi_poverty(VirtualGamesInterface const & vgi,Trick const & trick,Team const team,HandCard const & card,Team const winnerteam,Ai const & ai)1226 TrickWeighting::modi_poverty(VirtualGamesInterface const& vgi,
1227                              Trick const& trick,
1228                              Team const team,
1229                              HandCard const& card,
1230                              Team const winnerteam,
1231                              Ai const& ai)
1232 {
1233   int modi = 0;
1234   if ( vgi.game().type() != GameType::poverty )
1235     return modi;
1236   Player const& ai_virt = trick.game().player(ai.no());
1237 
1238   if(    card.istrump()
1239      && trick.cardno_of_player(ai_virt) == 0)
1240     modi -= 3; // 1:reference 208016, 3: reference 194579
1241 
1242   //  get large cards of poverty player
1243   if((  //only for not poverty-player
1244       vgi.no() == vgi.game().players().poverty_partner().no() ))
1245   {
1246 
1247     if( (trick.cardno_of_player(trick.game().players().soloplayer()) > trick.cardno_of_player(card.player())) //
1248        && !card.less(ai.value(Aiconfig::Type::limithigh))
1249        &&  card.player().no() != vgi.game().players().previous(vgi.game().players().soloplayer()).no())
1250     {
1251       modi += 21;
1252       if( ai.value(Aiconfig::Type::limithigh).less(trick.winnercard()) )
1253         modi += 5;
1254       if ( trick.winnercard().isdulle()
1255           || trick.winnercard().isswine()
1256           || trick.winnercard().ishyperswine() )
1257         modi +=4;
1258     }
1259   }
1260 #ifdef PLAYERCHECK
1261   if (vgi.no() == playerCheck) {
1262     // 4. block
1263     COUT << "MPV" << modi << "\t";
1264   }
1265 #endif
1266 
1267   return modi;
1268 }
1269 
1270 /** -> result
1271  **
1272  ** @param    vgi   the virtual games interface
1273  ** @param    trick   the trick to be examined
1274  ** @param    t   the team which should make points
1275  ** @param    card    the card played by the player
1276  **
1277  ** @return   the weighting of the trick for the team 'team'
1278  **
1279  ** @todo       perhaps points for getting the fox home
1280  ** @todo       perhaps when playing the highest card, subtract in modi
1281  **   the distance to the next lower card
1282  **/
1283 int
modi(VirtualGamesInterface const & vgi,Trick const & trick,Team const t,HandCard const & card)1284 TrickWeighting::modi(VirtualGamesInterface const& vgi,
1285                      Trick const& trick,
1286                      Team const t,
1287                      HandCard const& card)
1288 {
1289   DEBUG_ASSERTION(trick.isfull(),
1290                   "TrickWeighting::modi()\n"
1291                   "  trick is not full");
1292   Game const& virt_game = trick.game();
1293   Ai const& ai = (dynamic_cast<Ai const*>(&virt_game.player(vgi.no()))
1294                   ? dynamic_cast<Ai const&>(virt_game.player( vgi.no() ))
1295                   : dynamic_cast<Ai const&>(vgi.game().player(vgi.no()))
1296                  );
1297   Player const& ai_virt = virt_game.player(ai.no());
1298   //Team const winnerteam = ai.teamofplayer(trick.winnerplayer());
1299   Team winnerteam
1300     = ::maybe_to_team(vgi.teamofplayer(trick.winnerplayer()));
1301   if (winnerteam == Team::unknown)
1302     winnerteam = ::opposite(t);
1303 
1304   if (virt_game.marriage().is_undetermined()) {
1305     // in an undetermined marriage all players shall play for themselves
1306     if (t == Team::re)
1307       winnerteam = ::maybe_to_team(ai.teaminfo(trick.winnerplayer()));
1308     else if (trick.winnerplayer().no() == vgi.no())
1309       winnerteam = ::maybe_to_team(t);
1310     else
1311       winnerteam = ::opposite(::maybe_to_team(t));
1312   }
1313 
1314 
1315   Team const team = ((virt_game.type() == GameType::marriage)
1316                      ? maybe_to_team(t)
1317                      : t);
1318 
1319   int modi = 0;
1320 
1321 
1322   if (winnerteam == team)
1323     modi += trick.points();
1324   else
1325     modi -= trick.points();
1326 
1327 #ifdef PLAYERCHECK
1328   // Playernumber for which to produce output
1329   playerCheck = PLAYERCHECK;
1330 
1331   // so in virtual games no informatin is shown
1332   if (vgi.game().isvirtual())
1333     playerCheck = 10;
1334 #endif
1335 
1336 
1337 
1338 
1339 #ifdef PLAYERCHECK
1340   if (vgi.no() == playerCheck) {
1341     //COUT << trick.game().player(0).hand();
1342     COUT << '\n';
1343     COUT << trick << endl;
1344     COUT << team << "\t" << trick.winnerplayer().no() << " " << winnerteam << std::endl;
1345     for( unsigned i = 0; i < ai.game().playerno(); i++ )
1346       COUT << virt_game.player( i ).team() << "\t";
1347     COUT << std::endl;
1348     // 1. block
1349     COUT << card << "\t";
1350   }
1351 #endif
1352 
1353 #ifdef PLAYERCHECK
1354   if (vgi.no() == playerCheck) {
1355 
1356     COUT << "START" << modi << "\t";
1357 
1358   }
1359 #endif
1360 
1361   modi += modi_dulle_swines( vgi, trick, t, card, winnerteam, ai );
1362 
1363   modi += modi_queen( vgi, trick, t, card, winnerteam, ai  );
1364 
1365   modi += modi_jack( vgi, trick, t, card, winnerteam, ai  );
1366 
1367   modi += modi_fox( vgi, trick, t, card, winnerteam, ai );
1368 
1369   modi += modi_soli_meat_less( vgi, trick, t, card, winnerteam, ai  );
1370 
1371   modi += modi_marriage( vgi, trick, t, card, winnerteam, ai  );
1372 
1373   modi += modi_special_points( vgi, trick, t, card, winnerteam, ai  );
1374 
1375   modi += modi_no_trump( vgi, trick, t, card, winnerteam, ai  );
1376 
1377   modi += modi_picture_soli( vgi, trick, t, card, winnerteam, ai  );
1378 
1379   modi += modi_other_trumps( vgi, trick, t, card, winnerteam, ai  );
1380 
1381   modi += modi_force_trump( vgi, trick, t, card, winnerteam, ai  );
1382 
1383   modi += modi_poverty( vgi, trick, t, card, winnerteam, ai  );
1384 
1385 
1386   bool allmyteam=true;
1387 
1388   for (auto i = trick.cardno_of_player(ai_virt);
1389        i < ai.game().playerno();
1390        i++ )
1391     allmyteam = allmyteam && ( ai.team() == ::maybe_to_team( vgi.teamofplayer( trick.player_of_card(i) ) ) );
1392 
1393   /// @todo jabbed by player of other team behind me
1394   if(   !trick.startcard().istrump()
1395      && vgi.jabbedbyotherteam( trick.startcard().color() )
1396      && card.value() >= 10
1397      && !allmyteam
1398      && oppositeTeamCanWinTrick( trick, vgi )
1399     ) {
1400     modi -= 4;
1401 #ifdef PLAYERCHECK
1402     if (vgi.no() == playerCheck) {
1403 
1404       COUT << "XX " << modi << "\t";
1405     }
1406 #endif
1407   }
1408 
1409 #ifdef PLAYERCHECK
1410   if (vgi.no() == playerCheck) {
1411     COUT << "END" << modi << endl;
1412   }
1413 #endif
1414 
1415   return modi;
1416 } // int WVirtualGames::modi(Trick const& trick, Team const& team, Card const& card)
1417 
1418 
1419 /** -> result
1420  **
1421  ** @param    vgi         virtual game interface
1422  ** @param    c           the card played by the player
1423  ** @param    virt_game   actual virtual game
1424  **
1425  ** @return   weighting modifier for getting own team in backhand
1426  **/
1427 int
backhand(VirtualGamesInterface const & vgi,HandCard const & c,Game const & virt_game)1428 TrickWeighting::backhand(VirtualGamesInterface const& vgi,
1429                          HandCard const& c,
1430                          Game const& virt_game )
1431 {
1432   int result = 0;
1433 
1434   // add some points, if the own team is in the back,
1435   if (virt_game.players().previous( virt_game.tricks().current().winnerplayer() ).team()
1436       == vgi.team() && !c.isfox() &&
1437       vgi.game().type() != GameType::solo_meatless )
1438   {
1439     result = 5;
1440 
1441     if( virt_game.tricks().current().points() > 10 )
1442       result -= 3;  // Bugreport reference 1236
1443 
1444     if (virt_game.type() == GameType::poverty )
1445       result -= 3;
1446   }
1447   else
1448     result = -6;
1449 
1450 
1451   return result;
1452 }
1453 
1454