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 "game.h"
31 
32 #include "gameplay.h"
33 #include "gameplay_actions/marriage.h"
34 #include "gameplay_actions/genscher.h"
35 
36 #include "../party/rule.h"
37 #include "../player/player.h"
38 #include "../card/trick.h"
39 #include "../ui/ui.h"
40 
41 /** constructor
42  **
43  ** @param    game   corresponding game
44  **/
GameMarriage(Game & game)45 GameMarriage::GameMarriage(Game& game) noexcept :
46   game_(&game)
47 { }
48 
49 /** constructor
50  **
51  ** @param    marriage   marriage to copy
52  ** @param    game   corresponding game
53  **/
GameMarriage(GameMarriage const & marriage,Game & game)54 GameMarriage::GameMarriage(GameMarriage const& marriage, Game& game) noexcept :
55   game_(&game),
56   selector_(marriage.selector_),
57   determination_trickno_(marriage.determination_trickno_)
58 { }
59 
60 /** @return   the marriage selector
61  **/
62 MarriageSelector
selector() const63 GameMarriage::selector() const noexcept
64 { return this->selector_; }
65 
66 /** @return   the tricknumber, the marriage was determined
67  **/
68 unsigned
determination_trickno() const69 GameMarriage::determination_trickno() const noexcept
70 { return this->determination_trickno_; }
71 
72 /** test, whether a genscher is played
73  **
74  ** @param    played_card   the played card
75  **/
76 void
check_for_genscher(HandCard const & played_card)77 GameMarriage::check_for_genscher(HandCard const& played_card)
78 {
79   auto& game = *this->game_;
80   auto const& rule = game.rule();
81 
82   if (!rule(Rule::Type::genscher))
83     return ;
84 
85   if (   ::is_solo(game.type())
86       || (game.type() == GameType::poverty))
87     return ;
88 
89   if (!played_card.istrumpking())
90     return ;
91 
92   if (game.players().current_player().hand().count_trump_kings()
93       != rule(Rule::Type::number_of_same_cards))
94     return ;
95 
96   Player const* const genscher_partner
97     = game.players().current_player().genscher_partner();
98 
99   if (!genscher_partner)
100     return ;
101 
102   game.players().set_soloplayer(game.players().current_player());
103   auto const& soloplayer = game.players().soloplayer();
104   // set the teams: 're' for the genscher players, 'contra' for the others
105   for (auto& p : game.players()) {
106     auto const team = ( (   (p == game.players().current_player())
107                          || (p == *genscher_partner))
108                        ? Team::re
109                        : Team::contra);
110     game.teaminfo_.set(p, team);
111     p.set_team(team);
112   } // for (p : this->player)
113   game.set_type(GameType::genscher);
114 
115   game.announcements().remove_all_but_re_contra();
116 
117   // tell all players about the genscher
118   for (auto& p : game.players())
119     p.genscher(game.players().current_player(), *genscher_partner);
120 
121   game.gameplay_->gameplay_action(GameplayActions::Genscher(soloplayer.no(),
122                                                             genscher_partner->no()));
123   if (!game.isvirtual()) {
124     ::ui->genscher(soloplayer, *genscher_partner);
125     this->signal_genscher_(soloplayer, *genscher_partner);
126     ::ui->gameplay_action(GameplayActions::Genscher(soloplayer.no(),
127                                                     genscher_partner->no()));
128     game.signal_gameplay_action_(GameplayActions::Genscher(soloplayer.no(),
129                                                            genscher_partner->no()));
130   }
131 } // void GameMarriage::check_for_genscher(HandCard played_card)
132 
133 
134 /** test, whether a silent marriage is played
135  **
136  ** @return
137  **/
138 void
check_for_silent_marriage()139 GameMarriage::check_for_silent_marriage()
140 {
141   if (::game_status == GameStatus::game_redistribute)
142     return ;
143 
144   DEBUG_ASSERTION((::game_status == GameStatus::game_reservation),
145                   "GameMarriage::check_for_silent_marriage()\n"
146                   "  game status is not 'reservation' "
147                   "but '" << ::game_status << "'");
148 
149   auto& game = *this->game_;
150   auto const& rule = game.rule();
151 
152   if (game.type() != GameType::normal)
153     return ;
154 
155   for (auto& p : game.players()) {
156     if (p.hand().count_club_queens()
157         == rule(Rule::Type::number_of_same_cards)) {
158       game.players().set_soloplayer(p);
159       game.set_type(GameType::marriage_silent);
160       this->selector_ = MarriageSelector::silent;
161       this->determination_trickno_ = UINT_MAX;
162       break;
163     } // if (silent marriage)
164   } // for (p : game.players())
165 } // void GameMarriage::check_for_silent_marriage()
166 
167 /** test, if the silent marriage is solved
168  **/
169 void
determine_silent_marriage()170 GameMarriage::determine_silent_marriage()
171 {
172   auto& game = *this->game_;
173   auto const& rule = game.rule();
174 
175   if (   (game.type_ != GameType::marriage_silent)
176       || (this->selector() != MarriageSelector::silent))
177     return ;
178 
179   // whether the silent marriage is known to all
180   bool solved = false;
181 
182   { // check whether both club queens have been played
183     if (game.cards().count_played(Card::club_queen)
184         == rule(Rule::Type::number_of_same_cards) )
185       solved = true;
186   } // check whether both club queens have been played
187 
188   { // check whether all other players are known to be contra
189     unsigned contra_no = 0;
190     for (auto& p : game.players())
191       if (game.teaminfo().get(p) == Team::contra)
192         contra_no += 1;
193 
194     if (contra_no == game.playerno() - 1)
195       solved = true;
196   } // check whether all other players are known to be contra
197 
198   if (solved) {
199     this->selector_ = MarriageSelector::team_set;
200     this->determination_trickno_ = game.tricks().current_no();
201   } // if (solved)
202 } // void GameMarriage::determine_silent_marriage()
203 
204 /** test, if the marriage is solved
205  **
206  ** @return
207  **/
208 void
determine_marriage()209 GameMarriage::determine_marriage()
210 {
211   if (!this->is_undetermined())
212     return ;
213 
214   auto& game = *this->game_;
215   auto const& rule = game.rule();
216   auto const& tricks = game.tricks();
217   auto const& current_trick = tricks.current();
218   auto const& soloplayer = game.players().soloplayer();
219 
220   // whether the player has to play alone
221   // note that 'tricks().current_no()' begins at '0'
222   // but 'determination' at '1'
223   bool alone = (tricks.current_no() >= rule(Rule::Type::marriage_determination));
224   auto const& winnerplayer = current_trick.winnerplayer();
225 
226   if (   rule(Rule::Type::marriage_first_one_decides)
227       && is_selector(current_trick.startcard().tcolor(),
228                      this->selector())
229       && (winnerplayer == soloplayer) )
230     alone = true;
231 
232 
233   if (   is_selector(current_trick.startcard().tcolor(),
234                      this->selector())
235       && (winnerplayer != soloplayer) ) {
236     // set the teams
237     for (auto& p : game.players()) {
238       auto const team = ((   (p == soloplayer)
239                           || (p == winnerplayer))
240                          ? Team::re
241                          : Team::contra);
242       game.teaminfo_.set(p, team);
243       p.set_team(team);
244     }
245     this->selector_ = MarriageSelector::team_set;
246     this->determination_trickno_ = tricks.current_no();
247     // update the teaminfo of the players
248     for (auto& p : game.players()) {
249       p.marriage(soloplayer, winnerplayer);
250     }
251 
252     game.gameplay_->gameplay_action(GameplayActions::Marriage(soloplayer.no(),
253                                                               winnerplayer.no()));
254     if (!game.isvirtual()) {
255       ::ui->marriage(soloplayer, winnerplayer);
256       this->signal_marriage_(soloplayer, winnerplayer);
257       ::ui->gameplay_action(GameplayActions::Marriage(soloplayer.no(),
258                                                       winnerplayer.no()));
259       game.signal_gameplay_action_(GameplayActions::Marriage(soloplayer.no(),
260                                                              winnerplayer.no()));
261     }
262 
263     alone = false;
264   } // if selected trick is caught
265 
266 
267   if (   (this->selector() != MarriageSelector::team_set)
268       && !alone) {
269     // test, whether there is a remaining card of the color
270     bool has_card = false; // whether a player has a card of the color
271     for (auto& p : game.players()) {
272       switch(this->selector()) {
273       case MarriageSelector::silent:
274       case MarriageSelector::team_set:
275       case MarriageSelector::first_foreign:
276         has_card = true;
277         break;
278       case MarriageSelector::first_trump:
279         if (p.hand().contains(Card::trump))
280           has_card = true;
281         break;
282       case MarriageSelector::first_color:
283         if (   p.hand().contains(Card::club)
284             || p.hand().contains(Card::spade)
285             || p.hand().contains(Card::heart))
286           has_card = true;
287         break;
288       case MarriageSelector::first_club:
289         if (p.hand().contains(Card::club))
290           has_card = true;
291         break;
292       case MarriageSelector::first_spade:
293         if (p.hand().contains(Card::spade))
294           has_card = true;
295         break;
296       case MarriageSelector::first_heart:
297         if (p.hand().contains(Card::heart))
298           has_card = true;
299         break;
300       } // switch (this->selector())
301     } // for (p : this->players())
302 
303     if (!has_card)
304       alone = true;
305   } // if (!alone)
306 
307   if (alone) {
308     this->determination_trickno_ = tricks.current_no();
309     game.set_type(GameType::marriage_solo);
310     for (auto& p : game.players()) {
311       auto const team = (  (p == soloplayer)
312                          ? Team::re
313                          : Team::contra);
314       game.teaminfo_.set(p, team);
315       p.set_team(team);
316     } // for (p : this->players())
317     this->selector_ = MarriageSelector::team_set;
318 
319     for (auto& p : game.players())
320       p.marriage(soloplayer, soloplayer);
321 
322     game.gameplay_->gameplay_action(GameplayActions::Marriage(soloplayer.no(),
323                                                               soloplayer.no())
324                                    );
325     if (!game.isvirtual()) {
326       ::ui->marriage(soloplayer, soloplayer);
327       this->signal_marriage_(soloplayer, soloplayer);
328       ::ui->gameplay_action(GameplayActions::Marriage(soloplayer.no(),
329                                                       soloplayer.no())
330                            );
331       game.signal_gameplay_action_(GameplayActions::Marriage(soloplayer.no(),
332                                                              soloplayer.no())
333                                   );
334     }
335   } // if (this->acttrick() >= rule(Rule::Type::determination))
336 
337   // it can be, that the team of the swines owner or the first fox catcher
338   // has changed
339   if (rule(Rule::Type::swine_only_second)
340       && game.swines().swines_announced()
341       && game.swines().first_fox_caught()
342       && (this->selector() == MarriageSelector::team_set)){
343     if (!game.isvirtual())
344       ::ui->redraw_all();
345   } // if (first fox of swines in trick)
346 } // void GameMarriage::determine_marriage()
347 
348 /** reset the values
349  **/
350 void
reset()351 GameMarriage::reset() noexcept
352 {
353   this->selector_ = MarriageSelector::team_set;
354   this->determination_trickno_ = 0;
355 }
356 
357 /** @return   whether the game is a marriage and undetermined
358  **/
359 bool
is_undetermined() const360 GameMarriage::is_undetermined() const noexcept
361 {
362   return (   (this->game_->type() == GameType::marriage)
363           && (this->selector() != MarriageSelector::team_set));
364 } // bool GameMarriage::marriage().is_undetermined() const
365 
366 /** @return   signal for a marriage
367  **/
368 Signal<void(Player const&, Player const&)>&
signal_marriage()369 GameMarriage::signal_marriage() noexcept
370 { return this->signal_marriage_; }
371 
372 /** @return   signal, when the partner for a genscher shall be selected
373  **/
374 Signal<void()>&
signal_get_genscher_partner()375 GameMarriage::signal_get_genscher_partner() noexcept
376 { return this->signal_get_genscher_partner_; }
377 
378 /** @return   signal, when a genscher is made
379  **/
380 Signal<void(Player const&, Player const&)>&
signal_genscher()381 GameMarriage::signal_genscher() noexcept
382 { return this->signal_genscher_; }
383 
384