Adding new files concerning new AI...
...(ai/akihara/recruitment.?pp) and new scenario for the ai_arena_small.
This commit is contained in:
parent
b40dc28d59
commit
104a28654d
10 changed files with 385 additions and 1 deletions
|
@ -18,6 +18,8 @@ Version 1.11.0-svn:
|
|||
markup character (any of *, `, ~, {, ^, }, |, @, #, <, &)
|
||||
* AI:
|
||||
* AI now properly considers the expected damage from poison when attacking using poisoners.
|
||||
* Adding a new scenario for the ai-arena-small in order to test the new AI.
|
||||
* Adding new files for the new AI (ai/akihara/recruitment.?pp)
|
||||
* Campaigns:
|
||||
* Added a note to all final scenarios, stating which one is the last scenario
|
||||
* Dead Water:
|
||||
|
|
27
data/ai/dev/akihara_recruitment.cfg
Normal file
27
data/ai/dev/akihara_recruitment.cfg
Normal file
|
@ -0,0 +1,27 @@
|
|||
#textdomain wesnoth
|
||||
{core/macros}
|
||||
|
||||
[ai]
|
||||
id=ai_akihara
|
||||
description="Experimental Recruitment AI"
|
||||
version=10800
|
||||
[stage]
|
||||
id=main_loop
|
||||
name=testing_ai_default::candidate_action_evaluation_loop
|
||||
{AI_CA_GOTO}
|
||||
[candidate_action]
|
||||
id=alternate_recruitment
|
||||
engine=cpp
|
||||
name=akihara_recruitment::recruitment
|
||||
max_score={AI_CA_RECRUITMENT_SCORE}
|
||||
score={AI_CA_RECRUITMENT_SCORE}
|
||||
[/candidate_action]
|
||||
{AI_CA_MOVE_LEADER_TO_GOALS}
|
||||
{AI_CA_MOVE_LEADER_TO_KEEP}
|
||||
{AI_CA_COMBAT}
|
||||
{AI_CA_HEALING}
|
||||
{AI_CA_VILLAGES}
|
||||
{AI_CA_RETREAT}
|
||||
{AI_CA_MOVE_TO_TARGETS}
|
||||
[/stage]
|
||||
[/ai]
|
31
data/ai/scenarios/ai_arena_small/0005-recruitment_test.cfg
Normal file
31
data/ai/scenarios/ai_arena_small/0005-recruitment_test.cfg
Normal file
|
@ -0,0 +1,31 @@
|
|||
#textdomain wesnoth
|
||||
[event]
|
||||
name=preload
|
||||
first_time_only=no
|
||||
[lua]
|
||||
code = << register_test('0005-recruitment_test','Recruitment test'); >>
|
||||
[/lua]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=0005-recruitment_test
|
||||
first_time_only=no
|
||||
|
||||
[message]
|
||||
speaker=narrator
|
||||
image=wesnoth-icon.png
|
||||
message= "This situation should test the recruitment phase"
|
||||
[/message]
|
||||
[move_unit]
|
||||
name="Challenger AI"
|
||||
to_x,to_y=15,2
|
||||
[/move_unit]
|
||||
[move_unit]
|
||||
name="Champion AI"
|
||||
to_x,to_y=15,24
|
||||
[/move_unit]
|
||||
[modify_side]
|
||||
side=2
|
||||
switch_ai=$test_path_to_akihara_recruitment
|
||||
[/modify_side]
|
||||
[/event]
|
|
@ -51,9 +51,13 @@
|
|||
name=test_path_to_testing_ai_default
|
||||
value=ai/dev/testing_ai_default.cfg
|
||||
[/set_variable]
|
||||
[set_variable]
|
||||
name=test_path_to_akihara_recruitment
|
||||
value=ai/dev/akihara_recruitment.cfg
|
||||
[/set_variable]
|
||||
[set_variable]
|
||||
name=test_id
|
||||
value=0002-poisoning
|
||||
value=0005-recruitment_test
|
||||
[/set_variable]
|
||||
|
||||
[set_menu_item]
|
||||
|
@ -119,6 +123,7 @@
|
|||
team_name=north
|
||||
user_team_name= "North"
|
||||
fog=yes
|
||||
recruit="Dwarvish Guardsman,Dwarvish Fighter,Dwarvish Thunderer,Thief,Poacher,Footpad"
|
||||
[/side]
|
||||
[side]
|
||||
side=3
|
||||
|
@ -129,6 +134,7 @@
|
|||
team_name=south
|
||||
user_team_name= "South"
|
||||
fog=yes
|
||||
recruit="Dwarvish Guardsman,Dwarvish Fighter,Dwarvish Thunderer,Thief,Poacher,Footpad"
|
||||
[/side]
|
||||
|
||||
[event]
|
||||
|
@ -169,6 +175,15 @@
|
|||
[option]
|
||||
message="I am happy with the current AI of team 2, [$test_path_to_ai]"
|
||||
[/option]
|
||||
[option]
|
||||
message="Akihara's ai will be awesome, won't it?"
|
||||
[command]
|
||||
[set_variable]
|
||||
name=test_path_to_ai
|
||||
value=$test_path_to_akihara_recruitment
|
||||
[/set_variable]
|
||||
[/command]
|
||||
[/option]
|
||||
[option]
|
||||
message="My AI is TESTING AI DEFAULT, implemented as ai_composite."
|
||||
[command]
|
||||
|
|
|
@ -3,6 +3,7 @@ src/actions.cpp
|
|||
src/addon/manager.cpp
|
||||
src/addon/validation.cpp
|
||||
src/ai/actions.cpp
|
||||
src/ai/akihara/recruitment.cpp
|
||||
src/ai/composite/ai.cpp
|
||||
src/ai/composite/aspect.cpp
|
||||
src/ai/composite/component.cpp
|
||||
|
|
|
@ -590,6 +590,7 @@ set(wesnoth-main_SRC
|
|||
addon/state.cpp
|
||||
addon/validation.cpp
|
||||
ai/actions.cpp
|
||||
ai/akihara/recruitment.cpp
|
||||
ai/composite/ai.cpp
|
||||
ai/composite/aspect.cpp
|
||||
ai/composite/component.cpp
|
||||
|
|
|
@ -170,6 +170,7 @@ wesnoth_sources = Split("""
|
|||
addon/state.cpp
|
||||
addon/validation.cpp
|
||||
ai/actions.cpp
|
||||
ai/akihara/recruitment.cpp
|
||||
ai/composite/ai.cpp
|
||||
ai/composite/aspect.cpp
|
||||
ai/composite/component.cpp
|
||||
|
|
203
src/ai/akihara/recruitment.cpp
Normal file
203
src/ai/akihara/recruitment.cpp
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
Copyright (C) 2009 - 2012 by Aline Riss <aline.riss@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
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.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Experimental recruitment phase
|
||||
*/
|
||||
#include "recruitment.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "../composite/rca.hpp"
|
||||
#include "../../resources.hpp"
|
||||
#include "../../unit_map.hpp"
|
||||
#include "../../map.hpp"
|
||||
#include "../../team.hpp"
|
||||
#include "../../unit_display.hpp"
|
||||
#include "../../unit_types.hpp"
|
||||
|
||||
#include "../../log.hpp"
|
||||
|
||||
static lg::log_domain log_ai_aki("ai/aki");
|
||||
#define DBG_AI_AKI LOG_STREAM(debug, log_ai_aki)
|
||||
#define LOG_AI_AKI LOG_STREAM(info, log_ai_aki)
|
||||
#define WRN_AI_AKI LOG_STREAM(warn, log_ai_aki)
|
||||
#define ERR_AI_AKI LOG_STREAM(err, log_ai_aki)
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
//silence "inherits via dominance" warnings
|
||||
#pragma warning(disable:4250)
|
||||
#endif
|
||||
|
||||
namespace ai {
|
||||
|
||||
namespace akihara_recruitment {
|
||||
|
||||
recruitment::recruitment(rca_context &context, const config &cfg)
|
||||
: candidate_action(context,cfg),
|
||||
depth_(2)
|
||||
{
|
||||
BOOST_FOREACH( team &t, *resources::teams) {
|
||||
if (current_team().is_enemy(t.side()))
|
||||
enemy_.push_back(t);
|
||||
else if (!current_team().is_enemy(t.side()))
|
||||
ally_.push_back(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
recruitment::~recruitment()
|
||||
{
|
||||
}
|
||||
|
||||
double recruitment::evaluate()
|
||||
{
|
||||
std::vector<unit_map::unit_iterator> leaders = resources::units->find_leaders(get_side());
|
||||
|
||||
BOOST_FOREACH(unit_map::unit_iterator &leader, leaders){
|
||||
if (leader == resources::units->end()) {
|
||||
return BAD_SCORE;
|
||||
}
|
||||
|
||||
std::set<map_location> checked_hexes;
|
||||
const map_location &keep = leader->get_location();
|
||||
checked_hexes.insert(keep);
|
||||
|
||||
if (resources::game_map->is_keep(leader->get_location()) && count_free_hexes_in_castle(leader->get_location(), checked_hexes) != 0) {
|
||||
return get_score();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return BAD_SCORE;
|
||||
}
|
||||
|
||||
struct situation recruitment::get_next_stage(std::string unit, situation current) {
|
||||
situation new_situation;
|
||||
|
||||
new_situation.ally_new_unit = current.ally_new_unit;
|
||||
new_situation.enemy_new_unit = current.enemy_new_unit;
|
||||
|
||||
if (current.current_team_side == current_team().side()) {
|
||||
new_situation.new_unit = unit;
|
||||
} else {
|
||||
new_situation.new_unit = current.new_unit;
|
||||
new_situation.enemy_new_unit.insert(unit);
|
||||
}
|
||||
|
||||
new_situation.current_team_side = get_next_team(current.current_team_side);
|
||||
|
||||
if (new_situation.current_team_side == -1) {
|
||||
LOG_AI_AKI << "Error: get_mext_team";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (current_team().is_enemy(new_situation.current_team_side) && new_situation.current_team_side != enemy_[0].side())
|
||||
new_situation.depth = current.depth;
|
||||
else
|
||||
new_situation.depth = current.depth - 1;
|
||||
|
||||
|
||||
|
||||
|
||||
return new_situation;
|
||||
}
|
||||
|
||||
int recruitment::get_next_team(int current_side) {
|
||||
if (current_team().side() == current_side)
|
||||
return enemy_[0].side();
|
||||
|
||||
unsigned i;
|
||||
for(i = 0; i < enemy_.size()-1; i++) {
|
||||
if (enemy_[i].side() == current_side)
|
||||
return enemy_[i+1].side();
|
||||
}
|
||||
if (enemy_[enemy_.size()-1].side() == current_side)
|
||||
return current_team().side();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct situation recruitment::do_min_max(situation current) {
|
||||
LOG_AI_AKI << "\nDepth : " << current.depth << "; Side : " << current.current_team_side << "\n";
|
||||
|
||||
if (current.depth == 0) {
|
||||
LOG_AI_AKI << "On evalue " << current.new_unit << "\n";
|
||||
current.score = evaluate_unit(current);
|
||||
return current;
|
||||
}
|
||||
|
||||
situation best_situation;
|
||||
best_situation = do_min_max(get_next_stage("", current));
|
||||
|
||||
std::set<std::string> list = get_current_team_recruit(current.current_team_side).recruits();
|
||||
|
||||
BOOST_FOREACH(std::string unit, list) {
|
||||
situation new_situation;
|
||||
new_situation = do_min_max(get_next_stage(unit, current));
|
||||
|
||||
if (new_situation.score > best_situation.score)
|
||||
best_situation = new_situation;
|
||||
}
|
||||
|
||||
return best_situation;
|
||||
}
|
||||
|
||||
team recruitment::get_current_team_recruit(int side) {
|
||||
BOOST_FOREACH( team &t, *resources::teams) {
|
||||
if (t.side() == side)
|
||||
return t;
|
||||
}
|
||||
|
||||
return current_team();
|
||||
}
|
||||
|
||||
double recruitment::evaluate_unit(situation current) {
|
||||
|
||||
LOG_AI_AKI << "EVALUATION! unit: " << current.new_unit << "; enemies : \n";
|
||||
BOOST_FOREACH(std::string s, current.enemy_new_unit) {
|
||||
LOG_AI_AKI << s << "\n";
|
||||
}
|
||||
|
||||
double score = 0;
|
||||
|
||||
LOG_AI_AKI << "score = " << score << "\n";
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void recruitment::execute()
|
||||
{
|
||||
LOG_AI_AKI << "Akihara's recruitment begin! \n";
|
||||
LOG_AI_AKI << "Init: Depth : " << depth_ << "; Side : " << current_team().side() << "\n";
|
||||
|
||||
struct situation current_situation;
|
||||
current_situation.current_team_side = current_team().side();
|
||||
current_situation.depth = depth_;
|
||||
|
||||
situation best_situation = do_min_max(current_situation);
|
||||
|
||||
LOG_AI_AKI << "Unit to recruit is.... " << best_situation.new_unit << "\n";
|
||||
}
|
||||
|
||||
|
||||
} //end of akihara_recruitment
|
||||
|
||||
} // end of namespace ai
|
99
src/ai/akihara/recruitment.hpp
Normal file
99
src/ai/akihara/recruitment.hpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* $Id: ca_testing_recruitment.hpp 52533 2012-01-07 02:35:17 +0000 (Sat, 07 Jan 2012) shadowmaster $ */
|
||||
/*
|
||||
Copyright (C) 2009 - 2012 by Yurii Chernyi <terraninfo@terraninfo.net>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
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.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Strategic recruitment routine, for experimentation
|
||||
*/
|
||||
|
||||
#ifndef AKIHARA_AI_HPP_INCLUDED
|
||||
#define AKIHARA_AI_HPP_INCLUDED
|
||||
|
||||
#include "../composite/rca.hpp"
|
||||
#include "../../team.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
//silence "inherits via dominance" warnings
|
||||
#pragma warning(disable:4250)
|
||||
#endif
|
||||
|
||||
namespace ai {
|
||||
|
||||
namespace akihara_recruitment {
|
||||
|
||||
struct situation {
|
||||
|
||||
int depth;
|
||||
|
||||
//Score of the current situation;
|
||||
double score;
|
||||
|
||||
//Current team to analyze
|
||||
int current_team_side;
|
||||
|
||||
//New unit of AI
|
||||
std::string new_unit;
|
||||
|
||||
//New unit of allies
|
||||
std::set<std::string> ally_new_unit;
|
||||
|
||||
//New unit of enemies
|
||||
std::set<std::string> enemy_new_unit;
|
||||
};
|
||||
|
||||
class recruitment : public candidate_action {
|
||||
public:
|
||||
|
||||
recruitment( rca_context &context , const config &cfg );
|
||||
|
||||
virtual ~recruitment();
|
||||
|
||||
virtual double evaluate();
|
||||
|
||||
virtual void execute();
|
||||
|
||||
void do_describe(struct situation);
|
||||
|
||||
private:
|
||||
int depth_;
|
||||
|
||||
std::vector<team> ally_;
|
||||
std::vector<team> enemy_;
|
||||
|
||||
|
||||
void do_recruit(int max_units_to_recruit, double quality_factor);
|
||||
|
||||
struct situation get_next_stage(std::string unit, situation current);
|
||||
|
||||
double analyze_situation();
|
||||
double evaluate_unit(situation current);
|
||||
situation do_min_max(situation current);
|
||||
int get_next_team(int current_side);
|
||||
team get_current_team_recruit(int side);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // of namespace testing_ai_default
|
||||
|
||||
} // of namespace ai
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#include "testing/ca_global_fallback.hpp"
|
||||
#include "testing/stage_rca.hpp"
|
||||
#include "testing/stage_fallback.hpp"
|
||||
#include "akihara/recruitment.hpp"
|
||||
|
||||
namespace ai {
|
||||
// =======================================================================
|
||||
|
@ -127,6 +128,9 @@ static register_candidate_action_factory<testing_ai_default::passive_leader_shar
|
|||
static register_candidate_action_factory<testing_ai_default::global_fallback_phase>
|
||||
global_fallback_phase_factory("testing_ai_default::global_fallback_phase");
|
||||
|
||||
static register_candidate_action_factory<akihara_recruitment::recruitment>
|
||||
recruitment_factory("akihara_recruitment::recruitment");
|
||||
|
||||
// =======================================================================
|
||||
// Goals
|
||||
// =======================================================================
|
||||
|
|
Loading…
Add table
Reference in a new issue