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 "ai.h"
31
32 #include "../../game/game.h"
33 #include "../../party/rule.h"
34 #include "../../card/trick.h"
35
36 /** constructor
37 **/
AiRandom()38 AiRandom::AiRandom() :
39 Player(Player::Type::ai_random)
40 { }
41
42 /** construktor
43 **
44 ** @param istr stream with the infos
45 **
46 ** @todo all
47 **/
AiRandom(istream & istr)48 AiRandom::AiRandom(istream& istr) :
49 Player(Player::Type::ai_random)
50 {
51 (void)istr;
52 DEBUG_ASSERTION(false,
53 "AiRandom::AiRandom(istr):\n"
54 " Contructor not implemented");
55 } // AiRandom::AiRandom(istream& istr)
56
57 /** copy constructor
58 **
59 ** @param player player to copy
60 **/
AiRandom(Player const & player)61 AiRandom::AiRandom(Player const& player) :
62 Player(player),
63 Aiconfig()
64 {
65 this->set_type(Player::Type::ai_random);
66 } // AiRandom::AiRandom(Player player)
67
68 /** copy constructor
69 **
70 ** @param player player to copy
71 ** @param aiconfig configuration to copy
72 **/
AiRandom(Player const & player,Aiconfig const & aiconfig)73 AiRandom::AiRandom(Player const& player, Aiconfig const& aiconfig) :
74 Player(player),
75 Aiconfig(aiconfig)
76 {
77 this->set_type(Player::Type::ai_random);
78 } // AiRandom::AiRandom(Player player, Aiconfig aiconfig)
79
80 /** clone the player
81 **
82 ** @return pointer of a clone
83 **/
84 unique_ptr<Player>
clone() const85 AiRandom::clone() const
86 {
87 return make_unique<AiRandom>(*this);
88 } // virtual unique_ptr<Player> AiRandom::clone() const
89
90 /** -> result
91 ** (test of poverty, marriage, swines, hyperswines)
92 **
93 ** @param duty_solo whether the player has to play a solo
94 ** (default: false)
95 **
96 ** @return simple Reservation
97 **/
98 Reservation const&
reservation_get(bool const duty_solo)99 AiRandom::reservation_get(bool const duty_solo)
100 {
101 this->reservation() = this->Player::reservation_get_default();
102
103 if ( duty_solo
104 || (::random_value(this->game().playerno() * this->game().playerno()) == 0) ) {
105 vector<GameType> soli;
106 for (auto t : game_type_list) {
107 if (is_real_solo(t)
108 && this->game().rule()(t) ) {
109 soli.push_back(t);
110 }
111 } // for (t)
112 if (!soli.empty()) {
113 this->reservation().game_type = soli[::random_value(soli.size())];
114 }
115 } // if (duty_solo)
116
117 return this->reservation();
118 } // Reservation const& AiRandom::reservation_get(bool duty_solo)
119
120 /** -> result:
121 ** take a random card of all valid ones
122 **
123 ** @return valid card
124 **/
125 HandCard
card_get()126 AiRandom::card_get()
127 {
128 HandCard card;
129 do {
130 card = this->hand().card(::random_value(this->hand().cardsnumber()));
131 } while (!this->game().tricks().current().isvalid(card));
132
133 return card;
134 } // HandCard AiRandom::card_get()
135
136 /** @return announcement of the player
137 **/
138 Announcement
announcement_request() const139 AiRandom::announcement_request() const
140 {
141 // points of the own team
142 unsigned points = 0;
143
144 // count the points, the own team has made
145 for(auto const& player : this->game().players()) {
146 if (this->game().teaminfo().get(player) == this->team())
147 points += this->game().points_of_player(player);
148 }
149
150 if (points == 240)
151 return Announcement::no0;
152 if (points > 240 - 30)
153 return Announcement::no30;
154 if (points > 240 - 60)
155 return Announcement::no60;
156 if (points > 240 - 90)
157 return Announcement::no90;
158 if (points > 240 - 120)
159 return Announcement::no120;
160
161 return Announcement::noannouncement;
162 } // Announcement AiRandom::announcement_request() const
163
164 /** @return NULL (no new partner)
165 **/
166 Player const*
genscher_partner()167 AiRandom::genscher_partner()
168 {
169 return {};
170 } // Player const* AiRandom::genscher_partner()
171
172 /** @return shifted cards
173 **/
174 HandCards
poverty_shift()175 AiRandom::poverty_shift()
176 {
177 HandCards hand_cards = this->hand().cards();
178 HandCards cards_to_shift;
179
180 // first add all trump
181 for (auto c = hand_cards.begin(); c != hand_cards.end(); ) {
182 if (c->istrump()) {
183 cards_to_shift.push_back(*c);
184 c = hand_cards.erase(c);
185 } else {
186 ++c;
187 }
188 } // for (c : hand_cards)
189
190 // then fill up with cards randomly chosen
191 while (cards_to_shift.size() < this->hand().count_poverty_cards()) {
192 auto const i = ::random_value(hand_cards.size());
193 cards_to_shift.push_back(hand_cards[i]);
194 hand_cards.erase(hand_cards.begin() + i);
195 }
196
197 this->hand().remove(cards_to_shift);
198
199 return cards_to_shift;
200 } // HandCards AiRandom::poverty_shift()
201
202 /** -> result
203 **
204 ** @param cardno number of shifted cards (ignored)
205 **
206 ** @return false (do not accept the poverty)
207 **/
208 bool
poverty_take_accept(unsigned const cardno)209 AiRandom::poverty_take_accept(unsigned const cardno)
210 {
211 return false;
212 } // bool AiRandom::poverty_take_accept(unsigned cardno)
213
214
215 // the player changes the cards of the poverty
216 /** should not be called
217 **
218 ** @param cards the cards the player takes
219 **
220 ** @return empty cards
221 **/
222 HandCards
poverty_cards_change(HandCards const & cards)223 AiRandom::poverty_cards_change(HandCards const& cards)
224 {
225 DEBUG_ASSERTION(false,
226 "AiRandom::poverty_cards_change(cards)\n"
227 " function should not be called!");
228 return HandCards();
229 } // HandCards AiRandom::poverty_cards_change(HandCards cards)
230
231 /** the poverty player gets 'cards'
232 **
233 ** @param cards cards the player gets back
234 **/
235 void
poverty_cards_get_back(HandCards const & cards)236 AiRandom::poverty_cards_get_back(HandCards const& cards)
237 {
238 this->hand().add(cards);
239 } // void AiRandom::poverty_cards_get_back(HandCards cards)
240