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 "cards_information.of_player.h"
31 #include "cards_information.heuristics.h"
32 #include "ai.h"
33 
34 #include "../../party/rule.h"
35 #ifdef DEBUG_ASSERT
36 #include "../../card/trick.h"
37 #endif
38 #include "../../card/weighted_card_list.h"
39 
40 #ifdef CHECK_RUNTIME
41 #include "../../runtime.h"
42 #endif
43 
44 // whether to print information of the throwing
45 #ifndef RELEASE
46 #ifdef DKNOF
47 // whether to print information of the information flow
48 #define CONDITION_INFORMATION_FLOW \
49   false \
50   && (this->cards_information().player().no() == 1) \
51   && (this->playerno() == 3)
52 #define CONDITION_INFORMATION_ESTIMATED_HAND \
53   false \
54   && (this->cards_information().player().no() == 1) \
55   && (this->playerno() == 3)
56 
57 #endif
58 #endif
59 
60 /*
61  * CardsInformation::OfPlayer contains the information an ai has about the
62  * cards a specific player can / must / cannot have.
63  * The class contains four counters and a weighting
64  * - played
65  *   what cards the player has played
66  * - must have
67  *   which and how many cards the player must have
68  *   (p.e. if he has announced 're' and not played a club queen, he must
69  *    have one (but can have two) )
70  * - can have
71  *   which and how many cards the player can have at max
72  *   (p.e. if another player has annouced 're' he can only have one club queen)
73  * - does not have tcolor
74  *   just remembers the colors the player cannot have anymore
75  *   (because he could not serve).
76  *   This should not really be necessary anymore, but I feel more sure with this
77  *   code (should check someday)
78  * - cards weighting
79  *   According to the gameplay the cards are weighted.
80  *   positive weight means higher probability for the card,
81  *   negative weight means lower probability for the card.
82  *
83  * The easy part of the code is to add the information gotten by the game
84  * (see CardsInformation).
85  * Complicated is to update the information over the players.
86  * - if the cards a player has to play == the number he must have
87  *   the player can only have the cards he must have
88  *   (must have --> can have)
89  *   A bit more information is gained, like:
90  *     If the player has only one free card (the rest to play are 'must') he
91  *     can only have at most one card from each card he must not have).
92  * - if the cards a player has to play == the number he can have
93  *   the player must have the cards he can have
94  *   (can have --> must have)
95  *   This is analogous to the previous case, so here also a bit more information
96  *   can be gained (and yes, there was at least one case I needed this), p.e.
97  *     The player has to play two cards
98  *     and he can have one diamond jack and two heart jacks,
99  *     he must have at least one heart jack.
100  * - count data for a single card
101  *   Sum up how many times the card was played and the other players must have
102  *   it. Then the player can at max have the remaining number of cards.
103  *   If p.e. a player has announced 're' he must have a club queen. So the other
104  *     players can only have at max one club queen in their hands.
105  *   And again this can be viewed from the opposite side:
106  *   If for a card the sum of 'played' and 'can have' of the other players
107  *   are less than two, then the player must have the remaining ones.
108  *   A simple (and most common) example is that three players do not have
109  *   spade, so the fourth player must have all remaining spade cards.
110  */
111 
112 /** constructor
113  **
114  ** @param    cards_information   corresponding cards information
115  ** @param    playerno   number of the player of this information
116  **/
OfPlayer(CardsInformation & cards_information,unsigned const playerno)117 CardsInformation::OfPlayer::OfPlayer(CardsInformation& cards_information,
118                                      unsigned const playerno) :
119   cards_information_(&cards_information),
120   playerno_(playerno)
121 { this->reset(); }
122 
123 /** copy constructor
124  **
125  ** @param    of_player   object to be copied
126  **/
127 CardsInformation::OfPlayer::OfPlayer(OfPlayer const& of_player) = default;
128 
129 /** copy operator
130  **
131  ** @param    of_player   object to be copied
132  **
133  ** @return   object
134  **/
135 CardsInformation::OfPlayer&
136 CardsInformation::OfPlayer::operator=(OfPlayer const& of_player) = default;
137 
138 /** destructor
139  **/
140 CardsInformation::OfPlayer::~OfPlayer() = default;
141 
142 /** resets all information
143  **/
144 void
reset()145 CardsInformation::OfPlayer::reset()
146 {
147   // cards
148   this->played_.clear();
149   this->must_have_.clear();
150   this->cards_weighting_.clear();
151   for (const auto & c : this->game().rule().cards()) {
152     this->can_have_.set(c, this->game().rule()(Rule::Type::number_of_same_cards));
153     this->cards_weighting_[c] = 0;
154   } // for (c \in cards)
155 
156   // tcolors
157   this->tcolor_played_.clear();
158   this->tcolor_must_have_.clear();
159   for (unsigned c = 0; c < Card::number_of_tcolors; ++c)
160     this->tcolor_can_have_.set(static_cast<Card::TColor>(c),
161                                min(this->game().rule()(Rule::Type::number_of_cards_on_hand),
162                                    this->game().cards().count(static_cast<Card::TColor>(c))));
163 
164   return ;
165 } // void CardsInformation::OfPlayer::reset()
166 
167 /** writes 'of_player' in 'ostr'
168  **
169  ** @param    ostr   output stream
170  ** @param    of_player   object to write into 'ostr'
171  **
172  ** @return   the output stream
173  **/
174 ostream&
operator <<(ostream & ostr,CardsInformation::OfPlayer const & of_player)175 operator<<(ostream& ostr, CardsInformation::OfPlayer const& of_player)
176 {
177   of_player.write(ostr);
178   return ostr;
179 } // ostream& operator<<(ostream& ostr, CardsInformation::OfPlayer of_player)
180 
181 /** writes 'of_player' in 'ostr'
182  **
183  ** @param    ostr   output stream
184  **/
185 void
write(ostream & ostr) const186 CardsInformation::OfPlayer::write(ostream& ostr) const
187 {
188   ostr << "player = " << this->playerno() << " (" << this->player().name() << ")\n";
189 
190   ostr << "{\n";
191 
192   ostr << "  played\n"
193     << "  {\n"
194     << this->played_
195     << "  }\n";
196 
197   ostr << "  must_have\n"
198     << "  {\n"
199     << this->must_have_
200     << "  }\n";
201 
202   ostr << "  can_have\n"
203     << "  {\n"
204     << "cardno = " << this->can_have_.cards_no() << '\n';
205   for (const auto & c : this->game().rule().cards()) {
206     if (this->can_have(c) > 0) {
207       ostr << setw(14)
208         << c << " = "
209         << this->can_have(c) << ' '
210         << "(" << this->weighting(c, false) << ")\n";
211     }
212   } // for (c \in cards)
213   ostr << "  }\n";
214 
215   ostr << "  tcolors played\n"
216     << "  {\n"
217     << this->tcolor_played_
218     << "  }\n";
219 
220   ostr << "  tcolors must_have\n"
221     << "  {\n"
222     << this->tcolor_must_have_
223     << "  }\n";
224 
225   ostr << "  tcolors can_have\n"
226     << "  {\n"
227     << this->tcolor_can_have_
228     << "  }\n";
229 
230   ostr << '\n';
231   ostr << "estimated hand\n"
232     << this->estimated_hand() << '\n';
233   ostr << "}\n";
234 
235   return ;
236 } // void CardsInformation::OfPlayer::write(ostream& ostr) const
237 
238 /** @return   the corresponding cards information
239  **/
240 CardsInformation const&
cards_information() const241 CardsInformation::OfPlayer::cards_information() const
242 { return *this->cards_information_; }
243 
244 /** @return   the corresponding cards information
245  **/
246 CardsInformation&
cards_information()247 CardsInformation::OfPlayer::cards_information()
248 { return *this->cards_information_; }
249 
250 /** @return   the number of the player
251  **/
252 unsigned
playerno() const253 CardsInformation::OfPlayer::playerno() const
254 { return this->playerno_; }
255 
256 /** @return   the corresponding game
257  **/
258 Game const&
game() const259 CardsInformation::OfPlayer::game() const
260 {
261   return this->cards_information().game();
262 }
263 
264 /** @return   the corresponding player
265  **/
266 Player const&
player() const267 CardsInformation::OfPlayer::player() const
268 {
269   return this->game().player(this->playerno());
270 }
271 
272 /** sets the corresponding cards information
273  **
274  ** @param    cards_information   new cards information
275  **/
276 void
set_cards_information(CardsInformation & cards_information)277 CardsInformation::OfPlayer::set_cards_information(CardsInformation&
278                                                   cards_information)
279 { this->cards_information_ = &cards_information; }
280 
281 /** @return   whether all cards are known
282  **/
283 bool
all_known() const284 CardsInformation::OfPlayer::all_known() const
285 {
286   return (this->can_have_.cards_no() == this->must_have_.cards_no());
287 }
288 
289 /** -> result
290  **
291  ** @param    card   card
292  **
293  ** @return   how many of 'card' the player has played
294  **/
295 unsigned
played(Card const card) const296 CardsInformation::OfPlayer::played(Card const card) const
297 {
298   return this->played_[card];
299 }
300 
301 /** -> result
302  **
303  ** @param    tcolor   tcolor
304  **
305  ** @return   how many cards of the tcolor 'tcolor' the player has played
306  **/
307 unsigned
played(Card::TColor const tcolor) const308 CardsInformation::OfPlayer::played(Card::TColor const tcolor) const
309 {
310   DEBUG_ASSERTION(tcolor != Card::unknowncardcolor,
311                   "CardsInformation::OfPlayer::played(" << tcolor << ")\n"
312                   "  tcolor 'unknown' is forbidden");
313 
314   return this->tcolor_played_[tcolor];
315 }
316 
317 /** -> result
318  **
319  ** @param    card   card
320  **
321  ** @return   how many cards of 'card' the player must still have on the hand
322  **/
323 unsigned
must_have(Card const card) const324 CardsInformation::OfPlayer::must_have(Card const card) const
325 {
326   return this->must_have_[card];
327 }
328 
329 /** -> result
330  **
331  ** @param    tcolor    tcolor
332  **
333  ** @return   how many cards of 'tcolor' the player must still have on the hand
334  **/
335 unsigned
must_have(Card::TColor const tcolor) const336 CardsInformation::OfPlayer::must_have(Card::TColor const tcolor) const
337 {
338   DEBUG_ASSERTION(tcolor != Card::unknowncardcolor,
339                   "CardsInformation::OfPlayer::must_have(" << tcolor << ")\n"
340                   "  tcolor 'unknown' is forbidden");
341   return this->tcolor_must_have_[tcolor];
342 }
343 
344 /** -> result
345  **
346  ** @param    card   card
347  **
348  ** @return   how many cards of 'card' the player can still have on the hand
349  **/
350 unsigned
can_have(Card const card) const351 CardsInformation::OfPlayer::can_have(Card const card) const
352 {
353   return this->can_have_[card];
354 }
355 
356 /** -> result
357  **
358  ** @param    tcolor    tcolor
359  **
360  ** @return   how many cards of 'tcolor' the player can still have on the hand
361  **/
362 unsigned
can_have(Card::TColor const tcolor) const363 CardsInformation::OfPlayer::can_have(Card::TColor const tcolor) const
364 {
365   DEBUG_ASSERTION(tcolor != Card::unknowncardcolor,
366                   "CardsInformation::OfPlayer::can_have(" << tcolor << ")\n"
367                   "  tcolor 'unknown' is forbidden");
368   return this->tcolor_can_have_[tcolor];
369 }
370 
371 /** -> result
372  **
373  ** @param    card   card
374  **
375  ** @return   whether the player cannot have the card still on the hand
376  **/
377 bool
cannot_have(Card const card) const378 CardsInformation::OfPlayer::cannot_have(Card const card) const
379 {
380   return (this->can_have(card) == 0);
381 }
382 
383 /** -> result
384  **
385  ** @param    tcolor   tcolor to check
386  **
387  ** @return   whether the player does not have anymore the tcolor
388  **/
389 bool
does_not_have(Card::TColor const tcolor) const390 CardsInformation::OfPlayer::does_not_have(Card::TColor const tcolor) const
391 {
392   return (this->can_have(tcolor) == 0);
393 }
394 
395 /** -> result
396  **
397  ** @param    card   card
398  **
399  ** @return   the number of unkown cards 'card'
400  **/
401 unsigned
unknown(Card const card) const402 CardsInformation::OfPlayer::unknown(Card const card) const
403 {
404   return (this->can_have(card) - this->must_have(card));
405 }
406 
407 /** -> result
408  **
409  ** @param    tcolor    tcolor
410  **
411  ** @return   the number of unknown cards of 'tcolor'
412  **/
413 unsigned
unknown(Card::TColor const tcolor) const414 CardsInformation::OfPlayer::unknown(Card::TColor const tcolor) const
415 {
416   return (this->can_have(tcolor) - this->must_have(tcolor));
417 }
418 
419 /** -> result
420  **
421  ** @param    card     card
422  ** @param    modify   whether to modify the weighting (t.i. of the club queen) (default: true)
423  **
424  ** @return   weighting for the card
425  **             positive means more probability for having the card
426  **/
427 int
weighting(Card const card,bool const modify) const428 CardsInformation::OfPlayer::weighting(Card const card, bool const modify) const
429 {
430   if (this->cannot_have(card))
431     return 0;
432 
433   int modifier = 0;
434 
435   // take the announcement into account:
436   // if the player has announced, he will likely have less color cards
437   if (!card.istrump(this->game())) {
438     switch (this->game().announcements().last(this->player()).announcement) {
439     case Announcement::reply:
440     case Announcement::no120_reply:
441       modifier -= 10;
442       break;
443     case Announcement::no120:
444       modifier -= 15;
445       break;
446     case Announcement::no90:
447       modifier -= 30;
448       break;
449     case Announcement::no60:
450       modifier -= 100;
451       break;
452     case Announcement::no30:
453       modifier -= 500;
454       break;
455     case Announcement::no0:
456       modifier -= 1000;
457       break;
458     default:
459       break;
460     } // switch (announcement)
461   } // if (!card.istrump(this->game()))
462 
463   if (modify) {
464     if (   (card == Card::club_queen)
465         && (this->game().type() == GameType::normal) ) {
466       modifier += (10 // *Value*
467                    * this->cards_information().player().team_information().team_value(this->playerno()));
468       if (maybe_to_team(this->cards_information().player().team_information().team(this->playerno())) == Team::re) {
469         if (this->played(Card::club_queen))
470           modifier -= 500;
471         else
472           modifier += 1000;
473       } else if (maybe_to_team(this->cards_information().player().team_information().team(this->playerno())) == Team::contra)
474         modifier -= 1000;
475     } // if (club queen in normal game)
476   } // if (modify)
477 
478   return (this->cards_weighting_[card] + modifier);
479 } // int CardsInformation::OfPlayer::weighting(Card card, bool modify = true) const
480 
481 /** @return   the cards the player has played
482  **/
483 Hand
played_cards() const484 CardsInformation::OfPlayer::played_cards() const
485 {
486   Hand cards(this->player());
487 
488   for (const auto & c : this->played_.cards())
489     cards.add(c);
490 
491   return cards;
492 }
493 
494 /** @return   the cards the player must have
495  **/
496 Hand
must_have_cards() const497 CardsInformation::OfPlayer::must_have_cards() const
498 {
499   Hand cards(this->player());
500 
501   for (const auto & c : this->must_have_.cards())
502     cards.add(c);
503 
504   return cards;
505 }
506 
507 /** @return   the cards the player cannot have
508  **/
509 Hand
cannot_have_cards() const510 CardsInformation::OfPlayer::cannot_have_cards() const
511 {
512   Hand cards(this->player());
513 
514   for (const auto & c : this->game().rule().cards()) {
515     for (unsigned i = 0;
516          i < this->game().rule()(Rule::Type::number_of_same_cards) - this->can_have(c);
517          ++i) {
518       cards.add(c);
519     }
520   }
521 
522   return cards;
523 }
524 
525 /** @return   the possible hand of the player
526  **
527  ** @todo   check whether the cards the player must have are as many as the
528  **   player can only have
529  ** @todo   add the played cards
530  **/
531 Hand
possible_hand() const532 CardsInformation::OfPlayer::possible_hand() const
533 {
534   DEBUG_ASSERTION((this->can_have_.cards_no()
535                    >= this->player().cards_to_play()),
536                   "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::possible_hand():\n"
537                   "  can_have.cards_no() = " << this->can_have_.cards_no()
538                   << " < " << this->player().cards_to_play()
539                   << " = this->player().cards_to_play()");
540 
541   DEBUG_ASSERTION((this->can_have_.cards().size()
542                    == this->can_have_.cards_no()),
543                   "CardsInformation::OfPlayer::possible_hand():\n"
544                   "  the number of cards is not valid");
545 
546   return Hand(this->player(),
547               this->can_have_.cards(), this->played_.cards());
548 }
549 
550 /** -> result
551  ** the estimation is based by the weighting
552  **
553  ** @return   estimated hand for the player
554  **
555  ** @todo       check tcolor (can have, must have)
556  ** @todo       better alogrithm for the estimation
557  ** @todo       ensure, that all cards are distributed
558  ** @todo       ensure, that each player has enough cards
559  ** @todo       maybe contra -> no club queen
560  ** @todo       two re -> both one club queen
561  **/
562 Hand
estimated_hand() const563 CardsInformation::OfPlayer::estimated_hand() const
564 {
565 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
566   if (CONDITION_INFORMATION_ESTIMATED_HAND) {
567     clog << __FILE__ << '#' << __LINE__ << "  " << "start CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->player().no() << ")::estimate_hand()\n";
568   }
569 #endif
570 
571   if (this->cards_information().player().value(Aiconfig::Type::hands_known))
572     return this->player().hand();
573 
574   Hand hand(this->player());
575 
576   // start with the played cards
577   hand.add_played(this->played_.cards());
578 
579 #ifdef WORKAROUND
580   // all cards known
581   if (this->can_have_.cards_no() == this->player().cards_to_play()) {
582     hand.add(this->can_have_.cards());
583     return hand;
584   }
585 #endif
586 
587   auto const& game = this->game();
588   auto const& rule = game.rule();
589 
590   { // 1) add all 'must have' cards
591     // ToDo: use must_have for the cards directly
592     for (auto c : rule.cards()) {
593       hand.add(c, this->must_have(c));
594     }
595 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
596     if (CONDITION_INFORMATION_ESTIMATED_HAND) {
597       //clog << __FILE__ << '#' << __LINE__ << "  " << "hand after 1) must have\n" << hand << '\n';
598     }
599 #endif
600   } // 1) add all 'must have' cards
601 
602   // all cards of the player are known
603   if (hand.cardsnumber() == this->player().cards_to_play())
604     return hand;
605 
606   // the cards to distribute
607   WeightedCardList cards(this->game());
608   { // Put all remaining can_have-cards in the list 'cards'.
609     for (const auto & c : rule.cards()) {
610       if (this->cannot_have(c))
611         continue;
612       int w = INT_MIN; // the weighting from the other players
613       // take the weighting of the other players into account
614       for (unsigned p = 0; p < game.playerno(); ++p) {
615         if (   (p != this->playerno())
616             && this->cards_information().of_player(p).unknown(c)) {
617           w = max(w, this->cards_information().of_player(p).weighting(c));
618         }
619       } // for (p)
620 
621       // '2 * i' reflects the probability to have two of the same cards
622       for (int i = 0;
623 #ifdef WORKAROUND
624            // ToDo: remaining(*c) should always be >= can_have(*c)
625            i < static_cast<int>(min(this->can_have(c) - this->must_have(c),
626                                     this->cards_information().remaining_unknown(c)));
627 #else
628            i < static_cast<int>(this->can_have(*c) - this->must_have(*c));
629 #endif
630            ++i) {
631         if (w == INT_MIN) {
632           cards.add(c, INT_MAX);
633           continue;
634         }
635         if (   (c == Card::club_queen)
636             && (this->game().type() == GameType::normal) ) {
637           // in a normal game, a player will most surely not have two club queens
638           cards.add(c,
639                     this->weighting(c)
640                     - w / static_cast<int>(this->cards_information().remaining_unknown(c))
641                     - 10000 * (i + this->must_have(c))); // *Value*
642         } else {
643           cards.add(c,
644                     this->weighting(c)
645                     - w / static_cast<int>(this->cards_information().remaining_unknown(c))
646                     - 10 * i); // *Value*
647         }
648       }
649     } // for (c \in cards)
650   } // Put all remaining can_have-cards in the list 'cards'.
651 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
652   if (CONDITION_INFORMATION_ESTIMATED_HAND) {
653     clog << __FILE__ << '#' << __LINE__ << "  " << "weighted cards\n" << cards << '\n';
654   }
655 #endif
656 
657   { // 2) add to each player the cards with the greates weighting
658     // (a card can be distributed multible times)
659     // Now fill up the hand in the order of weighting.
660     while (   !cards.empty()
661            // '- 1' here, so that in the next block 'w' is the right weighting
662            // (the next card is always added)
663            && (hand.cardsnumber() + 1 < this->player().cards_to_play()) ) {
664 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
665       if (CONDITION_INFORMATION_ESTIMATED_HAND) {
666         clog << __FILE__ << '#' << __LINE__ << "  " << "2a) add card " << cards.highest() << '\n';
667       }
668 #endif
669       hand.add(cards.highest());
670       cards.pop_highest();
671     }
672 
673     // Also add the cards with a weighting nearly the same as the lowest so far.
674     int const w = cards.highest_weighting();
675     while (   !cards.empty()
676            && (cards.highest_weighting() > w - 40)) { // *Value*
677 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
678       if (CONDITION_INFORMATION_ESTIMATED_HAND) {
679         clog << __FILE__ << '#' << __LINE__ << "  " << "2b) add card " << cards.highest() << '\n';
680       }
681 #endif
682       hand.add(cards.highest());
683       cards.pop_highest();
684     }
685   } // 2) add each player the cards with the greates weighting
686 
687   { // 3) for each color add enough cards according to 'tcolor_must_have' and 'tcolor_can_have'
688     // single tcolors
689     for (unsigned tc = 0; tc < Card::number_of_tcolors; ++tc) {
690       Card::TColor tcolor = static_cast<Card::TColor>(tc);
691       unsigned n = hand.count(tcolor);
692       unsigned const min = this->must_have(tcolor);
693       if (n >= min)
694         continue;
695       // add at least 'min' cards of 'tcolor'
696       while (!cards.highest(tcolor).is_empty()
697              && (n + 1 < min)) {
698 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
699         if (CONDITION_INFORMATION_ESTIMATED_HAND) {
700           clog << __FILE__ << '#' << __LINE__ << "  " << "3) add card " << cards.highest(tcolor) << '\n';
701         }
702 #endif
703         hand.add(cards.highest(tcolor));
704         cards.pop_highest(tcolor);
705         n += 1;
706       }
707 
708       // Also add the cards with a weighting nearly the same as the lowest so far.
709       int const w = cards.highest_weighting(tcolor);
710       while (   !cards.highest(tcolor).is_empty()
711              && (cards.highest_weighting(tcolor) > w - 40)) { // *Value*
712 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
713         if (CONDITION_INFORMATION_ESTIMATED_HAND) {
714           clog << __FILE__ << '#' << __LINE__ << "  " << "3) add card " << cards.highest(tcolor) << '\n';
715         }
716 #endif
717         hand.add(cards.highest(tcolor));
718         cards.pop_highest(tcolor);
719       }
720     } // for (tcolor)
721 
722     // single tcolors inverted
723     for (unsigned tc = 0; tc < Card::number_of_tcolors; ++tc) {
724       Card::TColor tcolor = static_cast<Card::TColor>(tc);
725       if (this->player().cards_to_play() <= this->can_have(tcolor))
726         continue;
727       unsigned n = hand.cardsnumber() - hand.count(tcolor);
728       unsigned const min = (this->player().cards_to_play()
729                             - this->can_have(tcolor));
730       if (n >= min)
731         continue;
732       if (cards.cards_no() < min - n) {
733         DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
734           << ")::OfPlayer(" << this->playerno() << ")::"
735           << "throw in estimated_hand()\n";
736         DEBUG_THROW(InvalidGameException, InvalidGameException());
737       } // if (cards.size() < min - n)
738 
739       // add at least 'min' cards of not 'tcolor'
740       while (!cards.highest_not_of(tcolor).is_empty()
741              && (n + 1 < min)) {
742 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
743         if (CONDITION_INFORMATION_ESTIMATED_HAND) {
744           clog << __FILE__ << '#' << __LINE__ << "  " << "3) add card " << cards.highest_not_of(tcolor) << '\n';
745         }
746 #endif
747         hand.add(cards.highest_not_of(tcolor));
748         cards.pop_highest_not_of(tcolor);
749         n += 1;
750       }
751 
752       // Also add the cards with a weighting nearly the same as the lowest so far.
753       int const w = cards.highest_weighting(tcolor);
754       while (   !cards.highest_not_of(tcolor).is_empty()
755              && (cards.highest_weighting_not_of(tcolor) > w - 40)) { // *Value*
756 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
757         if (CONDITION_INFORMATION_ESTIMATED_HAND) {
758           clog << __FILE__ << '#' << __LINE__ << "  " << "3) add card " << cards.highest_not_of(tcolor) << '\n';
759         }
760 #endif
761         hand.add(cards.highest_not_of(tcolor));
762         cards.pop_highest_not_of(tcolor);
763       }
764     } // for (tcolor)
765   } // 3) for each color add enough cards according to 'tcolor_must_have' and 'tcolor_can_have'
766 
767   { // 4) add the cards this player has the greates weighting of
768     // this must be the last part to make use of 'cards', since 'cards' is empty after this part
769 
770     while (!cards.empty()) {
771       Card const& card = cards.highest();
772       // player with the maximal weighting
773       int weighting_max = INT_MIN;
774       for (unsigned p = 0; p < game.playerno(); ++p) {
775         if (   !this->cards_information().of_player(p).all_known()
776             && this->cards_information().of_player(p).can_have(card)
777             && (this->cards_information().of_player(p).weighting(card)
778                 > weighting_max) )
779           weighting_max
780             = this->cards_information().of_player(p).weighting(card);
781       }
782 
783 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
784       if (CONDITION_INFORMATION_ESTIMATED_HAND) {
785         clog << __FILE__ << '#' << __LINE__ << "  " << "4) " << setw(5) << cards.highest_weighting() << " -- "
786           << setw(5) << weighting_max << " - 40: " << card << '\n';
787       }
788 #endif
789       if (cards.highest_weighting() >= weighting_max - 40) { // *Value* (same below, 2 times)
790 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
791         if (CONDITION_INFORMATION_ESTIMATED_HAND) {
792           clog << __FILE__ << '#' << __LINE__ << "  " << "4) add card " << card << '\n';
793         }
794 #endif
795         hand.add(card);
796       }
797 
798       cards.pop_highest();
799     } // while (!cards.empty())
800   } // 4) add the cards this player has the greates weighting of
801 
802 #ifdef CONDITION_INFORMATION_ESTIMATED_HAND
803   if (CONDITION_INFORMATION_ESTIMATED_HAND) {
804     clog << __FILE__ << '#' << __LINE__ << "  " << "end CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->player().no() << ")::estimate_hand()\n";
805   }
806 #endif
807 
808   return hand;
809 } // Hand CardsInformation::OfPlayer::estimated_hand() const
810 
811 /** -> result
812  **
813  ** @param    hand   hand to check
814  **
815  ** @return   whether the hand is valid
816  **/
817 bool
hand_valid(Hand const & hand) const818 CardsInformation::OfPlayer::hand_valid(Hand const& hand) const
819 {
820   map<Card, unsigned> const counter = hand.counted_cards();
821 
822   for (auto const& c : counter) {
823     Card const& card = c.first;
824     unsigned const& n = c.second;
825     if (!(   (this->must_have(card) <= n)
826           && (this->can_have(card) >= n)) )
827       return false;
828   } // for (c : counter)
829 
830   for (unsigned c = 0; c < Card::number_of_tcolors; ++c) {
831     Card::TColor const tcolor = static_cast<Card::TColor>(c);
832     unsigned const n = hand.count(tcolor);
833     if (!(   (this->must_have(tcolor) <= n)
834           && (this->can_have(tcolor) >= n)) )
835       return false;
836   } // for (c < Card::number_of_tcolors)
837 
838   return true;
839 } // bool CardsInformation::OfPlayer::hand_valid(Hand hand) const
840 
841 /** the game starts
842  **/
843 void
game_start()844 CardsInformation::OfPlayer::game_start()
845 {
846 #ifdef CONDITION_INFORMATION_FLOW
847   if (CONDITION_INFORMATION_FLOW)
848     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::game_start()\n";
849 #endif
850   switch (this->game().type()) {
851   case GameType::marriage:
852     if (this->player() == this->game().players().soloplayer()) {
853       this->add_must_have(Card::club_queen, 2);
854       // tcolor is set in CardsInformation::do_update()
855     }
856     break;
857   case GameType::poverty:
858     /// the player who takes the poverty
859     if (this->player() == this->game().players().poverty_partner())
860       CardsInformationHeuristics::poverty_returned
861         (this->player(),
862          this->cards_information().player(),
863          this->cards_weighting_,
864          this->game().poverty().returned_trumpno());
865     if (this->player() == this->game().players().soloplayer())
866       if (this->game().poverty().returned_trumpno() == 0)
867         this->add_must_exactly_have(Card::trump, this->game().poverty().returned_trumpno());
868     break;
869   default:
870     break;
871   } // switch (this->game().type())
872 
873   return ;
874 } // void CardsInformation::OfPlayer::game_start()
875 
876 /** the player has played 'card'
877  **
878  ** @param    card   card that has been played
879  ** @param    trick   current trick
880  **/
881 void
card_played(HandCard const & card,Trick const & trick)882 CardsInformation::OfPlayer::card_played(HandCard const& card,
883                                         Trick const& trick)
884 {
885   if (card.is_unknown()) {
886     this->played_.inc(card);
887     this->tcolor_played_.inc(card.tcolor());
888     return ;
889   }
890 
891 #ifdef CONDITION_INFORMATION_FLOW
892   if (CONDITION_INFORMATION_FLOW)
893     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
894       << "card_played(card = " << card << ", trick)\n";
895 #endif
896   if (!this->can_have(card)) {
897 #ifdef DEBUG_ASSERT
898     if (!this->cards_information().is_virtual()) {
899       cerr << "--\n"
900         << __FILE__ << "#" << __LINE__ << ": "
901         << "Error in 'CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")"
902         << "::card_played(" << card << ")\n";
903       cerr << '\n';
904       cerr << "trick " << this->game().tricks().current_no() << '\n';
905       cerr << card.game().tricks().current() << '\n';
906       cerr << '\n';
907       cerr << this->cards_information() << endl;
908       cerr << "Hand:\n" << this->player().hand();
909       cerr << '\n';
910       //cerr << *this;
911       cerr << endl;
912     }
913 #endif
914     DEBUG_ASSERTION(this->cards_information().is_virtual(),
915                     "CardsInformation"
916                     << "(" << this->cards_information().player().no() << ")"
917                     << "::OfPlayer(" << this->playerno() << ")"
918                     << "::card_played(" << card << "):\n"
919                     "  card cannot be on the hand.\n"
920                     << "  trick = " << this->game().tricks().current_no() << '\n'
921                     //<< "  Game:\n" << this->game()
922                     //<< "  Information:\n" << this->cards_information()
923                     //<< "  Hand:\n" << this->player().hand()
924                    );
925     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
926       << ")::OfPlayer(" << this->playerno() << ")::"
927       << "throw in card_played(" << card << ", trick" << ")\n"
928       << trick;
929     DEBUG_THROW(InvalidGameException, InvalidGameException());
930   } // if (!this->can_have(card))
931 
932   this->played_.inc(card);
933   if (this->must_have(card))
934     this->must_have_.dec(card);
935   this->can_have_.dec(card);
936   Card::TColor const tcolor = card.tcolor();
937   this->tcolor_played_.inc(tcolor);
938   if (this->must_have(tcolor))
939     this->tcolor_must_have_.dec(tcolor);
940   this->tcolor_can_have_.dec(tcolor);
941 
942   if (!this->cards_information().in_recalcing)
943     this->update_remaining_cards();
944 
945   return ;
946 } // void CardsInformation::OfPlayer::card_played(HandCard card, Trick trick)
947 
948 /** change the weightings according to the played card
949  ** call some heuristics which
950  **
951  ** @param    card    played_card
952  ** @param    trick   current trick
953  **
954  ** @todo      better name: all cards can be weighted
955  **/
956 void
weight_played_card(HandCard const & card,Trick const & trick)957 CardsInformation::OfPlayer::weight_played_card(HandCard const& card,
958                                                Trick const& trick)
959 {
960   // no information from unknown cards
961   if (card.is_unknown())
962     return ;
963   // I do not get more information from my own cardplay
964   if (card.player() == this->cards_information().player())
965     return ;
966 
967 #ifdef CONDITION_INFORMATION_FLOW
968   if (CONDITION_INFORMATION_FLOW)
969     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
970       << "weight_played_card(card = " << card << ", trick)\n";
971 #endif
972 
973   CardsInformationHeuristics::card_played(card, trick,
974                                           this->cards_information().player(),
975                                           this->cards_weighting_);
976 
977   return ;
978 } // void CardsInformation::OfPlayer::weight_played_card(HandCard const& card)
979 
980 /** adds the information that the player must have the card 'no' times
981  **
982  ** @param    card   card that the player must have
983  ** @param    no   how many times the player must have the card
984  **   default: 1
985  **/
986 void
add_must_have(Card const card,unsigned const no)987 CardsInformation::OfPlayer::add_must_have(Card const card, unsigned const no)
988 {
989 #ifdef CONDITION_INFORMATION_FLOW
990   if (CONDITION_INFORMATION_FLOW) {
991     if (this->must_have(card) < no) {
992       cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
993         << "add_must_have(card = " << card << ", no = " << no << ")\n";
994     }
995   }
996 #endif
997   if (no > this->can_have(card)) {
998     DEBUG_ASSERTION(this->cards_information().is_virtual(),
999                     "CardsInformation"
1000                     << "(" << this->cards_information().player().no() << ")"
1001                     << "::OfPlayer(" << this->playerno() << ")"
1002                     << "::add_must_have(" << card << ", " << no << ")\n"
1003                     "  player = " << this->playerno() << "\n"
1004                     "  can_have(" << card << ") = " << this->can_have(card)
1005                     << " < " << no << " = no");
1006     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1007       << ")::OfPlayer(" << this->playerno() << ")::"
1008       << "throw in add_must_have(" << card << ", " << no << ")\n";
1009     DEBUG_THROW(InvalidGameException, InvalidGameException());
1010   } // if (no > this->can_have(card))
1011 
1012   if (this->must_have_.min_set(card, no))
1013     this->cards_information().queue_update(card);
1014 
1015   return ;
1016 } // void CardsInformation::OfPlayer::add_must_have(Card card, unsigned no = 1)
1017 
1018 /** adds the information that the player must have the cards
1019  **
1020  ** @param    cards   cards the player must have
1021  **/
1022 void
add_must_have(vector<Card> const & cards)1023 CardsInformation::OfPlayer::add_must_have(vector<Card> const& cards)
1024 {
1025   map<Card, unsigned> number;
1026   for (const auto & card : cards)
1027     number[card] += 1;
1028 
1029   for (map<Card, unsigned>::const_iterator n = number.begin();
1030        n != number.end();
1031        ++n)
1032     this->add_must_have(n->first, n->second);
1033 
1034   return ;
1035 } // void CardsInformation::OfPlayer::add_must_have(vector<Card> cards)
1036 
1037 /** adds the information that the player must have the tcolor 'no' times
1038  **
1039  ** @param    tcolor   tcolor that the player must have
1040  ** @param    no       how many times the player must have the tcolor
1041  **/
1042 void
add_must_have(Card::TColor const tcolor,unsigned const no)1043 CardsInformation::OfPlayer::add_must_have(Card::TColor const tcolor,
1044                                           unsigned const no)
1045 {
1046 #ifdef CONDITION_INFORMATION_FLOW
1047   if (CONDITION_INFORMATION_FLOW) {
1048     if (this->must_have(tcolor) < no) {
1049       cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1050         << "add_must_have(tcolor = " << tcolor << ", no = " << no << ")\n";
1051     }
1052   }
1053 #endif
1054 
1055   if (no > this->can_have(tcolor)) {
1056     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1057                     "CardsInformation"
1058                     << "(" << this->cards_information().player().no() << ")"
1059                     << "::OfPlayer(" << this->playerno() << ")"
1060                     << "::add_must_have(" << tcolor << ", " << no << "):\n"
1061                     "  no = " << no << " < " << this->can_have(tcolor) << " = can have\n"
1062                     "  player = " << this->playerno());
1063     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1064       << ")::OfPlayer(" << this->playerno() << ")::"
1065       << "throw in add_must_have(" << tcolor << ", " << no << ")\n";
1066     DEBUG_THROW(InvalidGameException, InvalidGameException());
1067   } // if (no < this->must_have(card))
1068 
1069   if (this->tcolor_must_have_.cards_no()
1070       - this->must_have(tcolor)
1071       + no
1072       > this->player().cards_to_play() ) {
1073     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1074                     "CardsInformation"
1075                     << "(" << this->cards_information().player().no() << ")"
1076                     << "::OfPlayer(" << this->playerno() << ")"
1077                     << "::add_must_have(" << tcolor << ", " << no << "):\n"
1078                     "  no too great" << '\n');
1079     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1080       << ")::OfPlayer(" << this->playerno() << ")::"
1081       << "throw in add_must_have(" << tcolor << ", " << no << ")\n";
1082     DEBUG_THROW(InvalidGameException, InvalidGameException());
1083   } // if (tcolor_must_have - must_have(tcolor) + no > cards to play)
1084 
1085   if (this->tcolor_must_have_.min_set(tcolor, no)) {
1086     this->cards_information().queue_update(tcolor);
1087   }
1088 
1089   return ;
1090 } // void CardsInformation::OfPlayer::add_must_have(Card::TColor tcolor, unsigned no)
1091 
1092 /** adds the information that the player must have the tcolor exactly 'no' times
1093  **
1094  ** @param    tcolor   tcolor that the player must have
1095  ** @param    no       how many times exactly the player must have the tcolor
1096  **/
1097 void
add_must_exactly_have(Card::TColor const tcolor,unsigned const no)1098 CardsInformation::OfPlayer::add_must_exactly_have(Card::TColor const tcolor,
1099                                                   unsigned const no)
1100 {
1101 #ifdef CONDITION_INFORMATION_FLOW
1102   if (CONDITION_INFORMATION_FLOW)
1103     if (   (this->must_have(tcolor) < no)
1104         || (this->can_have(tcolor) > no) )
1105       cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1106         << "add_must_exactly_have(tcolor = " << tcolor << ", no = " << no << ")\n";
1107 #endif
1108 
1109   this->add_can_have(tcolor, no);
1110   this->add_must_have(tcolor, no);
1111 
1112   return ;
1113 } // void CardsInformation::OfPlayer::add_must_exactly_have(Card::TColor tcolor, unsigned no)
1114 
1115 /** adds the information that the player can have the card at max 'no' times
1116  **
1117  ** @param    card   card that the player can have
1118  ** @param    no   how many times the player can have the card at max
1119  **/
1120 void
add_can_have(Card const card,unsigned const no)1121 CardsInformation::OfPlayer::add_can_have(Card const card, unsigned const no)
1122 {
1123 #ifdef CONDITION_INFORMATION_FLOW
1124   if (CONDITION_INFORMATION_FLOW)
1125     if (this->can_have(card) > no)
1126       cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1127         << "add_can_have(card = " << card << ", no = " << no << ")\n";
1128 #endif
1129   if (no < this->must_have(card)) {
1130     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1131                     "CardsInformation"
1132                     << "(" << this->cards_information().player().no() << ")"
1133                     << "::OfPlayer(" << this->playerno() << ")"
1134                     << "::add_can_have(" << card << ", " << no << "):\n"
1135                     "  no < " << this->must_have(card) << " = must have\n"
1136                     "  player = " << this->playerno());
1137     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1138       << ")::OfPlayer(" << this->playerno() << ")::"
1139       << "throw in add_can_have(" << card << ", " << no << ")\n";
1140     DEBUG_THROW(InvalidGameException, InvalidGameException());
1141   } // if (no < this->must_have(card))
1142 
1143   if (this->can_have_.max_set(card, no))
1144     this->cards_information().queue_update(card);
1145 
1146   // now erase the 'can_have' for all cards of 'tcolor'
1147 
1148   return ;
1149 } // void CardsInformation::OfPlayer::add_can_have(Card card, unsigned no)
1150 
1151 /** adds the information that the player can have the cards at max 'no' times
1152  **
1153  ** @param    cards   cards that the player can have
1154  ** @param    no   how many times the player can have the card at max
1155  **/
1156 void
add_can_have(vector<Card> const & cards,unsigned const no)1157 CardsInformation::OfPlayer::add_can_have(vector<Card> const& cards,
1158                                          unsigned const no)
1159 {
1160   for (const auto & card : cards)
1161     this->add_can_have(card, no);
1162 
1163   return ;
1164 }  // void CardsInformation::OfPlayer::add_can_have(vector<Card> cards, unsigned no)
1165 
1166 /** adds the information that the player can only have the cards
1167  **
1168  ** @param    cards   cards the player can only have
1169  **/
1170 void
add_can_only_have(vector<Card> const & cards)1171 CardsInformation::OfPlayer::add_can_only_have(vector<Card> const& cards)
1172 {
1173 #ifdef CONDITION_INFORMATION_FLOW
1174   if (CONDITION_INFORMATION_FLOW) {
1175 #if 0
1176     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1177       << "add_can_only_have(cards)\n";
1178 #else
1179     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1180       << "add_can_only_have(cards = ";
1181     for (auto c = cards.begin(); c != cards.end(); ++c)
1182       cout << ((c == cards.begin()) ? "" : ", ") << *c;
1183     cout << ")" << endl;
1184 #endif
1185   }
1186 #endif
1187   map<Card, unsigned> number;
1188   for (const auto & card : cards) {
1189     number[card] += 1;
1190   }
1191 
1192   unsigned const unknown_no = std::count(cards.begin(), cards.end(), Card::unknown);
1193   if (unknown_no == 0) {
1194     // remove all entries in 'can_have' which have the value '0'
1195     // count the number of cards the player can have
1196     vector<Card> to_remove;
1197     for (auto x = this->can_have_.begin();
1198          x != this->can_have_.end();
1199          ++x) {
1200       map<Card, unsigned>::const_iterator n = number.find(x->first);
1201       if (n == number.end()) {
1202         if (this->must_have(x->first)) {
1203           DEBUG_ASSERTION(this->cards_information().is_virtual(),
1204                           "CardsInformation"
1205                           << "(" << this->cards_information().player().no() << ")"
1206                           << "::OfPlayer(" << this->playerno() << ")"
1207                           "::add_can_only_have():\n"
1208                           "  card '" << x->first << "':\n"
1209                           "    new number = 0 < "
1210                           << this->must_have(x->first) << " = must_have");
1211           if (::debug("throw")) {
1212             DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << x->first << ": " << this->must_have(x->first) << endl;
1213             DEBUG("throw") << *this << endl;
1214             DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1215               << ")::OfPlayer(" << this->playerno() << ")::"
1216               << "throw in add_can_only_have(cards): " << x->first << "\n";
1217           }
1218           DEBUG_THROW(InvalidGameException, InvalidGameException());
1219         } // if (this->must_have(x->first))
1220         to_remove.push_back(x->first);
1221         continue;
1222       }
1223 
1224       if (n->second < this->must_have(x->first)) {
1225         DEBUG_ASSERTION(this->cards_information().is_virtual(),
1226                         "CardsInformation"
1227                         << "(" << this->cards_information().player().no() << ")"
1228                         << "::OfPlayer(" << this->playerno() << ")"
1229                         "::add_can_only_have():\n"
1230                         "  card '" << x->first << "':\n"
1231                         "    new number = " << n->second << " < "
1232                         << this->must_have(x->first) << " = must_have");
1233         DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1234           << ")::OfPlayer(" << this->playerno() << ")::"
1235           << "throw in add_can_only_have(cards)\n";
1236         DEBUG_THROW(InvalidGameException, InvalidGameException());
1237       } // if (n->second < this->must_have(x->first))
1238     } // for (x \in can_have)
1239 
1240     // remove the cards with value '0' from the list
1241     if (!to_remove.empty()) {
1242       for (vector<Card>::const_iterator c = to_remove.begin();
1243            c != to_remove.end();
1244            ++c) {
1245         if (this->must_have(*c)) {
1246           DEBUG_ASSERTION(this->cards_information().is_virtual(),
1247                           "CardsInformation"
1248                           << "(" << this->cards_information().player().no() << ")"
1249                           << "::OfPlayer(" << this->playerno() << ")"
1250                           << "):\n"
1251                           "  card '" << *c << "':\n"
1252                           "    new number = 0 < "
1253                           << this->must_have(*c) << " = must_have");
1254           DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1255             << ")::OfPlayer(" << this->playerno() << ")::"
1256             << "throw in add_can_only_have(cards)\n";
1257           DEBUG_THROW(InvalidGameException, InvalidGameException());
1258         } // if (this->must_have(*c))
1259 
1260         this->add_cannot_have(*c);
1261       } // for (c \in to_remove)
1262     } // if (!to_remove.empty())
1263   } // if (no unknown card)
1264 
1265   // set the maximal number of the cards
1266   for (map<Card, unsigned>::const_iterator n = number.begin();
1267        n != number.end();
1268        ++n) {
1269     if (this->can_have_.max_set(n->first, n->second + unknown_no))
1270       this->cards_information().queue_update(n->first);
1271   } // for (n \in number)
1272 
1273   if (   (::game_status != GameStatus::game_redistribute)
1274       && (this->can_have_.cards_no() < this->player().cards_to_play())) {
1275     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1276                     "CardsInformation"
1277                     << "(" << this->cards_information().player().no() << ")"
1278                     << "::OfPlayer(" << this->playerno() << ")"
1279                     << "::add_can_only_have(cards)\n"
1280                     "  can_have.cards_no() = " << this->can_have_.cards_no()
1281                     << " < "
1282                     << this->player().cards_to_play() << " = cards to play");
1283     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1284       << ")::OfPlayer(" << this->playerno() << ")::"
1285       << "throw in add_can_only_have(cards)\n";
1286     DEBUG_THROW(InvalidGameException, InvalidGameException());
1287   }
1288 
1289   return ;
1290 } // void CardsInformation::OfPlayer::add_can_only_have(vector<Card> cards)
1291 
1292 /** adds the information that the player cannot have the card
1293  **
1294  ** @param    card   card the player cannot have
1295  **/
1296 void
add_cannot_have(Card const card)1297 CardsInformation::OfPlayer::add_cannot_have(Card const card)
1298 {
1299 #ifdef CONDITION_INFORMATION_FLOW
1300   if (CONDITION_INFORMATION_FLOW)
1301     if (this->can_have(card) > 0)
1302       cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1303         << "add_cannot_have(card = " << card << ")\n";
1304 #endif
1305   if (this->must_have(card)) {
1306     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1307                     "CardsInformation"
1308                     << "(" << this->cards_information().player().no() << ")"
1309                     << "::OfPlayer(" << this->playerno() << ")"
1310                     << "::add_cannot_have(" << card << ")\n"
1311                     "  player = " << this->playerno() << "\n"
1312                     "  must_have(card) = " << this->must_have(card) << " > 0");
1313     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1314       << ")::OfPlayer(" << this->playerno() << ")::"
1315       << "throw in add_cannot_have(" << card << ")\n";
1316     DEBUG_THROW(InvalidGameException, InvalidGameException());
1317   } // if (this->must_have(card))
1318 
1319   if (this->can_have_.erase(card)) {
1320     if (this->must_have(card) > 0) {
1321       DEBUG_ASSERTION(this->cards_information().is_virtual(),
1322                       "CardsInformation"
1323                       << "(" << this->cards_information().player().no() << ")"
1324                       << "::OfPlayer(" << this->playerno() << ")"
1325                       << "::add_cannot_have(" << card << "):\n"
1326                       << "  must_have = " << this->must_have(card) << '\n'
1327                       << "  player = " << this->playerno());
1328       DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1329         << ")::OfPlayer(" << this->playerno() << ")::"
1330         << "throw in add_cannot_have(" << card << ")\n";
1331       DEBUG_THROW(InvalidGameException, InvalidGameException());
1332     } // if (this->must_have(card))
1333     if (this->can_have_.cards_no() < this->player().cards_to_play()) {
1334       DEBUG_ASSERTION(this->cards_information().is_virtual(),
1335                       "CardsInformation"
1336                       << "(" << this->cards_information().player().no() << ")"
1337                       << "::OfPlayer(" << this->playerno() << ")"
1338                       << "::add_cannot_have(" << card << ")\n"
1339                       "  player = " << this->playerno() << "\n"
1340                       "  can_have.cards_no() = " << this->can_have_.cards_no()
1341                       << " < "
1342                       << this->player().cards_to_play() << " = cards to play");
1343       if (::debug("throw")) {
1344         DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1345           << ")::OfPlayer(" << this->playerno() << ")::"
1346           << "throw in add_cannot_have(" << card << ")\n"
1347           << "can have = " << this->can_have_.cards_no()
1348           << " < " << this->player().cards_to_play() << " = cards to play\n";
1349       }
1350       DEBUG_THROW(InvalidGameException, InvalidGameException());
1351     } // if (this->can_have_.cards_no() < this->player().cards_to_play())
1352 
1353 #ifdef WORKAROUND
1354     // if only one player can have the card, he must have it (see 'update_card')
1355     { // check whether all cards of 'card' are either played,
1356       // one player has it or it can be forgotten
1357       unsigned distributed = this->cards_information().played(card);
1358       for (unsigned p = 0; p < this->game().playerno(); ++p)
1359         distributed += this->cards_information().of_player(p).can_have(card);
1360       distributed += this->cards_information().forgotten_cards_no();
1361 
1362       if (distributed < this->game().rule()(Rule::Type::number_of_same_cards)) {
1363         DEBUG_ASSERTION(this->cards_information().is_virtual(),
1364                         "CardsInformation"
1365                         << "(" << this->cards_information().player().no() << ")"
1366                         << "::OfPlayer(" << this->playerno() << ")"
1367                         << "::add_cannot_have"
1368                         "(" << card << ")\n"
1369                         "  player = " << this->playerno() << "\n"
1370                         "  the card is not distributed");
1371         DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1372           << ")::OfPlayer(" << this->playerno() << ")::"
1373           << "throw in add_cannot_have(" << card << ")\n";
1374         DEBUG_THROW(InvalidGameException, InvalidGameException());
1375       } // if (distributed < this->game().rule()(Rule::Type::number_of_same_cards))
1376 
1377 
1378     } // check whether all cards of 'card' are somewhere
1379 #endif
1380     this->cards_information().queue_update(card);
1381   } // if (this->can_have_.erase(card))
1382 
1383   return ;
1384 } // void CardsInformation::OfPlayer::add_cannot_have(Card card)
1385 
1386 /** adds the information that the player can have the tcolor at max 'no' times
1387  **
1388  ** @param    tcolor   tcolor that the player can have
1389  ** @param    no       how many times the player can have the tcolor at max
1390  **/
1391 void
add_can_have(Card::TColor const tcolor,unsigned const no)1392 CardsInformation::OfPlayer::add_can_have(Card::TColor const tcolor,
1393                                          unsigned const no)
1394 {
1395 #ifdef CONDITION_INFORMATION_FLOW
1396   if (CONDITION_INFORMATION_FLOW)
1397     if (this->can_have(tcolor) > no)
1398       cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1399         << "add_can_have(tcolor = " << tcolor << ", no = " << no << ")\n";
1400 #endif
1401   DEBUG_ASSERTION(no <= this->game().cards().count(),
1402                   "CardsInformation"
1403                   << "(" << this->cards_information().player().no() << ")"
1404                   << "::OfPlayer(" << this->playerno() << ")"
1405                   << "::add_can_have(" << tcolor << ", " << no << "):\n"
1406                   "  no = " << no << " too great");
1407   if (no < this->must_have(tcolor)) {
1408     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1409                     "CardsInformation"
1410                     << "(" << this->cards_information().player().no() << ")"
1411                     << "::OfPlayer(" << this->playerno() << ")"
1412                     << "::add_can_have(" << tcolor << ", " << no << "):\n"
1413                     "  no = " << no << " < " << this->must_have(tcolor) << " = must have\n"
1414                     "  player = " << this->playerno() << '\n'
1415                     << *this
1416                    );
1417     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1418       << ")::OfPlayer(" << this->playerno() << ")::"
1419       << "throw in add_can_have(" << tcolor << ", " << no << ")\n";
1420     DEBUG_THROW(InvalidGameException, InvalidGameException());
1421   } // if (no < this->must_have(card))
1422 
1423   if (this->tcolor_can_have_.max_set(tcolor, no)) {
1424     this->cards_information().queue_update(tcolor);
1425   }
1426 
1427   return ;
1428 } // void CardsInformation::OfPlayer::add_can_have(Card::TColor tcolor, unsigned no)
1429 
1430 /** adds the information that the player cannot have the cards
1431  **
1432  ** @param    cards   cards the player cannot have
1433  **/
1434 void
add_cannot_have(vector<Card> const & cards)1435 CardsInformation::OfPlayer::add_cannot_have(vector<Card> const& cards)
1436 {
1437   for (const auto & card : cards)
1438     this->add_cannot_have(card);
1439 
1440   return ;
1441 } // void CardsInformation::OfPlayer::add_cannot_have(vector<Card> cards)
1442 
1443 /** adds the information that the player cannot have the tcolor
1444  **
1445  ** @param    tcolor   tcolor the player cannot have
1446  **/
1447 void
add_cannot_have(Card::TColor const tcolor)1448 CardsInformation::OfPlayer::add_cannot_have(Card::TColor const tcolor)
1449 {
1450 #ifdef CONDITION_INFORMATION_FLOW
1451   if (CONDITION_INFORMATION_FLOW) {
1452     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1453       << "add_does_not_have(tcolor = " << tcolor << ")\n";
1454     COUT << this->player().hand() << endl;
1455   }
1456 #endif
1457 
1458   this->add_must_exactly_have(tcolor, 0);
1459 
1460   return ;
1461 } // void CardsInformation::OfPlayer::add_cannot_have(Card::TColor tcolor)
1462 
1463 /** updates the information of the card
1464  ** throws InvalidGameException
1465  **
1466  ** @param    card   card to update the information of
1467  **/
1468 void
update_information(Card const card)1469 CardsInformation::OfPlayer::update_information(Card const card)
1470 {
1471   if (card.is_unknown())
1472     return;
1473 
1474 #ifdef CONDITION_INFORMATION_FLOW
1475   if (CONDITION_INFORMATION_FLOW) {
1476     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1477       << "update_information(card = " << card << ")\n";
1478   }
1479 #endif
1480   if (this->cards_information().in_recalcing)
1481     return ;
1482 
1483   // how many times this card was played
1484   unsigned const played = this->cards_information().played(card);
1485   // the number of forgotten cards
1486   unsigned const forgotten_cards
1487     = this->cards_information().forgotten_cards_no();
1488   // count how many of the card the other player must have
1489   unsigned must_have = 0;
1490   // count how many of the card the other player can have
1491   unsigned can_have = 0;
1492   for (unsigned p = 0; p < this->game().playerno(); ++p) {
1493     if (p != this->playerno()) {
1494       must_have += this->cards_information().of_player(p).must_have(card);
1495       can_have += this->cards_information().of_player(p).can_have(card);
1496     }
1497   } // for (p < this->game().playerno())
1498 
1499 #ifdef WORKAROUND
1500   // see bug report 232744
1501   // the cards distribution shall be sufficient
1502   // so that this case does not happen
1503   if (   (played + must_have > this->game().rule()(Rule::Type::number_of_same_cards))
1504       && !card.is_unknown()
1505       && this->cards_information().is_virtual()) {
1506     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1507       << ")::OfPlayer(" << this->playerno() << ")::"
1508       << "throw in update_information(" << card << ")\n";
1509     DEBUG_THROW(InvalidGameException, InvalidGameException());
1510   }
1511 #endif
1512 
1513   if (played + must_have
1514       > this->game().rule()(Rule::Type::number_of_same_cards)) {
1515     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1516                     "CardsInformation"
1517                     << "(" << this->cards_information().player().no() << ")"
1518                     << "::OfPlayer(" << this->playerno() << ")"
1519                     << "::update_information(" << card << ")\n"
1520                     "  played + must_have > max number:\n"
1521                     "  " << played
1522                     << " + " << must_have << " > "
1523                     << this->game().rule()(Rule::Type::number_of_same_cards)
1524                    );
1525     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1526       << ")::OfPlayer(" << this->playerno() << ")::"
1527       << "throw in update_information(" << card << ")\n";
1528     DEBUG_THROW(InvalidGameException, InvalidGameException());
1529   } // if (played + must_have > number_of_same_cards)
1530 
1531 
1532   // the number of cards this player can at most have
1533   unsigned const n = min(this->game().rule()(Rule::Type::number_of_same_cards)
1534                          - played
1535                          - must_have,
1536                          this->can_have(card.tcolor(this->game()))
1537                          - this->must_have_(card.tcolor(this->game()),
1538                                             this->game())
1539                          + this->must_have(card)
1540                         );
1541   if (n < this->must_have(card)) {
1542     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1543                     "CardsInformation"
1544                     << "(" << this->cards_information().player().no() << ")"
1545                     << "::OfPlayer(" << this->playerno() << ")"
1546                     << "::update_information(" << card << ")\n"
1547                     "  player = " << this->playerno() << "\n"
1548                     "  card = " << card << "\n"
1549                     "  number of same cards - played - must_have total"
1550                     " < must_have(card):\n"
1551                     << this->game().rule()(Rule::Type::number_of_same_cards)
1552                     << " - " << played
1553                     << " - " << must_have
1554                     << " < " << this->must_have(card));
1555     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1556       << ")::OfPlayer(" << this->playerno() << ")::"
1557       << "throw in update_information(" << card << ")\n";
1558     DEBUG_THROW(InvalidGameException, InvalidGameException());
1559   } // if (n < this->must_have(card))
1560 
1561   if (this->can_have_.max_set(card, n))
1562     this->cards_information().queue_update(card);
1563 
1564   // check whether a player must have the remaining cards of 'card'
1565   if (can_have + played + this->must_have(card) + forgotten_cards
1566       < this->game().rule()(Rule::Type::number_of_same_cards)) {
1567     this->add_must_have(card,
1568                         this->game().rule()(Rule::Type::number_of_same_cards)
1569                         - can_have - played - forgotten_cards);
1570   }
1571 
1572 
1573   if (this->cards_information().is_virtual()) {
1574     if (   (this->can_have_.cards_no() < this->player().cards_to_play())
1575         || (this->must_have_.cards_no() > this->player().cards_to_play()) ) {
1576       DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1577         << ")::OfPlayer(" << this->playerno() << ")::"
1578         << "throw in update_information(" << card << ")\n";
1579       DEBUG_THROW(InvalidGameException, InvalidGameException());
1580     }
1581   } // if (this->cards_information().is_virtual(),
1582 
1583   if (this->can_have_.cards_no() < this->player().cards_to_play()) {
1584     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1585                     "CardsInformation"
1586                     << "(" << this->cards_information().player().no() << ")"
1587                     << "::OfPlayer(" << this->playerno() << ")"
1588                     << "::update_information(" << card << ")\n"
1589                     << "  can_have.cards_no() = "
1590                     << this->can_have_.cards_no()
1591                     << " < "
1592                     << this->player().cards_to_play() << " = cards to play");
1593     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1594       << ")::OfPlayer(" << this->playerno() << ")::"
1595       << "throw in update_information(" << card << ")\n";
1596     DEBUG_THROW(InvalidGameException, InvalidGameException());
1597   } // if (this->can_have_.cards_no() < this->player().cards_to_play())
1598 
1599   if (this->must_have_.cards_no() > this->player().cards_to_play()) {
1600     DEBUG_ASSERTION(this->cards_information().is_virtual(),
1601                     "CardsInformation"
1602                     << "(" << this->cards_information().player().no() << ")"
1603                     << "::OfPlayer(" << this->playerno() << ")"
1604                     << "::update_information(" << card << ")\n"
1605                     << "  must_have.cards_no() = "
1606                     << this->must_have_.cards_no()
1607                     << " > "
1608                     << this->player().cards_to_play() << " = cards to play");
1609     DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1610       << ")::OfPlayer(" << this->playerno() << ")::"
1611       << "throw in update_information(" << card << ")\n";
1612     DEBUG_THROW(InvalidGameException, InvalidGameException());
1613   } // if ((this->must_have_.cards_no() > this->player().cards_to_play())
1614 
1615   return ;
1616 } // void CardsInformation::OfPlayer::update_information(Card card)
1617 
1618 /** updates the information of the tcolor
1619  **
1620  ** @param    tcolor   tcolor to update the information of
1621  **/
1622 void
update_information(Card::TColor const tcolor)1623 CardsInformation::OfPlayer::update_information(Card::TColor const tcolor)
1624 {
1625   if (tcolor == Card::unknowncardcolor)
1626     return ;
1627 
1628 #ifdef CONDITION_INFORMATION_FLOW
1629   if (CONDITION_INFORMATION_FLOW)
1630     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1631       << "update_information(" << tcolor << ")\n";
1632 #endif
1633 
1634   // the number of forgotten cards
1635   unsigned const forgotten_cards = this->cards_information().forgotten_cards_no();
1636 
1637   { // maximum can have
1638     // the number of cards still to be played minus must have of other colors
1639     if (this->player().cards_to_play()
1640         + this->must_have(tcolor)
1641         < this->tcolor_must_have_.cards_no()) {
1642       DEBUG_ASSERTION(this->game().isvirtual(),
1643                       "CardsInformation(" << this->cards_information().player().no()
1644                       << ")::OfPlayer(" << this->playerno() << ")::"
1645                       << "update_information(" << tcolor << ")\n"
1646                       << " cards to play + must have(" << tcolor << ") = "
1647                       << this->player().cards_to_play()
1648                       << " + " << this->must_have(tcolor)
1649                       << " < " << this->tcolor_must_have_.cards_no() << " = "
1650                       << tcolor_must_have_.cards_no());
1651 
1652       DEBUG("throw") << __FILE__ << '#' << __LINE__ << "  " << "\n  CardsInformation(" << this->cards_information().player().no()
1653         << ")::OfPlayer(" << this->playerno() << ")::"
1654         << "update_information(" << tcolor << ")\n";
1655       DEBUG_THROW(InvalidGameException, InvalidGameException());
1656     }
1657 
1658     this->add_can_have(tcolor,
1659                        this->player().cards_to_play()
1660                        - this->tcolor_must_have_.cards_no()
1661                        + this->must_have(tcolor));
1662   } // maximum can have
1663   { // minimum must have
1664     // the number of cards still to be played minus can have of other colors
1665     if (this->player().cards_to_play()
1666         > this->tcolor_can_have_.cards_no()
1667         - this->can_have(tcolor)) {
1668       this->add_must_have(tcolor,
1669                           this->player().cards_to_play()
1670                           - (this->tcolor_can_have_.cards_no()
1671                              - this->can_have(tcolor)));
1672     }
1673   } // minimum must have
1674   { // maximum can have
1675     // number of cards still in game but not must have of the other players
1676     unsigned sum_must_have = 0;
1677     for (unsigned p = 0; p < this->game().playerno(); ++p)
1678       if (p != this->playerno())
1679         sum_must_have += this->cards_information().of_player(p).must_have(tcolor);
1680     if (this->game().cards().count(tcolor)
1681         < this->cards_information().played(tcolor)
1682         + sum_must_have) {
1683       DEBUG_ASSERTION(this->game().isvirtual(),
1684                       "CardsInformation::OfPlayer::update_information(" << tcolor << ")\n"
1685                       << "  numberof = " << this->game().cards().count(tcolor)
1686                       << " > " << this->cards_information().played(tcolor)
1687                       << " + " << sum_must_have
1688                       << " = played + sum_must_have");
1689       DEBUG_THROW(InvalidGameException, InvalidGameException());
1690     }
1691     this->add_can_have(tcolor,
1692                        this->game().cards().count(tcolor)
1693                        - this->cards_information().played(tcolor)
1694                        - sum_must_have);
1695   } // maximum can have
1696   { // minimum must have
1697     // number of cards of the color - played - can have of others
1698     unsigned sum_can_have = 0;
1699     for (unsigned p = 0; p < this->game().playerno(); ++p)
1700       if (p != this->playerno())
1701         sum_can_have += this->cards_information().of_player(p).can_have(tcolor);
1702     if (this->game().cards().count(tcolor)
1703         > (forgotten_cards
1704            + this->cards_information().played(tcolor)
1705            + sum_can_have) ) {
1706 
1707       this->add_must_have(tcolor,
1708                           this->game().cards().count(tcolor)
1709                           - forgotten_cards
1710                           - this->cards_information().played(tcolor)
1711                           - sum_can_have);
1712     }
1713   } // minimum must have
1714   // set the can have and must have according to the information of the cards
1715   this->add_can_have(tcolor, this->can_have_(tcolor, this->game()));
1716   this->add_must_have(tcolor, this->must_have_(tcolor, this->game()));
1717   this->check_can_is_must(tcolor);
1718   return ;
1719 } // void CardsInformation::OfPlayer::update_information(Card::TColor tcolor)
1720 
1721 /** updates the information of the tcolors
1722  **/
1723 void
update_tcolor_information()1724 CardsInformation::OfPlayer::update_tcolor_information()
1725 {
1726 #ifdef CONDITION_INFORMATION_FLOW
1727   if (CONDITION_INFORMATION_FLOW)
1728     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1729       << "update_tcolor_information()\n";
1730 #endif
1731 
1732   for (unsigned c = 0; c < Card::number_of_tcolors; ++c)
1733     this->update_information(static_cast<Card::TColor>(c));
1734 
1735   if (!this->all_known()) {
1736     { // check can is must
1737       if (this->tcolor_can_have_.cards_no()
1738           == this->player().cards_to_play()) {
1739         for (unsigned c = 0; c < Card::number_of_tcolors; ++c)
1740           this->add_must_have(static_cast<Card::TColor>(c),
1741                               this->can_have(static_cast<Card::TColor>(c)));
1742       }
1743     } // check can is must
1744 
1745     { // check must is can
1746       if (this->tcolor_must_have_.cards_no()
1747           == this->player().cards_to_play()) {
1748         for (unsigned c = 0; c < Card::number_of_tcolors; ++c)
1749           this->add_can_have(static_cast<Card::TColor>(c),
1750                              this->must_have(static_cast<Card::TColor>(c)));
1751       }
1752     } // check must is can
1753   } // if (!this->all_known())
1754 
1755   // ToDo: if the player has only one free of a color, then he cannot have two of a card (p.e. three trumps, two swines so he cannot have two club kings)
1756 
1757   return ;
1758 } // void CardsInformation::OfPlayer::update_tcolor_information()
1759 
1760 /** updates 'can have' according to 'remaining cards'
1761  **/
1762 void
update_remaining_cards()1763 CardsInformation::OfPlayer::update_remaining_cards()
1764 {
1765 #ifdef CONDITION_INFORMATION_FLOW
1766   if (CONDITION_INFORMATION_FLOW)
1767     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1768       << "update_remaining_cards()\n";
1769 #endif
1770   unsigned const remaining_cards_no
1771     = (this->player().cards_to_play() - this->must_have_.cards_no());
1772 
1773   if ( !(remaining_cards_no
1774          < this->game().rule()(Rule::Type::number_of_same_cards)) )
1775     return ;
1776   if ( !(this->must_have_.cards_no() != this->can_have_.cards_no()) )
1777     return ;
1778 
1779   vector<Card> cards;
1780   for (const auto & c : this->can_have_) {
1781     if (this->can_have(c.first)
1782         > remaining_cards_no - this->must_have(c.first))
1783       cards.push_back(c.first);
1784   } // for (c \in this->can_have_)
1785   for (vector<Card>::const_iterator c = cards.begin();
1786        c != cards.end();
1787        ++c)
1788     this->add_can_have(*c, remaining_cards_no + this->must_have(*c));
1789 
1790   return ;
1791 } // void CardsInformation::OfPlayern::update_remaining_cards()
1792 
1793 /** checks whether the cards which the player can have are the ones
1794  ** he has to have
1795  **/
1796 void
check_can_is_must()1797 CardsInformation::OfPlayer::check_can_is_must()
1798 {
1799 #ifdef CONDITION_INFORMATION_FLOW
1800   if (CONDITION_INFORMATION_FLOW)
1801     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1802       << "check_can_is_must()\n";
1803 #endif
1804   if (this->can_have_.cards_no() == this->must_have_.cards_no())
1805     return ;
1806   if (this->must_have_.cards_no() == this->player().cards_to_play())
1807     return ;
1808 
1809   // update the tcolor information
1810   for (unsigned c = 0; c < Card::number_of_tcolors; ++c)
1811     this->check_can_is_must(static_cast<Card::TColor>(c));
1812 
1813   if (this->can_have_.cards_no() != this->player().cards_to_play()) {
1814     if (this->can_have_.cards_no() <
1815         (this->player().cards_to_play()
1816          + this->game().rule()(Rule::Type::number_of_same_cards)) ) {
1817       unsigned const cards_surplus
1818         = this->can_have_.cards_no() - this->player().cards_to_play();
1819       for (const auto & c : this->can_have_) {
1820         if (c.second > cards_surplus)
1821           if (this->must_have_.min_set(c.first, c.second - cards_surplus))
1822             this->cards_information().queue_update(c.first);
1823       } // for (c \in this->can_have)
1824     } // if (surplus less than number of cards)
1825     { // only one card unknown
1826 
1827       // Check whether there is only one card in 'can have' unknown.
1828       // Then the remaining number must be the difference between
1829       // 'cards to play' and 'must have'.
1830 
1831       if (this->can_have_.cards_no()
1832           >= (this->must_have_.cards_no()
1833               + this->game().rule()(Rule::Type::number_of_same_cards)))
1834         return ;
1835 
1836       Card unknown_card;
1837       for (const auto & c : this->can_have_) {
1838         if (this->must_have_[c.first] != c.second) {
1839           // found a second unknown card
1840           if (!unknown_card.is_empty())
1841             return ;
1842 
1843           unknown_card = c.first;
1844         } // if (must_have != can_have)
1845       } // for (c \in this->can_have_)
1846 
1847       this->can_have_.max_set(unknown_card,
1848                               this->player().cards_to_play()
1849                               - this->must_have_.cards_no()
1850                               + this->must_have_[unknown_card]);
1851     } // only one card unknown
1852   } // if (can_have != cards_to_play)
1853 
1854   // so all 'can_have' are 'must_have'
1855 
1856   for (const auto & c : this->can_have_) {
1857     if (this->must_have_[c.first] != c.second) {
1858       if (this->must_have_.min_set(c.first, c.second))
1859         this->cards_information().queue_update(c.first);
1860     }
1861   } // for (c \in this->can_have_)
1862 
1863   return ;
1864 } // void CardsInformation::OfPlayer::check_can_is_must()
1865 
1866 /** checks whether the cards which the player can have are the ones
1867  ** he has to have
1868  **
1869  ** @param    tcolor   tcolor to check
1870  **
1871  ** @todo       information of only one remaining unknown card (see below)
1872  **/
1873 void
check_can_is_must(Card::TColor const tcolor)1874 CardsInformation::OfPlayer::check_can_is_must(Card::TColor const tcolor)
1875 {
1876 #ifdef CONDITION_INFORMATION_FLOW
1877   if (CONDITION_INFORMATION_FLOW)
1878     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1879       << "check_can_is_must(" << tcolor << ")\n";
1880 #endif
1881   if (this->can_have(tcolor) > this->must_have(tcolor))
1882     return ;
1883   unsigned const can_have_tcolor = this->can_have_(tcolor, this->game());
1884   unsigned const must_have_tcolor = this->must_have_(tcolor, this->game());
1885   if (can_have_tcolor == must_have_tcolor)
1886     return ;
1887 #ifdef POSTPONED
1888   // ToDo: check, whether only one card is unknown:
1889   // either set 'can have' or 'must have' according to the free
1890   // can_have(tcolor) - must_have_(tcolor, game()) or
1891   // can_have_(tcolor, game()) - must_have(tcolor)
1892   if (can_have_tcolor > this->must_have(tcolor)) {
1893     if (can_have_tcolor - this->must_have(tcolor) <
1894         this->game().rule()(Rule::Type::number_of_same_cards)) {
1895       // check whether there is only one unknown card
1896       for (CardCounter::const_iterator c = this->can_have_.begin();
1897            c != this->can_have_.end();
1898            ++c) {
1899         if (c->first.tcolor(this->game()) == tcolor) {
1900           if (this->must_have_[c->first] != c->second) {
1901             this->must_have_[c->first].min_set(c->first,
1902                                                c->second
1903                                                - (can_have_tcolor
1904                                                   - this->must_have(tcolor)));
1905           } // if (must_have != can_have)
1906         }
1907       } // for (c \in this->can_have_)
1908 
1909     }
1910   } // if (can_have_tcolor > this->must_have(tcolor))
1911 #endif
1912 
1913   if (can_have_tcolor == this->must_have(tcolor)) {
1914     // all cards of tcolor are must have
1915     for (const auto & c : this->can_have_) {
1916       if (c.first.tcolor(this->game()) == tcolor) {
1917         if (this->must_have_.min_set(c.first, c.second))
1918           this->cards_information().queue_update(c.first);
1919       } // if (c->tcolor(this->game()) == tcolor)
1920     } // for (c \in this->can_have_)
1921   } // if (this->can_have_(tcolor, this->game()) == this->must_have(tcolor))
1922 
1923   if (must_have_tcolor == this->can_have(tcolor)) {
1924     // all cards of tcolor are must have
1925     // this->can_have_ is changed in the loop!
1926     CardCounter const can_have = this->can_have_;
1927     for (const auto & c : can_have) {
1928       if (c.first.tcolor(this->game()) == tcolor) {
1929         if (this->can_have_.max_set(c.first, this->must_have(c.first))) {
1930           this->cards_information().queue_update(c.first);
1931         }
1932       } // if (c->tcolor(this->game()) == tcolor)
1933     } // for (c \in this->can_have_)
1934   } // if (this->can_have_(tcolor, this->game()) == this->must_have(tcolor))
1935 
1936   return ;
1937 } // void CardsInformation::OfPlayer::check_can_is_must(Card::TColor tcolor)
1938 
1939 /** check whether the cards the player has to have are the only ones
1940  ** he can have
1941  **/
1942 void
check_must_is_can()1943 CardsInformation::OfPlayer::check_must_is_can()
1944 {
1945 #ifdef CONDITION_INFORMATION_FLOW
1946   if (CONDITION_INFORMATION_FLOW)
1947     cout << "CardsInformation(" << this->cards_information().player().no() << ")::OfPlayer(" << this->playerno() << ")::"
1948       << "check_must_is_can()\n";
1949 #endif
1950 
1951   // the number of unknown cards of the player
1952   unsigned const unknown_cards_no
1953     = (this->player().cards_to_play() - this->must_have_.cards_no());
1954 
1955   if (unknown_cards_no >= this->game().rule()(Rule::Type::number_of_same_cards))
1956     return ;
1957 
1958   // Example:
1959   // We know now that there is only one unknown card.
1960   // So the player can only have one 'can have' more than 'must have'.
1961 
1962   vector<Card> update_cards;
1963   for (const auto & c : this->can_have_) {
1964     unsigned const must_have = this->must_have(c.first);
1965     if (c.second > must_have + unknown_cards_no) {
1966       //if (this->can_have_.max_set(c->first, must_have))
1967       update_cards.push_back(c.first);
1968     }
1969   }
1970 
1971   // limit the can have
1972   for (vector<Card>::const_iterator c = update_cards.begin();
1973        c != update_cards.end();
1974        ++c) {
1975     if (this->can_have_.max_set(*c, this->must_have(*c) + unknown_cards_no))
1976       this->cards_information().queue_update(*c);
1977   } // for (c \in update_cards)
1978 
1979   // special case: poverty
1980   if (   (this->game().type() == GameType::poverty)
1981       && (this->playerno() == this->game().players().soloplayer().no()) ) {
1982     // check whether all trumps of the player are known
1983     if (   !this->does_not_have(Card::trump)
1984         && (this->can_have(Card::trump) > this->must_have(Card::trump))
1985         && (this->played(Card::trump) + this->must_have(Card::trump)
1986             == this->game().poverty().returned_trumpno())) {
1987       // search the trumps
1988       vector<Card> update_cards;
1989       for (const auto & c : this->can_have_) {
1990         if (   (c.first.istrump(this->game()))
1991             && (c.second > this->must_have(c.first)) )
1992           update_cards.push_back(c.first);
1993       } // for (c \in this->can_have_)
1994       // limit the can have
1995       for (vector<Card>::const_iterator c = update_cards.begin();
1996            c != update_cards.end();
1997            ++c) {
1998         if (this->can_have_.max_set(*c, this->must_have(*c)))
1999           this->cards_information().queue_update(*c);
2000       } // for (c \in update_cards)
2001     } // if (all trumps known)
2002 
2003   } // if (poverty player)
2004 } // void CardsInformation::OfPlayer::check_must_is_can()
2005 
2006 /** -> result
2007  **
2008  ** @param    lhs   first object
2009  ** @param    rhs   second object
2010  **
2011  ** @return   whether the two objects are equal
2012  **   (the correspondign cards information may differ)
2013  **/
2014 bool
operator ==(CardsInformation::OfPlayer const & lhs,CardsInformation::OfPlayer const & rhs)2015 operator==(CardsInformation::OfPlayer const& lhs,
2016            CardsInformation::OfPlayer const& rhs)
2017 {
2018   return ( (lhs.playerno_
2019             == rhs.playerno_)
2020           && (lhs.played_
2021               == rhs.played_)
2022           && (lhs.must_have_
2023               == rhs.must_have_)
2024           && (lhs.can_have_
2025               == rhs.can_have_)
2026           && (lhs.tcolor_played_
2027               == rhs.tcolor_played_)
2028           && (lhs.tcolor_must_have_
2029               == rhs.tcolor_must_have_)
2030           && (lhs.tcolor_can_have_
2031               == rhs.tcolor_can_have_)
2032          );
2033 }
2034 
2035 /** -> result
2036  **
2037  ** @param    lhs   first object
2038  ** @param    rhs   second object
2039  **
2040  ** @return   whether the two objects are different
2041  **/
2042 bool
operator !=(CardsInformation::OfPlayer const & lhs,CardsInformation::OfPlayer const & rhs)2043 operator!=(CardsInformation::OfPlayer const& lhs,
2044            CardsInformation::OfPlayer const& rhs)
2045 {
2046   return !(lhs == rhs);
2047 }
2048 
2049 /** self check
2050  ** when an error is found, an ASSERTION is created
2051  **
2052  ** @return   whether the self-check was successful (no error)
2053  **/
2054 bool
self_check() const2055 CardsInformation::OfPlayer::self_check() const
2056 {
2057   if (this->player().cards_to_play() == UINT_MAX)
2058     return true;
2059 
2060   { // cards
2061     // the player has to have at least as many cards as he has to play
2062     if ( !(this->can_have_.cards_no() >= this->player().cards_to_play())) {
2063       DEBUG_ASSERTION(false,
2064                       "CardsInformation"
2065                       << "(" << this->cards_information().player().no() << ")"
2066                       << "::OfPlayer(" << this->playerno() << ")"
2067                       << "::self_check()\n"
2068                       "  playerno = " << this->playerno() << "\n"
2069                       "  can_have < cards to play:\n"
2070                       << "  " << this->can_have_.cards_no()
2071                       << " < " << this->player().cards_to_play());
2072       return false;
2073     }
2074 
2075     if (   !this->cards_information().is_virtual()
2076         && !this->game().isvirtual()) {
2077       { // the player has all cards of his hand in 'can_have'
2078         if (!this->can_have_.contains(this->player().hand().counted_cards())) {
2079           DEBUG_ASSERTION(false,
2080                           "CardsInformation"
2081                           << "(" << this->cards_information().player().no() << ")"
2082                           << "::OfPlayer(" << this->playerno() << ")"
2083                           << "::self_check()\n"
2084                           "  the cards of the hand are not contained in the can have cards.\n");
2085           return false;
2086         }
2087       } // the player has all cards of his hand in 'can_have'
2088       { // the player has all 'must_have' cards in his hand
2089         if (!this->must_have_.is_contained(this->player().hand().counted_cards())) {
2090           DEBUG_ASSERTION(false,
2091                           "CardsInformation"
2092                           << "(" << this->cards_information().player().no() << ")"
2093                           << "::OfPlayer(" << this->playerno() << ")"
2094                           << "::self_check()\n"
2095                           "  the must have cards are not contained in the cards of the hand.\n");
2096           return false;
2097         }
2098       } // the player has all 'must_have' cards in his hand
2099     } // if (!this->cards_information().is_virtual() && !this->game().isvirtual())
2100 
2101 
2102     // the player has to be able to play all 'must' cards
2103     if ( !(this->must_have_.cards_no() <= this->player().cards_to_play())) {
2104       DEBUG_ASSERTION(false,
2105                       "CardsInformation"
2106                       << "(" << this->cards_information().player().no() << ")"
2107                       << "::OfPlayer(" << this->playerno() << ")"
2108                       << "::self_check()\n"
2109                       "  playerno = " << this->playerno() << "\n"
2110                       "  must_have > cards to play:\n"
2111                       << "  " << this->must_have_.cards_no()
2112                       << " > " << this->player().cards_to_play());
2113       return false;
2114     }
2115 
2116     // check 'can have == cards to play' ==> 'can have == must have'
2117     if ( !(   (this->can_have_.cards_no() != this->player().cards_to_play())
2118            || (this->can_have_.cards_no() == this->must_have_.cards_no()) ) ) {
2119       DEBUG_ASSERTION(false,
2120                       "CardsInformation"
2121                       << "(" << this->cards_information().player().no() << ")"
2122                       << "::OfPlayer(" << this->playerno() << ")"
2123                       << "::self_check()\n"
2124                       "  playerno = " << this->playerno() << "\n"
2125                       "  cards_to_play == can_have != must_have:\n"
2126                       << "  " << this->player().cards_to_play()
2127                       << " == " << this->can_have_.cards_no()
2128                       << " != " << this->must_have_.cards_no()
2129                      );
2130       return false;
2131     }
2132 
2133     // for each card check:
2134     for (auto
2135          c = this->game().rule().cards().begin();
2136          c != this->game().rule().cards().end();
2137          ++c) {
2138       unsigned played = this->cards_information().played(*c);
2139       { // played(player) <= played(all)
2140         if (played < this->played(*c)) {
2141           DEBUG_ASSERTION(false,
2142                           "CardsInformation"
2143                           << "(" << this->cards_information().player().no() << ")"
2144                           << "::OfPlayer(" << this->playerno() << ")"
2145                           << "::self_check()\n"
2146                           "  playerno = " << this->playerno() << "\n"
2147                           "  card '" << *c << "' has been played "
2148                           << played << " times, but by the player "
2149                           << this->playerno() << " '" << this->played(*c)
2150                           << "' times");
2151           return false;
2152         }
2153       } // played(player) <= played(all)
2154 
2155       unsigned const can_have = this->can_have(*c);
2156       { // check 'can have < must have'
2157         if ( !(can_have >= this->must_have(*c))) {
2158           DEBUG_ASSERTION(false,
2159                           "CardsInformation"
2160                           << "(" << this->cards_information().player().no() << ")"
2161                           << "::OfPlayer(" << this->playerno() << ")"
2162                           << "::self_check()\n"
2163                           "  playerno = " << this->playerno() << "\n"
2164                           "  card '" << *c << "': "
2165                           "can_have = " << can_have << " < "
2166                           "must_have = " << this->must_have_[*c]
2167                          );
2168           return false;
2169         }
2170       } // check 'can have < must have'
2171 
2172       { // check 'can have < cards to play'
2173         if ( !(can_have <= this->player().cards_to_play())) {
2174           DEBUG_ASSERTION(false,
2175                           "CardsInformation"
2176                           << "(" << this->cards_information().player().no() << ")"
2177                           << "::OfPlayer(" << this->playerno() << ")"
2178                           << "::self_check()\n"
2179                           "  playerno = " << this->playerno() << "\n"
2180                           "  card '" << *c << "': "
2181                           "can_have = " << can_have << " > "
2182                           "cards to play = " << this->player().cards_to_play()
2183                          );
2184           return false;
2185         }
2186       } // check 'can have < cards to play'
2187 
2188       { // check 'can have + played + sum must have <= #Cards'
2189         unsigned sum = 0;
2190         for (unsigned p = 0; p < this->game().playerno(); ++p)
2191           if (p != this->playerno())
2192             sum += this->cards_information().of_player(p).must_have(*c);
2193 
2194         if (can_have + played + sum
2195             > this->game().rule()(Rule::Type::number_of_same_cards) ) {
2196 #ifdef DEBUG_ASSERT
2197           for (unsigned p = 0; p < this->game().playerno(); ++p) {
2198             if (p != this->playerno())
2199               if (this->cards_information().of_player(p).must_have(*c) > 0)
2200                 cerr << p << ": must have = " << this->cards_information().of_player(p).must_have(*c) << endl;
2201           }
2202 #endif
2203           DEBUG_ASSERTION(false,
2204                           "CardsInformation"
2205                           << "(" << this->cards_information().player().no() << ")"
2206                           << "::OfPlayer(" << this->playerno() << ")"
2207                           << "::self_check()\n"
2208                           "  playerno = " << this->playerno() << "\n"
2209                           "  card '" << *c << "':\n"
2210                           "  can_have + played + Sum must_have > number_of_cards:\n"
2211                           "  "
2212                           << can_have
2213                           << " + " << played << " + " << sum << " > "
2214                           << this->game().rule()(Rule::Type::number_of_same_cards)
2215                           //<< "\ngame:\n{\n" << this->game() << "}\n"
2216                           //<< "\n" << this->cards_information()
2217                          );
2218 
2219           return false;
2220         }
2221       } // check 'can have + played + sum must have <= #Cards'
2222       { // check 'can have(tcolor) >= can have'
2223         if (can_have > this->can_have(c->tcolor(this->game()))) {
2224           DEBUG_ASSERTION(false,
2225                           "CardsInformation"
2226                           << "(" << this->cards_information().player().no() << ")"
2227                           << "::OfPlayer(" << this->playerno() << ")"
2228                           << "::self_check()\n"
2229                           "  playerno = " << this->playerno() << "\n"
2230                           "  card '" << *c << "':\n"
2231                           "  can_have > can_have(tcolor):\n"
2232                           "  "
2233                           << can_have << " > "
2234                           << this->can_have(c->tcolor(this->game()))
2235                           //<< "\ngame:\n{\n" << this->game() << "}\n"
2236                           //<< "\n" << this->cards_information()
2237                          );
2238 
2239           return false;
2240         } // if (can_have < this->can_have(c->tcolor(this->game())))
2241       } // check 'can have(tcolor) >= can have'
2242     } // for (c \in cards)
2243 
2244     { // checked '#played intern <= #played by player'
2245       unsigned played_cardno = 0;
2246       for (const auto & p : this->played_)
2247         played_cardno += p.second;
2248       unsigned const played_cardno_by_player
2249         = (this->game().tricks().max_size() - this->player().cards_to_play());
2250       if (played_cardno > played_cardno_by_player) {
2251         DEBUG_ASSERTION(false,
2252                         "CardsInformation"
2253                         << "(" << this->cards_information().player().no() << ")"
2254                         << "::OfPlayer(" << this->playerno() << ")"
2255                         << "::self_check()\n"
2256                         "  " << played_cardno << " cards are marked as played, "
2257                         "but the player has played "
2258                         << played_cardno_by_player
2259                         << "\n" << this->game());
2260         return false;
2261       }
2262     } // checked '#played intern <= #played by player'
2263 
2264     if (   !this->cards_information().is_virtual()
2265         && (&this->cards_information()
2266             == &this->cards_information().player().cards_information())
2267        ) {
2268       // check that all cards on the hand of the player are 'can_be'
2269       for (const auto & card : this->player().hand().cards()) {
2270         if (card != Card::unknown)
2271           DEBUG_ASSERTION((this->can_have(card)
2272                            >= this->player().hand().count(card)),
2273                           "CardsInformation"
2274                           << "(" << this->cards_information().player().no() << ")"
2275                           << "::OfPlayer(" << this->playerno() << ")"
2276                           << "::self_check()\n"
2277                           "  card '" << card << "' is "
2278                           << this->player().hand().count(card)
2279                           << " times on the hand, but 'can have' = "
2280                           << this->can_have(card));
2281       } // for (card \in this->player().hand().cards())
2282     } // if (!is_virtual_game)
2283 
2284   } // cards
2285 
2286   { // tcolor
2287 
2288     // played in tcolor is as in cards
2289     if (!(this->tcolor_played_.cards_no() == this->played_.cards_no())) {
2290       DEBUG_ASSERTION(false,
2291                       "CardsInformation"
2292                       << "(" << this->cards_information().player().no() << ")"
2293                       << "::OfPlayer(" << this->playerno() << ")"
2294                       << "::self_check()\n"
2295                       "  playerno = " << this->playerno() << "\n"
2296                       "  tcolor played != played (cards):\n"
2297                       << "  " << this->tcolor_played_.cards_no()
2298                       << " != " << this->played_.cards_no());
2299       return false;
2300     }
2301 
2302     // the player has to be able to play all 'must' cards
2303     if (!(this->tcolor_must_have_.cards_no()
2304           <= this->player().cards_to_play())) {
2305       DEBUG_ASSERTION(false,
2306                       "CardsInformation"
2307                       << "(" << this->cards_information().player().no() << ")"
2308                       << "::OfPlayer(" << this->playerno() << ")"
2309                       << "::self_check()\n"
2310                       "  playerno = " << this->playerno() << "\n"
2311                       "  tcolor must_have > cards to play:\n"
2312                       << "  " << this->tcolor_must_have_.cards_no()
2313                       << " > " << this->player().cards_to_play());
2314       return false;
2315     }
2316 
2317     // the player has to have at least as many cards as he has to play
2318     if (!(this->tcolor_can_have_.cards_no()
2319           >= this->player().cards_to_play())) {
2320       DEBUG_ASSERTION(false,
2321                       "CardsInformation"
2322                       << "(" << this->cards_information().player().no() << ")"
2323                       << "::OfPlayer(" << this->playerno() << ")"
2324                       << "::self_check()\n"
2325                       "  playerno = " << this->playerno() << "\n"
2326                       "  tcolor can_have < cards to play:\n"
2327                       << "  " << this->tcolor_can_have_.cards_no()
2328                       << " < " << this->player().cards_to_play());
2329       return false;
2330     }
2331     // the player has to be able to play all 'must' cards
2332     if (!(this->tcolor_must_have_.cards_no()
2333           <= this->player().cards_to_play())) {
2334       DEBUG_ASSERTION(false,
2335                       "CardsInformation"
2336                       << "(" << this->cards_information().player().no() << ")"
2337                       << "::OfPlayer(" << this->playerno() << ")"
2338                       << "::self_check()\n"
2339                       "  playerno = " << this->playerno() << "\n"
2340                       "  tcolor must_have > cards to play:\n"
2341                       << "  " << this->tcolor_must_have_.cards_no()
2342                       << " > " << this->player().cards_to_play());
2343       return false;
2344     }
2345 
2346     // check 'can have == cards to play' ==> 'can have == must have'
2347     if ( !(   (this->tcolor_can_have_.cards_no()
2348                != this->player().cards_to_play())
2349            || (this->tcolor_can_have_.cards_no()
2350                == this->tcolor_must_have_.cards_no()) ) ) {
2351       DEBUG_ASSERTION(false,
2352                       "CardsInformation"
2353                       << "(" << this->cards_information().player().no() << ")"
2354                       << "::OfPlayer(" << this->playerno() << ")"
2355                       << "::self_check()\n"
2356                       "  playerno = " << this->playerno() << "\n"
2357                       "  cards_to_play == tcolor can_have != tcolor must_have:\n"
2358                       << "  " << this->player().cards_to_play()
2359                       << " == " << this->tcolor_can_have_.cards_no()
2360                       << " != " << this->tcolor_must_have_.cards_no()
2361                      );
2362       return false;
2363     }
2364 
2365     // for each tcolor check:
2366     for (unsigned c = 0; c < Card::number_of_tcolors; ++c) {
2367       Card::TColor const tcolor = static_cast<Card::TColor>(c);
2368       unsigned const played = this->cards_information().played(tcolor);
2369       { // played(player) <= played(all)
2370         if (played < this->played(tcolor)) {
2371           DEBUG_ASSERTION(false,
2372                           "CardsInformation"
2373                           << "(" << this->cards_information().player().no() << ")"
2374                           << "::OfPlayer(" << this->playerno() << ")"
2375                           << "::self_check()\n"
2376                           "  playerno = " << this->playerno() << "\n"
2377                           "  tcolor '" << tcolor << "' has been played "
2378                           << played << " times, but by the player "
2379                           << this->playerno() << " '" << this->played(tcolor)
2380                           << "' times");
2381           return false;
2382         }
2383       } // played(player) <= played(all)
2384       unsigned const can_have = this->can_have(tcolor);
2385       { // check 'can have < must have'
2386         if ( !(can_have >= this->must_have(tcolor))) {
2387           DEBUG_ASSERTION(false,
2388                           "CardsInformation"
2389                           << "(" << this->cards_information().player().no() << ")"
2390                           << "::OfPlayer(" << this->playerno() << ")"
2391                           << "::self_check()\n"
2392                           "  playerno = " << this->playerno() << "\n"
2393                           "  tcolor '" << tcolor << "': "
2394                           "can_have = " << can_have << " < "
2395                           "must_have = " << this->must_have(tcolor)
2396                          );
2397           return false;
2398         }
2399       } // check 'can have < must have'
2400 
2401       { // check 'can have < cards to play'
2402         if ( !(can_have <= this->player().cards_to_play())) {
2403           DEBUG_ASSERTION(false,
2404                           "CardsInformation"
2405                           << "(" << this->cards_information().player().no() << ")"
2406                           << "::OfPlayer(" << this->playerno() << ")"
2407                           << "::self_check()\n"
2408                           "  playerno = " << this->playerno() << "\n"
2409                           "  tcolor '" << tcolor << "': "
2410                           "can_have = " << can_have << " > "
2411                           "cards to play = " << this->player().cards_to_play()
2412                          );
2413           return false;
2414         }
2415       } // check 'can have < cards to play'
2416 
2417       { // check 'can have + played + sum must have <= #Cards'
2418         unsigned sum = 0;
2419         for (unsigned p = 0; p < this->game().playerno(); ++p)
2420           if (p != this->playerno())
2421             sum += this->cards_information().of_player(p).must_have(tcolor);
2422 
2423         if (can_have + played + sum > this->game().cards().count(tcolor) ) {
2424 #ifdef DEBUG_ASSERT
2425           for (unsigned p = 0; p < this->game().playerno(); ++p) {
2426             if (p != this->playerno())
2427               if (this->cards_information().of_player(p).must_have(tcolor) > 0)
2428                 cerr << p << ": tcolor must have = " << this->cards_information().of_player(p).must_have(tcolor) << endl;
2429           }
2430 #endif
2431           DEBUG_ASSERTION(false,
2432                           "CardsInformation"
2433                           << "(" << this->cards_information().player().no() << ")"
2434                           << "::OfPlayer(" << this->playerno() << ")"
2435                           << "::self_check()\n"
2436                           "  playerno = " << this->playerno() << "\n"
2437                           "  tcolor '" << tcolor << "':\n"
2438                           "  can_have + played + sum must_have > possible number:\n"
2439                           "  "
2440                           << can_have
2441                           << " + " << played << " + " << sum << " > "
2442                           << this->game().cards().count(tcolor)
2443                           //<< "\ngame:\n{\n" << this->game() << "}\n"
2444                           << "\n" << *this
2445                           //<< "\n" << this->cards_information()
2446                          );
2447 
2448           return false;
2449         }
2450       } // check 'can have + played + sum must have <= #Cards'
2451     } // for (c \in tcolors)
2452 
2453   } // tcolor
2454 
2455   return true;
2456 } // bool CardsInformation::OfPlayer::self_check() const
2457