/********************************************************************** * * FreeDoko a Doppelkopf-Game * * Copyright (C) 2001-2007 by Diether Knof and Borg Enders * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You can find this license in the file 'gpl.txt'. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Contact: * Diether Knof dknof@gmx.de * Borg Enders borg@borgsoft.de * **********************************************************************/ #ifndef CLASS_AICONFIG_HEADER #define CLASS_AICONFIG_HEADER #include "../card/card.h" #include "heuristicsmap.h" #include "rating/rating.h" #include "../misc/translation.h" #include namespace AITYPE { enum AiType { AITYPE_FIRST = 0, NO_CHOOSEBESTCARD = AITYPE_FIRST, RANDOM, VIRTUAL_GAMES, GAMETREE, GAMETREE_WITH_HEURISTICS, GAMETREE_FOR_TEAM, MONTE_CARLO, AITYPE_LAST = MONTE_CARLO }; // enum AiType extern unsigned const NUMBER; } // namespace AITYPE using AITYPE::AiType; extern AiType aitype; string name(const AiType& aitype); WRITE_NAME2(AITYPE, AiType) class Aiconfig { public: // whether to write the standard type (all the whole configuration) static bool write_standard_type; public: enum Difficulty { DIFFICULTY_FIRST = 0, NOVICE = DIFFICULTY_FIRST, STANDARD_DEFENSIVE, STANDARD_OFFENSIVE, PROFI, PROFI_UNFAIR, CUSTOM, DIFFICULTY_LAST = CUSTOM }; // enum Difficulty enum Heuristic { HEURISTIC_FIRST, NO_HEURISTIC = HEURISTIC_FIRST, MANUAL, BUG_REPORT, NETWORK, ONLY_VALID_CARD, PLAY_TO_MARRY, // Heuristics::play_to_marry CHOOSE_ACE, // Heuristics::choose_ace CHOOSE_FOR_COLOR_TRICK, // Heuristics::choose_for_color_trick RETRY_COLOR, PLAY_COLOR_FOR_PARTNER, // Heuristics::play_color_for_partner TRY_COLOR_FOR_PARTNER, // Heuristics::try_color_for_partner PLAY_COLOR_FOR_PARTNER_ACE, // Heuristics::play_color_for_partner_ace SERVE_COLOR_TRICK, SERVE_TRUMP_TRICK, CHOOSE_PFUND, // Heuristics::choose_pfund CHOOSE_PFUND_POVERTY, // Heuristics::choose_pfund_poverty CHOOSE_PFUND_BEFORE_PARTNER, // Heuristics::choose_pfund_before_partner JAB_FOR_ACE, // Heuristics::jab_for-ace CREATE_FEHL, // Heuristics::create_fehl BEST_WINNING, // Heuristics::best_winning_card LOW_HIGH, // Heuristics::play_low_high PLAY_FOR_TEAM, // Heuristics::play_for_team JAB_FOX, // Heuristics::jab_fox TRY_FOR_DOPPELKOPF, // Heuristics::try_for_doppelkopf PARTNER_BACKHAND_DRAW_TRUMP, // Heuristics::partner_backhand_draw_trump DRAW_TRUMP, GET_TRICK_FOR_ANNOUNCEMENT, GRAB_TRICK, HEURISTIC_POVERTY_FIRST, POVERTY_SPECIAL_PLAY_PFUND = HEURISTIC_POVERTY_FIRST, POVERTY_SPECIAL_GIVE_NO_POINTS, POVERTY_RE_TRUMP_COLOR_TRICK_HIGH, POVERTY_RE_PLAY_TRUMP, POVERTY_CONTRA_PLAY_COLOR, POVERTY_CONTRA_TRUMP_COLOR_TRICK_HIGH, POVERTY_LEAVE_TO_PARTNER, POVERTY_OVERJAB_RE, POVERTY_BEST_WINNING_CARD, HEURISTIC_POVERTY_LAST = POVERTY_BEST_WINNING_CARD, MEATLESS_PLAYHIGHESTCOLOR, // Meatless: Heuristics::play_highest_color PICTURE_SECONDBESTTRUMP, COLOR_CHOOSE_ACE, COLOR_BEST_WINNING, COLOR_JAB_FOR_ACE, COLOR_LOW_HIGH, CHOOSE_BEST_CARD, // for the database HEURISTIC_LAST = CHOOSE_BEST_CARD }; // enum Heuristic static unsigned const HEURISTIC_NUMBER; static Heuristic Heuristic_from_name(string const& name); static bool is_real(Heuristic const h); static bool is_general(Heuristic const h); static bool is_poverty(Heuristic const h); static bool is_solo(Heuristic const h); static bool is_solo_color(Heuristic const h); static bool is_solo_picture(Heuristic const h); static bool is_solo_meatless(Heuristic const h); struct HeuristicState { HeuristicState(Heuristic const heuristic, bool const active) : heuristic(heuristic), active(active) { } Heuristic heuristic; bool active; }; // struct HeuristicState enum TypeBool { BOOL_FIRST, TRUSTING = BOOL_FIRST, // whether the ai is trusting FAIRPLAYHANDS, // whether the ai takes the current hands of the players FAIRPLAYTEAMS, // whether the ai knows the team of the other players FEHLCREATIONONFIRSTCARD, BOOL_LAST = FEHLCREATIONONFIRSTCARD }; // enum TypeBool static unsigned const BOOL_NUMBER; enum TypeUnsigned { UNSIGNED_FIRST = BOOL_LAST + 1, REMEMBERTRICKS = UNSIGNED_FIRST, // how many tricks are remembered LIMIT_THROW_FEHL, // maximum points for playing a fehl LIMITQUEEN, // mininum points per trick for jabbing with a queen LIMITDOLLE, // minimum points per trick for jabbing with dollen or higher LASTFEHLCREATION, // last trick to create a fehl color LAST_TRICKS_WITHOUT_HEURISTICS, // how many tricks at the end of the game no heuristics are used FIRST_TRICK_FOR_TRUMP_POINTS_OPTIMIZATION, ANNOUNCELIMIT, // points of hand for first announcement ANNOUNCELIMITDEC, // points of hand you can lose between two announcements ANNOUNCECONFIG, // Parameter for Playerconfiguration of announcements ANNOUNCELIMITREPLY, // points of hand for first Reply ANNOUNCECONFIGREPLY, // Decrement for each announcment made, when replying TAKEPOVERTY, SINGLESOLO, // minimum cardvalue for a solo with only one picture trump DOUBLESOLO, // minimum cardvalue for a solo with two pictures trump TRIPLESOLO, // minimum cardvalue for a solo with three pictures trump COLORSOLO, // minimun cardvalue for playing a colorsolo MEATLESS, // minimun cardvalue for playing a fleischlosen UNSIGNED_LAST = MEATLESS }; // enum TypeUnsigned static unsigned const UNSIGNED_NUMBER; enum TypeCard { CARD_FIRST = UNSIGNED_LAST + 1, LIMITTHROWING = CARD_FIRST, // minimum team mate card for not over jabbing TRUMPLIMIT_SOLOCOLOR, TRUMPLIMIT_SOLOJACK, TRUMPLIMIT_SOLOQUEEN, TRUMPLIMIT_SOLOKING, TRUMPLIMIT_SOLOJACKKING, TRUMPLIMIT_SOLOJACKQUEEN, TRUMPLIMIT_SOLOQUEENKING, TRUMPLIMIT_SOLOKOEHLER, TRUMPLIMIT_MEATLESS, TRUMPLIMIT_NORMAL, LOWEST_TRUMPLIMIT_SOLOCOLOR, LOWEST_TRUMPLIMIT_SOLOJACK, LOWEST_TRUMPLIMIT_SOLOQUEEN, LOWEST_TRUMPLIMIT_SOLOKING, LOWEST_TRUMPLIMIT_SOLOJACKKING, LOWEST_TRUMPLIMIT_SOLOJACKQUEEN, LOWEST_TRUMPLIMIT_SOLOQUEENKING, LOWEST_TRUMPLIMIT_SOLOKOEHLER, LOWEST_TRUMPLIMIT_MEATLESS, LOWEST_TRUMPLIMIT_NORMAL, LIMITHIGH, // minimum team mate card for throwing a ten or ace into this trick CARD_LAST = LIMITHIGH }; // enum TypeCard static unsigned const CARD_NUMBER; public: // returns a preset ai static Aiconfig const& preset(Difficulty const difficulty); // returns all (interesting) keys for the heuristic configuration static list const& keys(); public: friend class Ai; public: Aiconfig(unsigned const no); Aiconfig(istream& istr); Aiconfig(Aiconfig const& aiconfig); Aiconfig& operator=(Aiconfig const& aiconfig); ~Aiconfig(); // set the aiconfig to the default values void reset_to_hardcoded(unsigned const no = UINT_MAX); // (re)sets the aiconfig to the given difficulty void set_to_difficulty(Difficulty const difficulty); // whether the aiconfig is equal bool equal(Aiconfig const& aiconfig) const; Difficulty difficulty() const; AiType const& aitype(unsigned const trickno) const; void set_aitype(unsigned const trickno, AiType const& aitype); void set_aitype_for_all_tricks(AiType const& aitype); unsigned const future_limit(unsigned const trickno) const; void set_future_limit(unsigned const trickno, unsigned const future_limit); void set_future_limit_for_all_tricks(unsigned const future_limit); Rating::Type const& rating(unsigned const trickno) const; void set_rating(unsigned const trickno, Rating::Type const& rating); void set_rating_for_all_tricks(Rating::Type const& rating); // returns the heuristic states vector const& heuristic_states(HeuristicsMap::Key const& key) const; vector const& heuristic_states(HeuristicsMap::GametypeGroup const gametype_group, HeuristicsMap::PlayerTypeGroup const playertype_group ) const; vector& heuristic_states(HeuristicsMap::Key const& key); vector& heuristic_states(HeuristicsMap::GametypeGroup const gametype_group, HeuristicsMap::PlayerTypeGroup const playertype_group ); // returns the heuristics vector heuristics(HeuristicsMap::GametypeGroup const gametype_group, HeuristicsMap::PlayerTypeGroup const playertype_group ) const; // returns the heuristics vector heuristics(Player const& player) const; // returns the value bool value(HeuristicsMap::Key const& key, Heuristic const heuristic) const; bool value(HeuristicsMap::GametypeGroup const gametype_group, HeuristicsMap::PlayerTypeGroup const playertype_group, Heuristic const heuristic) const; bool value(TypeBool const type) const; unsigned value(TypeUnsigned const type) const; Card value(TypeCard const type) const; // the minimum and maximum value unsigned min(TypeUnsigned const& type) const; unsigned max(TypeUnsigned const& type) const; // the valid cards for the type list const& valid_cards(TypeCard const type) const; // sets the value bool set(string const& type, string const& value); void set(HeuristicsMap::GametypeGroup const gametype_group, HeuristicsMap::PlayerTypeGroup const playertype_group, Heuristic const heuristic, string const& value); void move(HeuristicsMap::Key const& key, Heuristic const heuristic, unsigned const pos); void set(Heuristic const heuristic, string const& value); void set(TypeBool const type, string const& value); void set(TypeUnsigned const type, string const& value); void set(TypeCard const type, string const& value); void set(HeuristicsMap::Key const& key, Heuristic const heuristic, bool const value); void set(HeuristicsMap::GametypeGroup const gametype_group, HeuristicsMap::PlayerTypeGroup const playertype_group, Heuristic const heuristic, bool const value); void set_to_default(HeuristicsMap::Key const& key); void set(Heuristic const heuristic, bool const value); void set(TypeBool const type, bool const value); void set(TypeUnsigned const type, unsigned const value); void set(TypeCard const type, Card const value); bool load(string const& filename); bool read(istream& istr); bool read_heuristics(istream& istr); bool save(string const& filename) const; // output of the settings void write(ostream& ostr) const; private: // initializes the heuristic states void init_heuristic_states(); // fills the heuristic states with all heuristics void fill_up_heuristic_states(); private: vector aitype_p; vector rating_p; vector future_limit_p; map > heuristic_states_; vector bool_p; vector unsigned_p; vector card_p; private: // unused Aiconfig(); }; // class Aiconfig namespace HeuristicsMap { typedef std::map > Map; }; // namespace HeuristicsMap // whether the aitype has support for rating bool supports_rating(AiType const type); // whether the two aiconfigs are equal bool operator==(Aiconfig const& aiconfig_a, Aiconfig const& aiconfig_b); // whether the two aiconfigs are different bool operator!=(Aiconfig const& aiconfig_a, Aiconfig const& aiconfig_b); // whether the two heuristic states are equal bool operator==(Aiconfig::HeuristicState const& heuristic_state_a, Aiconfig::HeuristicState const& heuristic_state_b); string name(Aiconfig::Difficulty const difficulty); WRITE_NAME2(Aiconfig, Difficulty) // conversion in a string string name(Aiconfig::Heuristic const heuristic); string name(Aiconfig::TypeBool const type); string name(Aiconfig::TypeUnsigned const type); string name(Aiconfig::TypeCard const type); // output of the name WRITE_NAME2(Aiconfig, Heuristic) WRITE_NAME2(Aiconfig, TypeBool) WRITE_NAME2(Aiconfig, TypeUnsigned) WRITE_NAME2(Aiconfig, TypeCard) // output of the Aiconfig ostream& operator<<(ostream& ostr, Aiconfig const& aiconfig); inline Translator::Translation translation(Aiconfig::Difficulty const& difficulty) { return Translator::Translation(::translator, "AiConfig::Difficulty::" + ::name(difficulty)); } inline Translator::Translation translation(Aiconfig::Heuristic const& heuristic) { return Translator::Translation(::translator, "AiConfig::Heuristic::" + ::name(heuristic)); } inline Translator::Translation translation_description(Aiconfig::Heuristic const& heuristic) { return Translator::Translation(::translator, "AiConfig::Heuristic::Description::" + ::name(heuristic)); } inline Translator::Translation translation(Aiconfig::TypeBool const& type) { return Translator::Translation(::translator, "AiConfig::" + ::name(type)); } inline Translator::Translation translation(Aiconfig::TypeUnsigned const& type) { return Translator::Translation(::translator, "AiConfig::" + ::name(type)); } inline Translator::Translation translation(Aiconfig::TypeCard const& type) { return Translator::Translation(::translator, "AiConfig::" + ::name(type)); } inline Translator::Translation translation(AiType const& aitype) { return Translator::Translation(::translator, "AiConfig::AiType::" + ::name(aitype)); } #endif // #ifndef CLASS_AICONFIG_HEADER