Author: dhains
Date: Wed Jul 30 09:10:29 2008
New Revision: 28263

URL: http://svn.gna.org/viewcvs/wesnoth?rev=28263&view=rev
Log:
Formula AI can now make moves based on eval/move list. 
Changes to class formula_ai:
*Added build_move_list function to formula_ai to create eval/move list with 
eval scores.
*Added make_candidate_move function to take best move found.
Various changes made to the candidate_move class to allow this functionality.

Modified:
    trunk/data/scenario-formula.cfg
    trunk/src/formula_ai.cpp
    trunk/src/formula_ai.hpp

Modified: trunk/data/scenario-formula.cfg
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/data/scenario-formula.cfg?rev=28263&r1=28262&r2=28263&view=diff
==============================================================================
--- trunk/data/scenario-formula.cfg (original)
+++ trunk/data/scenario-formula.cfg Wed Jul 30 09:10:29 2008
@@ -80,29 +80,39 @@
             x,y=6,20
             type="Ghost"
             generate_description=yes
-            
formula="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
-                     where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
-                           shroud   = find_shroud()"
+          #  
formula="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
+          #           where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
+          #                 shroud   = find_shroud()"
         [/unit]
                [unit]
             x,y=15,22
             type="Ghost"
             generate_description=yes
-            
formula="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
-                     where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
-                           shroud   = find_shroud()"
+           # 
formula="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
+         #            where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
+         #                  shroud   = find_shroud()"
         [/unit]
                [unit]
             x,y=12,19
             type="Ghost"
             generate_description=yes
-            
formula="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
-                     where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
-                           shroud   = find_shroud()"
+         #   
formula="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
+         #            where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
+         #                  shroud   = find_shroud()"
         [/unit]
 
         ai_algorithm=formula_ai
         [ai]
+                       eval_list=yes
+                       [register_candidate_move]
+                name=test
+                type=test
+                               
action="if(size(filter(unit_moves(me.loc),units_can_reach(enemy_moves, self))) 
!= 0, fallback('default'), if(size(villages) != 0, move(me.loc, 
nearest_loc(nearest_loc(me.loc,villages),unit_moves(me.loc))), if(size(shroud) 
= 0, fallback('default'), move(me.loc, 
nearest_loc(nearest_loc(me.loc,shroud),unit_moves(me.loc))))))
+                     where villages = 
filter(unit_moves(me.loc),is_unowned_village(map,x,y)), 
+                           shroud   = find_shroud()"
+                evaluation="if(me.id='Ghost', 100, -5)"
+            [/register_candidate_move]
+
             [team_formula]
                 rulebase="{opening.fai}"
             [/team_formula]

Modified: trunk/src/formula_ai.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula_ai.cpp?rev=28263&r1=28262&r2=28263&view=diff
==============================================================================
--- trunk/src/formula_ai.cpp (original)
+++ trunk/src/formula_ai.cpp Wed Jul 30 09:10:29 2008
@@ -1121,7 +1121,7 @@
                const_formula_ptr formula, const_formula_ptr eval, 
                const_formula_ptr precondition, const std::vector<std::string>& 
args)
 {
-       candidate_move_ptr new_move(new candidate_move(name,eval));
+       candidate_move_ptr new_move(new candidate_move(name,eval,formula));
        candidate_moves.push_back(new_move);
        function_symbol_table::add_formula_function(name, formula, 
                        precondition, args);
@@ -1145,11 +1145,18 @@
        attacks_cache_(),
        keeps_cache_(),
        vars_(),
-       function_table(*this)
+       function_table(*this),
+       candidate_moves_(),
+       use_eval_lists_(false)
 {
        //make sure we don't run out of refcount
        vars_.add_ref();
        const config& ai_param = current_team().ai_parameters();
+
+       // Check to see if we want to use eval_lists
+       if(ai_param.get_attribute("eval_list") == "yes") {
+               use_eval_lists_ = true;
+       }
 
        // Register candidate moves in function symbol table
        config::const_child_itors rc_moves = 
@@ -1214,9 +1221,57 @@
                }
        }
 
-       game_logic::map_formula_callable callable(this);
-       callable.add_ref();
-       while(make_move(move_formula_,callable)) {
+       if(use_eval_lists_) {
+               make_candidate_moves();
+       } else {
+               game_logic::map_formula_callable callable(this);
+               callable.add_ref();
+               while(make_move(move_formula_,callable)) {
+               }
+       }
+}
+
+void formula_ai::make_candidate_moves() {
+
+       build_move_list();
+       candidate_move_set::iterator best_move = candidate_moves_.begin();
+
+       while( best_move != candidate_moves_.end() ) {
+               int best_score = (*best_move)->get_score();
+               std::cout << "size of set is " << candidate_moves_.size() << 
std::endl;
+               std::cout << "best score is " << best_score << std::endl;
+               // If no evals > 0, fallback
+               if(best_score < 0) {
+                       ai_interface* fallback = create_ai("", get_info());
+                       fallback->play_turn();
+                       return;
+               }
+               // Otherwise, make the best scoring move
+               game_logic::map_formula_callable callable(this);
+               callable.add_ref();
+               variant action_unit_callable(new 
unit_callable(*(*best_move)->get_action_unit()));
+               callable.add("me", action_unit_callable);
+               const_formula_ptr move_formula((*best_move)->get_move());
+               make_move(move_formula, callable);
+               // And re-evaluate candidate moves
+               build_move_list();
+               best_move = candidate_moves_.begin();
+       }
+
+       // After all candidate moves have been exhausted, fallback
+       ai_interface* fallback = create_ai("", get_info());
+       fallback->play_turn();
+
+}
+
+
+void formula_ai::build_move_list() {
+       std::cout << "BUILDING MOVE LIST" << std::endl;
+       candidate_moves_.clear();
+       std::vector<candidate_move_ptr>::iterator itor = 
function_table.candidate_move_begin();
+       for( ; itor != function_table.candidate_move_end(); ++itor) {
+               (*itor)->evaluate_move(this, units_, get_info().team_num);
+               candidate_moves_.insert(*itor);
        }
 }
 
@@ -1277,6 +1332,7 @@
 
 bool formula_ai::make_move(game_logic::const_formula_ptr formula_, const 
game_logic::formula_callable& variables)
 {
+       std::cout << "Makin move yo" << std::endl;
        if(!formula_) {
                ai_interface* fallback = create_ai("", get_info());
                fallback->play_turn();

Modified: trunk/src/formula_ai.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula_ai.hpp?rev=28263&r1=28262&r2=28263&view=diff
==============================================================================
--- trunk/src/formula_ai.hpp (original)
+++ trunk/src/formula_ai.hpp Wed Jul 30 09:10:29 2008
@@ -30,50 +30,56 @@
 
 class candidate_move {
 public:
-       candidate_move(std::string name, const_formula_ptr eval) :
+       candidate_move(std::string name, const_formula_ptr eval, 
const_formula_ptr move) :
                name_(name),
                eval_(eval),
+               move_(move),
                score_(-1),
                action_unit_()
        {};
 
        void evaluate_move(const formula_callable* ai, unit_map& units, int 
team_num) {
-
+               score_ = -1000;
                for(unit_map::unit_iterator i = units.begin() ; i != 
units.end() ; ++i)
                {
-                       if(i->second.side() == team_num) {
+                       if( (i->second.side() == team_num) && 
+                               (i->second.has_moved() == false) ) {
                                game_logic::map_formula_callable callable(ai);
                                callable.add_ref();
                                callable.add("me", variant(new 
unit_callable(*i)));
                                int res = (formula::evaluate(eval_, 
callable)).as_int();
                                if(res > score_) {
                                        score_ = res;
-                                       action_unit_.reset(&i->second);
+                                       action_unit_ = i;
                                }
                        }
                }
-
        }
 
        int get_score() const {return score_;}
+       unit_map::unit_iterator get_action_unit() {return action_unit_;}
+       const_formula_ptr get_move() {return move_;}
 
        struct move_compare {
-               bool operator() (const candidate_move& lmove,
-                               const candidate_move& rmove) const 
+               bool operator() (const boost::shared_ptr<candidate_move> lmove,
+                               const boost::shared_ptr<candidate_move> rmove) 
const 
                {
-                       return lmove.get_score() < rmove.get_score();
+                       return lmove->get_score() < rmove->get_score();
                }
        };
 
 private:
+
        std::string name_;
        const_formula_ptr eval_;
+       const_formula_ptr move_;
        int score_;
-       boost::shared_ptr<unit> action_unit_;
+       unit_map::unit_iterator action_unit_;
 };
 
 
 typedef boost::shared_ptr<candidate_move> candidate_move_ptr;  
+typedef std::set<game_logic::candidate_move_ptr, 
game_logic::candidate_move::move_compare> candidate_move_set;
 
 class ai_function_symbol_table : public function_symbol_table {
 
@@ -88,8 +94,12 @@
                        const_formula_ptr formula, const_formula_ptr eval, 
                        const_formula_ptr precondition, const 
std::vector<std::string>& args);
 
-       std::vector<candidate_move_ptr>::iterator get_candidate_move_itor() {
+       std::vector<candidate_move_ptr>::iterator candidate_move_begin() {
                return candidate_moves.begin(); 
+       }       
+
+       std::vector<candidate_move_ptr>::iterator candidate_move_end() {
+               return candidate_moves.end(); 
        }       
 
 private:
@@ -156,6 +166,8 @@
        mutable std::map<location,paths> possible_moves_;
 
        void prepare_move() const;
+       void build_move_list();
+       void make_candidate_moves();
        mutable bool move_maps_valid_;
        mutable move_map srcdst_, dstsrc_, full_srcdst_, full_dstsrc_, 
enemy_srcdst_, enemy_dstsrc_;
        mutable variant attacks_cache_;
@@ -164,7 +176,8 @@
        game_logic::map_formula_callable vars_;
        game_logic::ai_function_symbol_table function_table;
 
-       std::set<game_logic::candidate_move, 
game_logic::candidate_move::move_compare> candidate_moves;
+       game_logic::candidate_move_set candidate_moves_;
+       bool use_eval_lists_;
 };
 
 #endif


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to