31 #define DBG_AI LOG_STREAM(debug, log_formula_ai) 32 #define LOG_AI LOG_STREAM(info, log_formula_ai) 33 #define WRN_AI LOG_STREAM(warn, log_formula_ai) 34 #define ERR_AI LOG_STREAM(err, log_formula_ai) 39 auto fai = std::dynamic_pointer_cast<
const formula_ai>(for_fai);
40 assert(fai !=
nullptr);
41 return *std::const_pointer_cast<
formula_ai>(fai)->ai_ptr_;
49 variant move_map_callable::get_value(
const std::string& key)
const 52 std::vector<variant> vars;
53 for(move_map::const_iterator
i = srcdst_.begin();
i != srcdst_.end(); ++
i) {
54 if(
i->first ==
i->second || units_.count(
i->second) == 0) {
55 auto item = std::make_shared<move_callable>(
i->first,
i->second);
56 vars.emplace_back(
item);
61 }
else if(key ==
"has_moves") {
62 return variant(!srcdst_.empty());
70 add_input(inputs,
"moves");
76 if(mv_callable ==
nullptr) {
77 return formula_callable::do_compare(callable);
83 if (
int cmp = src_.do_compare(other_src)) {
94 if(!move_result->is_ok()) {
95 LOG_AI <<
"ERROR #" << move_result->get_status() <<
" while executing 'move' formula function";
96 return variant(std::make_shared<safe_call_result>(fake_ptr(), move_result->get_status(), move_result->get_unit_location()));
99 return variant(move_result->is_gamestate_changed());
105 if(mv_callable ==
nullptr) {
106 return formula_callable::do_compare(callable);
112 if (
int cmp = src_.do_compare(other_src)) {
123 if(!move_result->is_ok()) {
124 LOG_AI <<
"ERROR #" << move_result->get_status() <<
" while executing 'move_partial' formula function";
125 return variant(std::make_shared<safe_call_result>(fake_ptr(), move_result->get_status(), move_result->get_unit_location()));
128 return variant(move_result->is_gamestate_changed());
131 variant position_callable::get_value(
const std::string& key)
const {
132 if(key ==
"chance") {
140 add_input(inputs,
"chance");
143 variant outcome_callable::get_value(
const std::string& key)
const {
144 if(key ==
"hitpoints_left") {
146 }
else if(key ==
"probability") {
148 }
else if(key ==
"possible_status") {
156 add_input(inputs,
"hitpoints_left");
157 add_input(inputs,
"probability");
158 add_input(inputs,
"possible_status");
163 : move_from_(move_from), src_(src), dst_(dst),
171 if(key ==
"attack_from") {
172 return variant(std::make_shared<location_callable>(
src_));
173 }
else if(key ==
"defender") {
174 return variant(std::make_shared<location_callable>(
dst_));
175 }
else if(key ==
"move_from") {
191 if(a_callable ==
nullptr) {
208 const int other_weapon = a_callable->
weapon();
209 if (
int cmp = (this->
weapon() - other_weapon)) {
218 bool gamestate_changed =
false;
223 gamestate_changed |= move_result->is_gamestate_changed();
225 if(!move_result->is_ok()) {
227 LOG_AI <<
"ERROR #" << move_result->get_status() <<
" while executing 'attack' formula function";
228 return variant(std::make_shared<safe_call_result>(
fake_ptr(), move_result->get_status(), move_result->get_unit_location()));
232 if(!move_result || move_result->is_ok()) {
235 gamestate_changed |= attack_result->is_gamestate_changed();
236 if(!attack_result->is_ok()) {
238 LOG_AI <<
"ERROR #" << attack_result->get_status() <<
" while executing 'attack' formula function";
239 return variant(std::make_shared<safe_call_result>(
fake_ptr(), attack_result->get_status()));
243 return variant(gamestate_changed);
247 if(key ==
"attacks") {
248 std::vector<variant> vars;
251 if(units_.count(
i->second) == 0) {
252 collect_possible_attacks(vars,
i->first,
i->second);
258 collect_possible_attacks(vars,
i->get_location(),
i->get_location());
279 if (unit == units_.end())
283 unit->incapacitated() ||
284 unit->invisible(unit->get_location()))
287 auto item = std::make_shared<attack_callable>(attacker_location, attack_position, adj, -1);
288 vars.emplace_back(
item);
296 return variant(std::make_shared<location_callable>(
loc_));
309 if(recall_result->is_ok()) {
310 recall_result->execute();
312 LOG_AI <<
"ERROR #" << recall_result->get_status() <<
" while executing 'recall' formula function";
313 return variant(std::make_shared<safe_call_result>(
fake_ptr(), recall_result->get_status()));
316 return variant(recall_result->is_gamestate_changed());
320 if( key ==
"unit_type")
322 if( key ==
"recruit_loc")
323 return variant(std::make_shared<location_callable>(
loc_));
338 if(recruit_result->is_ok()) {
339 recruit_result->execute();
341 LOG_AI <<
"ERROR #" << recruit_result->get_status() <<
" while executing 'recruit' formula function";
342 return variant(std::make_shared<safe_call_result>(
fake_ptr(), recruit_result->get_status()));
347 return variant(recruit_result->is_gamestate_changed());
352 return variant(std::make_shared<location_callable>(
loc_));
383 LOG_AI <<
"Setting unit variable: " << key_ <<
" -> " << value_.to_debug_string();
384 unit->formula_manager().add_formula_var(key_, value_);
388 ERR_AI <<
"ERROR #" << status <<
" while executing 'set_unit_var' formula function";
389 return variant(std::make_shared<safe_call_result>(
fake_ptr(), status));
int do_compare(const formula_callable *callable) const override
Compare two attacks in deterministic way or compare pointers (nondeterministic in consequent game run...
variant execute_self(variant ctxt) override
variant get_value(const std::string &key) const override
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
virtual const unit_map & units() const override
This class represents a single unit of a specific type.
virtual recall_result_ptr check_recall_action(const std::string &id, const map_location &where=map_location::null_location(), const map_location &from=map_location::null_location())=0
const map_location & src() const
Managing the AI-Game interaction - AI actions and their results.
void get_inputs(formula_input_vector &inputs) const override
virtual const move_map & get_srcdst() const override
int do_compare(const map_location &a) const
three-way comparator
std::shared_ptr< move_result > move_result_ptr
std::vector< formula_input > formula_input_vector
std::shared_ptr< recruit_result > recruit_result_ptr
std::shared_ptr< attack_result > attack_result_ptr
ai_context & get_ai_context(wfl::const_formula_callable_ptr for_fai)
A small explanation about what's going on here: Each action has access to two game_info objects First...
std::shared_ptr< recall_result > recall_result_ptr
void get_inputs(formula_input_vector &inputs) const override
void get_inputs(formula_input_vector &inputs) const override
bool is_enemy(int n) const
variant execute_self(variant ctxt) override
int defender_weapon() const
variant execute_self(variant ctxt) override
variant get_value(const std::string &key) const override
virtual attack_result_ptr execute_attack_action(const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon)=0
Encapsulates the map of the game.
const_formula_callable_ptr as_callable() const
unit_iterator find(std::size_t id)
void get_inputs(formula_input_vector &inputs) const override
virtual const team & current_team() const override
Game information for the AI.
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
variant execute_self(variant ctxt) override
variant execute_self(variant ctxt) override
virtual side_number get_side() const override
Get the side number.
virtual recruit_result_ptr check_recruit_action(const std::string &unit_name, const map_location &where=map_location::null_location(), const map_location &from=map_location::null_location())=0
std::shared_ptr< const formula_callable > const_formula_callable_ptr
const map_location & move_from() const
variant get_value(const std::string &key) const override
void collect_possible_attacks(std::vector< variant > &vars, map_location attacker_location, map_location attack_position) const
Standard logging facilities (interface).
Container associating units to locations.
const map_location & dst() const
variant get_value(const std::string &key) const override
std::pair< std::string, unsigned > item
virtual move_result_ptr execute_move_action(const map_location &from, const map_location &to, bool remove_movement=true, bool unreach_is_ok=false)=0