ai/actions.hpp

Go to the documentation of this file.
00001 /* $Id: actions.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2009 - 2012 by Yurii Chernyi <terraninfo@terraninfo.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 as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * Managing the AI-Game interaction - AI actions and their results
00018  * @file
00019  * */
00020 
00021 #ifndef AI_ACTIONS_HPP_INCLUDED
00022 #define AI_ACTIONS_HPP_INCLUDED
00023 
00024 #include "game_info.hpp"
00025 
00026 #include "../actions.hpp"
00027 
00028 namespace pathfind {
00029 struct plain_route;
00030 } // of namespace pathfind
00031 
00032 class team;
00033 class gamemap;
00034 
00035 namespace ai {
00036 
00037 class action_result {
00038 public:
00039 
00040     enum tresult {
00041         AI_ACTION_SUCCESS = 0,
00042         AI_ACTION_STARTED = 1,
00043         AI_ACTION_FAILURE = -1
00044     };
00045 
00046     virtual ~action_result();
00047 
00048     /* check as must as possible without executing anything */
00049     void check_before();
00050 
00051     /* execute the action */
00052     void execute();
00053 
00054     /* has the game state changed during execution ? */
00055     bool is_gamestate_changed() const;
00056 
00057     /* check the return value of the action. mandatory to call. */
00058     bool is_ok();
00059 
00060     /* get the return value of the action */
00061     int get_status() const;
00062 
00063     /* describe the action */
00064     virtual std::string do_describe() const =0;
00065 protected:
00066     action_result( side_number side );
00067 
00068     /* do check before execution or just check. setting status_ via set_error to != cancels the execution.*/
00069     virtual void do_check_before() = 0;
00070 
00071     /* do some additional checks after execution. */
00072     virtual void do_check_after() = 0;
00073 
00074     /* execute. assert(is_success()) */
00075     virtual void do_execute() = 0;
00076 
00077     /* runs before cheching before execution */
00078     virtual void do_init_for_execution() = 0;
00079 
00080     /* are we going to execute the action now ? */
00081     bool is_execution() const;
00082 
00083     /* return the side number */
00084     int get_side() const { return side_; }
00085 
00086     /* return real information about the game state */
00087     game_info& get_info() const;
00088 
00089     team& get_my_team() const;
00090 
00091     /* set error code */
00092     void set_error(int error_code, bool log_as_error = true);
00093 
00094     /* is error code equal to 0 (no errors)? */
00095     bool is_success() const;
00096 
00097     /* note that the game state has been changed */
00098     void set_gamestate_changed();
00099 private:
00100 
00101     /* Check after the execution */
00102     void check_after();
00103 
00104     /* Initialization before execution */
00105     void init_for_execution();
00106 
00107     /* set the flag that the return value had been checked */
00108     void set_ok_checked();
00109 
00110     /* was the return value checked ? */
00111     bool return_value_checked_;
00112 
00113     /* current side number */
00114     int side_;
00115 
00116     /* execution status. if 0, all is ok. if !=0, then there were some problems. */
00117     int status_;
00118 
00119     /* are we going to execute the action now ? */
00120     bool is_execution_;
00121 
00122     bool is_gamestate_changed_;
00123 
00124 };
00125 
00126 class attack_result : public action_result {
00127 public:
00128     attack_result( side_number side,
00129         const map_location& attacker_loc,
00130         const map_location& defender_loc,
00131         int attacker_weapon,
00132         double aggression );
00133 
00134     enum tresult {
00135         E_EMPTY_ATTACKER = 1001,
00136         E_EMPTY_DEFENDER = 1002,
00137         E_INCAPACITATED_ATTACKER = 1003,
00138         E_INCAPACITATED_DEFENDER = 1004,
00139         E_NOT_OWN_ATTACKER = 1005,
00140         E_NOT_ENEMY_DEFENDER = 1006,
00141         E_NO_ATTACKS_LEFT = 1007,
00142         E_WRONG_ATTACKER_WEAPON = 1008,
00143         E_UNABLE_TO_CHOOSE_ATTACKER_WEAPON = 1009,
00144         E_ATTACKER_AND_DEFENDER_NOT_ADJACENT = 1010
00145     };
00146 
00147     virtual std::string do_describe() const;
00148 protected:
00149     virtual void do_check_before();
00150     virtual void do_check_after();
00151     virtual void do_execute();
00152     virtual void do_init_for_execution();
00153 private:
00154     const map_location& attacker_loc_;
00155     const map_location& defender_loc_;
00156     int attacker_weapon_;
00157     double aggression_;
00158 };
00159 
00160 class move_result : public action_result {
00161 public:
00162     move_result( side_number side,
00163         const map_location& from,
00164         const map_location& to,
00165         bool remove_movement,
00166         bool unreach_is_ok);
00167 
00168     enum tresult {
00169         E_EMPTY_MOVE = 2001,
00170         E_NO_UNIT = 2002,
00171         E_NOT_OWN_UNIT = 2003,
00172         E_INCAPACITATED_UNIT = 2004,
00173         E_AMBUSHED = 2005,
00174         E_FAILED_TELEPORT = 2006,
00175         E_NOT_REACHED_DESTINATION = 2007,
00176         E_NO_ROUTE = 2008
00177     };
00178 
00179     virtual std::string do_describe() const;
00180     virtual const map_location& get_unit_location() const;
00181 protected:
00182     virtual void do_check_before();
00183     virtual void do_check_after();
00184     virtual void do_execute();
00185     virtual void do_init_for_execution();
00186 private:
00187     const unit *get_unit();
00188     bool test_route(const unit &un);
00189     const map_location from_;
00190     move_unit_spectator move_spectator_;
00191     const map_location to_;
00192     bool remove_movement_;
00193     boost::shared_ptr<pathfind::plain_route> route_;
00194     map_location unit_location_;
00195     bool unreach_is_ok_;
00196 };
00197 
00198 
00199 class recall_result : public action_result {
00200 public:
00201     recall_result (side_number side, const std::string &unit_id, const map_location& where, const map_location& from);
00202 
00203     enum tresult {
00204         E_NOT_AVAILABLE_FOR_RECALLING = 6001,
00205         E_NO_GOLD = 6003,
00206         E_NO_LEADER = 6004,
00207         E_LEADER_NOT_ON_KEEP = 6005,
00208         E_BAD_RECALL_LOCATION = 6006
00209     };
00210 
00211     virtual std::string do_describe() const;
00212 protected:
00213     virtual void do_check_before();
00214     virtual void do_check_after();
00215     virtual void do_execute();
00216     virtual void do_init_for_execution();
00217 private:
00218     bool test_available_for_recalling(
00219         const team& my_team);
00220     bool test_enough_gold(
00221         const team& my_team);
00222     const unit *get_leader();
00223     bool test_leader_on_keep(
00224         const unit &my_leader);
00225     bool test_suitable_recall_location(
00226         const unit &my_leader);
00227 
00228     const std::string& unit_id_;
00229     const map_location where_;
00230     map_location recall_location_;
00231     map_location recall_from_;
00232 };
00233 
00234 class recruit_result : public action_result {
00235 public:
00236     recruit_result( side_number side, const std::string& unit_name, const map_location& where, const map_location& from);
00237 
00238     enum tresult {
00239         E_NOT_AVAILABLE_FOR_RECRUITING = 3001,
00240         E_UNKNOWN_OR_DUMMY_UNIT_TYPE = 3002,
00241         E_NO_GOLD = 3003,
00242         E_NO_LEADER = 3004,
00243         E_LEADER_NOT_ON_KEEP = 3005,
00244         E_BAD_RECRUIT_LOCATION = 3006
00245     };
00246 
00247     virtual std::string do_describe() const;
00248 protected:
00249     virtual void do_check_before();
00250     virtual void do_check_after();
00251     virtual void do_execute();
00252     virtual void do_init_for_execution();
00253 private:
00254     const std::string &get_available_for_recruiting(
00255         const team& my_team);
00256     const unit_type *get_unit_type_known(
00257         const std::string &recruit);
00258     bool test_enough_gold(
00259         const team& my_team,
00260         const unit_type &type );
00261     const unit *get_leader();
00262     bool test_leader_on_keep(
00263         const unit &my_leader);
00264     bool test_suitable_recruit_location (
00265         const unit &my_leader);
00266     const std::string& unit_name_;
00267     const map_location& where_;
00268     map_location recruit_location_;
00269     map_location recruit_from_;
00270     int num_;
00271 };
00272 
00273 class stopunit_result : public action_result {
00274 public:
00275     stopunit_result( side_number side,
00276         const map_location& unit_location,
00277         bool remove_movement,
00278         bool remove_attacks );
00279 
00280     enum tresult {
00281         E_NO_UNIT = 4002,
00282         E_NOT_OWN_UNIT = 4003,
00283         E_INCAPACITATED_UNIT = 4004
00284     };
00285 
00286     virtual std::string do_describe() const;
00287 protected:
00288     virtual void do_check_before();
00289     virtual void do_check_after();
00290     virtual void do_execute();
00291     virtual void do_init_for_execution();
00292 private:
00293     const unit *get_unit();
00294     const map_location& unit_location_;
00295     const bool remove_movement_;
00296     const bool remove_attacks_;
00297 };
00298 
00299 
00300 class actions {
00301 
00302 public:
00303 // =======================================================================
00304 // Stateless interface to actions
00305 // =======================================================================
00306 
00307 
00308 /**
00309  * Ask the game to attack an enemy defender using our unit attacker from attackers current location,
00310  * @param side the side which tries to execute the move
00311  * @param execute should move be actually executed or not
00312  * @param attacker_loc location of attacker
00313  * @param defender_loc location of defender
00314  * @param attacker_weapon weapon of attacker
00315  * @param aggression aggression of attacker, is used to determine attacker's weapon if it is not specified
00316  * @retval possible result: ok
00317  * @retval possible result: something wrong
00318  * @retval possible result: attacker and/or defender are invalid
00319  * @retval possible result: attacker doesn't have the specified weapon
00320  */
00321 static attack_result_ptr execute_attack_action( side_number side,
00322     bool execute,
00323     const map_location& attacker_loc,
00324     const map_location& defender_loc,
00325     int attacker_weapon,
00326     double aggression );
00327 
00328 
00329 /**
00330  * Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial move
00331  * @param side the side which tries to execute the move
00332  * @param execute should move be actually executed or not
00333  * @param from location of our unit
00334  * @param to where to move
00335  * @param remove_movement set unit movement to 0 in case of successful move
00336  * @retval possible result: ok
00337  * @retval possible result: something wrong
00338  * @retval possible result: move is interrupted
00339  * @retval possible result: move is impossible
00340  */
00341 static move_result_ptr execute_move_action( side_number side,
00342     bool execute,
00343     const map_location& from,
00344     const map_location& to,
00345     bool remove_movement,
00346     bool unreach_is_ok = false);
00347 
00348 
00349 
00350 /**
00351  * Ask the game to recall a unit for us on specified location
00352  * @param side the side which tries to execute the move
00353  * @param execute should move be actually executed or not
00354  * @param unit_id the id of the unit to be recalled.
00355  * @param where location where the unit is to be recalled.
00356  * @retval possible result: ok
00357  * @retval possible_result: something wrong
00358  * @retval possible_result: leader not on keep
00359  * @retval possible_result: no free space on keep
00360  * @retval possible_result: not enough gold
00361  */
00362 static recall_result_ptr execute_recall_action( side_number side,
00363     bool execute,
00364     const std::string& unit_id,
00365     const map_location& where,
00366     const map_location& from);
00367 
00368 
00369 
00370 /**
00371  * Ask the game to recruit a unit for us on specified location
00372  * @param side the side which tries to execute the move
00373  * @param execute should move be actually executed or not
00374  * @param unit_name the name of the unit to be recruited.
00375  * @param where location where the unit is to be recruited.
00376  * @retval possible result: ok
00377  * @retval possible_result: something wrong
00378  * @retval possible_result: leader not on keep
00379  * @retval possible_result: no free space on keep
00380  * @retval possible_result: not enough gold
00381  */
00382 static recruit_result_ptr execute_recruit_action( side_number side,
00383     bool execute,
00384     const std::string& unit_name,
00385     const map_location& where,
00386     const map_location& from);
00387 
00388 
00389 /**
00390  * Ask the game to remove unit movements and/or attack
00391  * @param side the side which tries to execute the move
00392  * @param execute should move be actually executed or not
00393  * @param unit_location the location of our unit
00394  * @param remove_movement set remaining movements to 0
00395  * @param remove_attacks set remaining attacks to 0
00396  * @retval possible result: ok
00397  * @retval possible_result: something wrong
00398  * @retval possible_result: nothing to do
00399  */
00400 static stopunit_result_ptr execute_stopunit_action( side_number side,
00401     bool execute,
00402     const map_location& unit_location,
00403     bool remove_movement,
00404     bool remove_attacks );
00405 
00406 
00407 /**
00408  * get human-readable name of the error by code.
00409  * @param error_code error code.
00410  * @retval result the name of the error.
00411  */
00412 const static std::string& get_error_name(int error_code);
00413 
00414 private:
00415 
00416 static std::map<int,std::string> error_names_;
00417 
00418 };
00419 
00420 
00421 ///@todo 1.7.11 important! Add an ai action (and fai function) to set a goto on a unit
00422 ///@todo 1.7.11 important! Add an ai action (and fai function) to send a chat message to a player
00423 
00424 } //end of namespace ai
00425 
00426 std::ostream &operator<<(std::ostream &s, ai::attack_result const &r);
00427 std::ostream &operator<<(std::ostream &s, ai::move_result const &r);
00428 std::ostream &operator<<(std::ostream &s, ai::recall_result const &r);
00429 std::ostream &operator<<(std::ostream &s, ai::recruit_result const &r);
00430 std::ostream &operator<<(std::ostream &s, ai::stopunit_result const &r);
00431 
00432 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Tue May 22 2012 01:03:34 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs