Skip to content

Commit

Permalink
WIP Generalizing the FAI concept of action objects
Browse files Browse the repository at this point in the history
[ci skip]
  • Loading branch information
CelticMinstrel committed Mar 29, 2017
1 parent 9431ae3 commit e79dd62
Show file tree
Hide file tree
Showing 11 changed files with 426 additions and 411 deletions.
57 changes: 57 additions & 0 deletions src/ai/default/attack.cpp
Expand Up @@ -19,6 +19,9 @@

#include "ai/manager.hpp"
#include "ai/default/contexts.hpp"
#include "ai/actions.hpp"
#include "ai/formula/ai.hpp"
#include "ai/composite/contexts.hpp"

#include "actions/attack.hpp"
#include "attack_prediction.hpp"
Expand All @@ -28,6 +31,8 @@
#include "team.hpp"
#include "units/unit.hpp"
#include "formula/callable_objects.hpp" // for location_callable
#include "resources.hpp"
#include "game_board.hpp"

static lg::log_domain log_ai("ai/attack");
#define LOG_AI LOG_STREAM(info, log_ai)
Expand Down Expand Up @@ -401,4 +406,56 @@ void attack_analysis::get_inputs(std::vector<game_logic::formula_input>* inputs)
inputs->push_back(formula_input("is_surrounded", FORMULA_READ_ONLY));
}

variant attack_analysis::execute(variant ctxt) {
//If we get an attack analysis back we will do the first attack.
//Then the AI can get run again and re-choose.
if(movements.empty()) {
return variant(false);
}

unit_map& units = resources::gameboard->units();

//make sure that unit which has to attack is at given position and is able to attack
unit_map::const_iterator unit = units.find(movements.front().first);
if(!unit.valid() || unit->attacks_left() == 0) {
return variant(false);
}

const map_location& move_from = movements.front().first;
const map_location& att_src = movements.front().second;
const map_location& att_dst = target;

//check if target is still valid
unit = units.find(att_dst);
if(unit == units.end()) {
return variant(new game_logic::safe_call_result(this, attack_result::E_EMPTY_DEFENDER, move_from));
}

//check if we need to move
if(move_from != att_src) {
//now check if location to which we want to move is still unoccupied
unit = units.find(att_src);
if(unit != units.end()) {
return variant(new game_logic::safe_call_result(this, move_result::E_NO_UNIT, move_from));
}

ai::move_result_ptr result = get_ai_context(this).execute_move_action(move_from, att_src);
if(!result->is_ok()) {
//move part failed
LOG_AI << "ERROR #" << result->get_status() << " while executing 'attack' formula function\n" << std::endl;
return variant(new game_logic::safe_call_result(this, result->get_status(), result->get_unit_location()));
}
}

if(units.count(att_src)) {
ai::attack_result_ptr result = get_ai_context(this).execute_attack_action(movements.front().second, target, -1);
if(!result->is_ok()) {
//attack failed
LOG_AI << "ERROR #" << result->get_status() << " while executing 'attack' formula function\n" << std::endl;
return variant(new game_logic::safe_call_result(this, result->get_status()));
}
}
return variant(true);
}

} //end of namespace ai
5 changes: 3 additions & 2 deletions src/ai/default/contexts.hpp
Expand Up @@ -55,11 +55,11 @@ struct target {
};


class attack_analysis : public game_logic::formula_callable
class attack_analysis : public game_logic::action_callable
{
public:
attack_analysis() :
game_logic::formula_callable(),
game_logic::action_callable(),
target(),
movements(),
target_value(0.0),
Expand Down Expand Up @@ -138,6 +138,7 @@ class attack_analysis : public game_logic::formula_callable
/** Is true if the units involved in this attack sequence are surrounded. */
bool is_surrounded;

variant execute(variant ctxt) override;
};


Expand Down

0 comments on commit e79dd62

Please sign in to comment.