ai_interface.hpp

Go to the documentation of this file.
00001 /* $Id: ai_interface.hpp 26083 2008-04-25 01:55:51Z soliton $ */
00002 /*
00003    Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file ai_interface.hpp
00016 //! Interface to the AI.
00017 
00018 #ifndef AI_INTERFACE_HPP_INCLUDED
00019 #define AI_INTERFACE_HPP_INCLUDED
00020 
00021 class game_display;
00022 class gamemap;
00023 
00024 #include "formula_callable.hpp"
00025 #include "generic_event.hpp"
00026 #include "pathfind.hpp"
00027 #include "gamestatus.hpp"
00028 
00029 class ai_interface : public game_logic::formula_callable {
00030 public:
00031 
00032     //! A convenient typedef for the often used 'location' object
00033     typedef gamemap::location location;
00034 
00035     //! The standard way in which a map of possible moves is recorded
00036     typedef std::multimap<location,location> move_map;
00037 
00038     //! info is structure which holds references to all the important objects
00039     //! that an AI might need access to, in order to make and implement its decisions.
00040     struct info {
00041         info(game_display& disp, const gamemap& map, unit_map& units,
00042             std::vector<team>& teams, unsigned int team_num, const gamestatus& state, class turn_info& turn_data, class game_state& game_state)
00043             : disp(disp), map(map), units(units), teams(teams),
00044               team_num(team_num), state(state), turn_data_(turn_data), game_state_(game_state)      {}
00045 
00046         //! The display object, used to draw the moves the AI makes.
00047         game_display& disp;
00048 
00049         //! The map of the game -- use this object to find the terrain at any location.
00050         const gamemap& map;
00051 
00052         //! The map of units. It maps locations -> units.
00053         unit_map& units;
00054 
00055         //! A list of the teams in the game.
00056         std::vector<team>& teams;
00057 
00058         //! The number of the team the AI is.
00059         //! Note: this number is 1-based, so 1 must be subtracted
00060         //! for using it as index of 'teams'.
00061         unsigned int team_num;
00062 
00063         //! Information about what turn it is, and what time of day.
00064         const gamestatus& state;
00065 
00066         //! The object that allows the player to interact with the game.
00067         //! Should not be used outside of ai_interface.
00068         class turn_info& turn_data_;
00069 
00070         //! The global game state, because we may set the completion field.
00071         class game_state& game_state_;
00072     };
00073 
00074     //! The constructor.
00075     //! All derived classes should take an argument of type info&
00076     //! which they should pass to this constructor.
00077     ai_interface(info& arg) : info_(arg), last_interact_(0), user_interact_("ai_user_interact"),
00078         unit_recruited_("ai_unit_recruited"), unit_moved_("ai_unit_moved"),
00079         enemy_attacked_("ai_enemy_attacked") {}
00080     virtual ~ai_interface() {}
00081 
00082     //! Function that is called when the AI must play its turn.
00083     //! Derived classes should implement their AI algorithm in this function.
00084     virtual void play_turn() = 0;
00085 
00086     //! Return a reference to the 'team' object for the AI.
00087     team& current_team() { return info_.teams[info_.team_num-1]; }
00088     const team& current_team() const { return info_.teams[info_.team_num-1]; }
00089 
00090     //! Show a diagnostic message on the screen.
00091     void diagnostic(const std::string& msg);
00092 
00093     //! Display a debug message as a chat message.
00094     void log_message(const std::string& msg);
00095 
00096     // Exposes events to allow for attaching/detaching handlers.
00097     events::generic_event& user_interact()  { return user_interact_; }
00098     events::generic_event& unit_recruited() { return unit_recruited_; }
00099     events::generic_event& unit_moved()     { return unit_moved_; }
00100     events::generic_event& enemy_attacked() { return enemy_attacked_; }
00101 
00102 protected:
00103     //! This function should be called to attack an enemy.
00104     void attack_enemy(const location u, const location target, int att_weapon, int def_weapon);
00105 
00106     //! This function should be called to move a unit.
00107     //! Once the unit has been moved, its movement allowance is set to 0.
00108     //! 'from':         the location of the unit being moved.
00109     //! 'to':               the location to be moved to. This must be a valid move for the unit.
00110     //! 'possible_moves':   the map of possible moves, as obtained from 'calculate_possible_moves'.
00111     location move_unit(location from, location to, std::map<location,paths>& possible_moves);
00112 
00113     //! Identical to 'move_unit', except that the unit's movement
00114     //! isn't set to 0 after the move is complete.
00115     location move_unit_partial(location from, location t, std::map<location,paths>& possible_moves);
00116 
00117     //! Calculate the moves units may possibly make.
00118     //! 'possible_moves':   a map which will be filled with the paths each unit can take
00119     //!                     to get to every possible destination.
00120     //!                     You probably don't want to use this object at all, except to pass to 'move_unit'.
00121     //! 'srcdst':           a map of units to all their possible destinations
00122     //! 'dstsrc':           a map of destinations to all the units that can move to that destination
00123     //! 'enemy':            if true, a map of possible moves for enemies will be calculated.
00124     //!                     If false, a map of possible moves for units on the AI's side will be calculated.
00125     //!                     The AI's own leader will not be included in this map.
00126     //! 'assume_full_movement': if true, the function will operate on the assumption
00127     //!                             that all units can move their full movement allotment.
00128     //! 'remove_destinations':      a pointer to a set of possible destinations to omit.
00129     void calculate_possible_moves(std::map<location,paths>& possible_moves, move_map& srcdst, move_map& dstsrc, bool enemy, bool assume_full_movement=false,
00130                                   const std::set<location>* remove_destinations=NULL) const;
00131 
00132   //! A more fundamental version of calculate_possible_moves
00133   //! which allows the use of a speculative unit map.
00134   void calculate_moves(const unit_map& units, std::map<location,paths>& possible_moves, move_map& srcdst, move_map& dstsrc, bool enemy, bool assume_full_movement=false,
00135        const std::set<location>* remove_destinations=NULL, bool see_all=false) const;
00136 
00137     //! Recruit a unit. It will recruit the unit with the given name,
00138     //! at the given location, or at an available location to recruit units
00139     //! if 'loc' is not a valid recruiting location.
00140     //!
00141     //! @retval false if recruitment cannot be performed,
00142     //!             because there are no available tiles,
00143     //!         or not enough money.
00144     bool recruit(const std::string& unit_name, location loc=location());
00145 
00146     //! functions to retrieve the 'info' object.
00147     //! Used by derived classes to discover all necessary game information.
00148     info& get_info() { return info_; }
00149     const info& get_info() const { return info_; }
00150 
00151     //! Function which should be called frequently to allow the user
00152     //! to interact with the interface.
00153     //! This function will make sure that interaction doesn't occur too often,
00154     //! so there is no problem with calling it very regularly.
00155     void raise_user_interact();
00156 
00157     //! Notifies all interested observers of the event respectively.
00158     void raise_unit_recruited() { unit_recruited_.notify_observers(); }
00159     void raise_unit_moved() {  unit_moved_.notify_observers(); }
00160     void raise_enemy_attacked() { enemy_attacked_.notify_observers(); }
00161 protected:
00162     virtual void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
00163     virtual variant get_value(const std::string& key) const;
00164 private:
00165     info info_;
00166     int last_interact_;
00167     events::generic_event user_interact_;
00168     events::generic_event unit_recruited_;
00169     events::generic_event unit_moved_;
00170     events::generic_event enemy_attacked_;
00171 };
00172 
00173 //! Returns all currently available AIs.
00174 std::vector<std::string> get_available_ais();
00175 //! Create a new AI object with the specified algorithm name.
00176 ai_interface* create_ai(const std::string& algorithm_name, ai_interface::info& info);
00177 
00178 #endif

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs