ai_dfool.cpp

Go to the documentation of this file.
00001 /* $Id: ai_dfool.cpp 25333 2008-03-30 13:49:03Z jhinrichs $ */
00002 /*
00003    Copyright (C) 2007 - 2008
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 version
00008    or at your option any later version2
00009    or 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 //! @file ai_dfool.cpp
00017 //!
00018 
00019 #include "global.hpp"
00020 
00021 #include "ai_dfool.hpp"
00022 #include "log.hpp"
00023 #include "variable.hpp"
00024 
00025 #include <set>
00026 
00027 namespace dfool {
00028   void dfool_ai::play_turn(){
00029     info info_ = get_info();
00030     int team_num=get_info().team_num;
00031     const config& parms = current_team().ai_parameters();
00032     config ai_mem = current_team().ai_memory();
00033 
00034     const config::child_list& orders = parms.get_children("order");
00035     LOG_STREAM(info, ai)<<"dfool side:"<<team_num<<" of "<<current_team().nteams()<<std::endl;
00036 
00037     config side_filter;
00038     char buf[80];
00039     snprintf(buf, sizeof(buf), "%d", team_num);
00040     side_filter["side"]=buf;
00041 
00042     LOG_STREAM(info, ai)<<"dfool sees:"<<std::endl;
00043 
00044     //    for(unit_map::iterator ua = get_info().units.begin(); ua != get_info().units.end(); ++ua) {
00045     //        std::string t = ua->second.get_ai_special();
00046     //        LOG_STREAM(info, ai)<<"ua:"<<ua->second.underlying_id()<<"\t"<<t<<std::endl;
00047     //        LOG_STREAM(info, ai)<<"\t\t\t"<<ua->first.x<<","<<ua->first.y<<std::endl;
00048     //    }
00049 
00050     unit_list all = all_units();
00051     unit_list my_units=filter_units(side_filter, all,get_info().units);
00052     unit_list v_units=visible_units();
00053 
00054     //    LOG_STREAM(info, ai)<<"My Units"<<std::endl;
00055     //    for(unit_list::iterator ui = all.begin(); ui != all.end(); ++ui) {
00056     //      LOG_STREAM(info, ai)<<"\t....."<<*ui<<"........"<<std::endl;
00057     //      unit_map::iterator u = unit(*ui,get_info().units);
00058     //      if(u!=get_info().units.end()){
00059     //  LOG_STREAM(info, ai)<<"\t"<<u->second.name()<<std::endl;
00060     //  LOG_STREAM(info, ai)<<"\t\t"<<u->second.underlying_id()<<std::endl;
00061     //  LOG_STREAM(info, ai)<<"\t\t\t"<<u->second.get_ai_special()<<std::endl;
00062     //  LOG_STREAM(info, ai)<<"\t\t\t"<<u->first.x<<","<<u->first.y<<std::endl;
00063     //      }
00064     //    }
00065 
00066     LOG_STREAM(info, ai)<<"Visible Units"<<std::endl;
00067     for(unit_list::iterator ui = v_units.begin(); ui != v_units.end(); ++ui) {
00068       unit_map::iterator u = unit(*ui,get_info().units);
00069       if(u!=get_info().units.end()){
00070     //  LOG_STREAM(info, ai)<<"\t"<<u->second.name()<<std::endl;
00071     LOG_STREAM(info, ai)<<"\t\t"<<u->second.underlying_id()<<std::endl;
00072     //  LOG_STREAM(info, ai)<<"\t\t\t"<<u->second.get_ai_special()<<std::endl;
00073     //  LOG_STREAM(info, ai)<<"\t\t\t"<<u->first.x<<","<<u->first.y<<std::endl;
00074 
00075     unit_memory_.add_unit_sighting(u->second, u->first, get_info().state.turn());
00076       }
00077     }
00078 
00079     for(config::child_list::const_iterator o = orders.begin(); o != orders.end(); ++o) {
00080       std::string order_id=(**o)["id"];
00081       std::string number=(**o)["number"];
00082       size_t num=atoi(number.c_str());
00083       const config::child_list& filter = (**o).get_children("filter");
00084 
00085       LOG_STREAM(info, ai)<<"dfool order:"<<order_id<<std::endl;
00086 
00087       // First find units where AI_SPECIAL matches order id
00088       config order_filter;
00089       order_filter["ai_special"]=order_id;
00090       unit_list order_units = filter_units(order_filter,my_units,get_info().units);
00091       if(num > order_units.size()){
00092     // Need to populate orders
00093     // Find units that match any filter.
00094     // If no filters, then accept all units.
00095     if(filter.size()){
00096       for(config::child_list::const_iterator f = filter.begin(); f != filter.end(); ++f) {
00097         config ff=**f;
00098         //            LOG_STREAM(info, ai)<<"dfool filter:"<<std::endl;
00099             unit_list filtered_units=filter_units(ff,my_units,get_info().units);
00100 
00101         //! @todo FIXME: add sorting
00102 
00103             for(unit_list::iterator i = filtered_units.begin(); i != filtered_units.end() && (num > order_units.size()); ++i) {
00104           unit_map::iterator ui=unit(*i,get_info().units);
00105           if(ui!=get_info().units.end()){
00106         std::string ais=ui->second.get_ai_special();
00107 
00108         //      LOG_STREAM(info, ai)<<"\t match: "<<ui->second.underlying_id()<<"\t"<<ais<<":::"<<std::endl;
00109 
00110         bool used=(ais.size() > 0);
00111         if(used){
00112           //          LOG_STREAM(info, ai)<<"\t\talready assigned: "<<ui->second.underlying_id()<<"\t"<<ais<<std::endl;
00113         }else{
00114           ui->second.assign_ai_special(order_id);
00115           order_units.push_back(*i);
00116 
00117           //          LOG_STREAM(info, ai)<<"\t\tmatching: "<<ui->second.underlying_id()<<" to order: "<<order_id<<"\t"<<ui->second.get_ai_special()<<std::endl;
00118         }
00119           }
00120             }
00121           }
00122         }else{
00123           order_units=my_units;
00124         }
00125       }
00126 
00127       // Execute commands
00128       for(unit_list::iterator ou = order_units.begin(); ou != order_units.end(); ou++){
00129         const config::child_list& commands = (**o).get_children("command");
00130     bool com_break=false;
00131 
00132         for(config::child_list::const_iterator com = commands.begin(); com != commands.end() && !com_break; ++com) {
00133       unit_map::iterator u=unit(*ou,get_info().units);
00134 
00135       const config::child_list& com_filter = (**com).get_children("filter");
00136       bool found=true;
00137       if(u!=get_info().units.end()){
00138         for(config::child_list::const_iterator sf = com_filter.begin(); sf != com_filter.end(); ++sf) {
00139           config ff=**sf;
00140           LOG_STREAM(info, ai)<<"ff:"<<(**com)["type"]<<" "<<ff["type"]<<" "<<ff["x"]<<","<<ff["y"]<<std::endl;
00141           LOG_STREAM(info, ai)<<"ff?"<<u->second.type_id()<<" "<<u->first.x<<","<<u->first.y<<std::endl;
00142           if(! u->second.matches_filter(&ff,u->first)) {
00143         found=false;
00144         break;
00145           }
00146         }
00147       }
00148 
00149       if(found){
00150         std::string type=(**com)["type"];
00151         std::string e=(**com)["test"];
00152         std::map<std::string, evaluator*> function_map;
00153         arithmetic_evaluator eval(get_info().state.sog(),&function_map);
00154         distance_evaluator dist(get_info().state.sog(),&function_map);
00155         function_map["eval"]=&eval;
00156         function_map["distance"]=&dist;
00157         std::cout<<"eval: "<<type<<":"<<e<<" = "<<eval.value(e)<<"\n";
00158 
00159         LOG_STREAM(info, ai)<<"\tcommand: "<<type<<std::endl;
00160         if(type=="moveto"){
00161           moveto(com,u);
00162         }
00163         if(type=="set_order"){
00164           std::string set_id=(**com)["id"];
00165           std::string a=(u->second.get_ai_special());
00166           LOG_STREAM(info, ai)<<"\t\t"<<u->second.underlying_id()<<"\t"<<a<<"->"<<set_id<<std::endl;
00167           (u->second.assign_ai_special(set_id));
00168           a=(u->second.get_ai_special());
00169           LOG_STREAM(info, ai)<<"\t\t"<<u->second.underlying_id()<<"\t"<<a<<" =?= "<<set_id<<std::endl;
00170         }
00171         if(type=="break"){
00172           com_break=true;
00173         }
00174           }
00175         }
00176       }
00177     }
00178 
00179     unit_memory_.write(ai_mem);
00180     current_team().set_ai_memory(ai_mem);
00181 
00182     return;
00183   }
00184 
00185   unit_list dfool_ai::filter_units(const config& filter, unit_list& ul, unit_map& um)
00186   {
00187     //    LOG_STREAM(info, ai)<<"filter1:"<<std::endl;
00188     unit_list filtered_units_;
00189     for(unit_list::const_iterator i = ul.begin(); i != ul.end(); ++i) {
00190       //      LOG_STREAM(info, ai)<<"filter2:"<<std::endl;
00191       unit_map::iterator j = unit(*i,um);
00192       //      LOG_STREAM(info, ai)<<"j:"<<j->second.underlying_id()<<":"<<j->first.x<<","<<j->first.y<<std::endl;
00193       if(j->second.underlying_id().size()>0){
00194     //  LOG_STREAM(info, ai)<<"filter3:"<<std::endl;
00195     if(j->second.matches_filter(&filter,j->first)) {
00196       //      LOG_STREAM(info, ai)<<"filter4:"<<std::endl;
00197       filtered_units_.push_back(*i);
00198     }
00199       }
00200     }
00201     //    LOG_STREAM(info, ai)<<"filter:"<<std::endl;
00202     return filtered_units_;
00203   }
00204 
00205   unit_list dfool_ai::visible_units()
00206   {
00207     unit_list visible_units;
00208     bool no_fog=current_team().uses_shroud() == false && current_team().uses_fog() == false;
00209 
00210     const unit_map& um=get_info().units;
00211     for(unit_map::const_iterator i = um.begin(); i != um.end(); ++i) {
00212       bool hidden_by_fog = current_team().fogged(i->first);
00213       bool hidden = i->second.invisible(i->first, um, get_info().teams);
00214       if((no_fog || !hidden_by_fog) && !hidden) {
00215       visible_units.push_back(i->second.underlying_id());
00216       }
00217     }
00218 
00219     LOG_STREAM(info, ai) << "number of visible units: " << visible_units.size() << "\n";
00220     return visible_units;
00221   }
00222 
00223   unit_list dfool_ai::all_units(){
00224     unit_list all;
00225     const unit_map& um=get_info().units;
00226     for(unit_map::const_iterator i = um.begin(); i != um.end(); ++i) {
00227       //      LOG_STREAM(info, ai)<<"all:"<<i->second.underlying_id()<<std::endl;
00228       all.push_back(i->second.underlying_id());
00229     }
00230     return(all);
00231   }
00232 
00233   bool dfool_ai::moveto(config::child_list::const_iterator o, unit_map::const_iterator m){
00234       location target(atoi((**o)["target_x"].c_str())-1,atoi((**o)["target_y"].c_str())-1);
00235       LOG_STREAM(info, ai)<<"\tmoving to:("<<target.x<<","<<target.y<<")"<<std::endl;
00236       if(m->second.movement_left()){
00237     std::map<location,paths> possible_moves;
00238     move_map srcdst, dstsrc;
00239     unit_map known_units;
00240 
00241     //  unit_memory_.known_map(known_units, get_info().state.turn());
00242     unit_memory_.known_map(known_units, 0);
00243 
00244     std::cout<<"known units:\n";
00245     for(unit_map::const_iterator uu = known_units.begin();uu!=known_units.end();uu++){
00246       std::cout<<"\t"<<uu->second.underlying_id()<<" "<<uu->first<<"\n";
00247     }
00248 
00249     calculate_moves(known_units,possible_moves,srcdst,dstsrc,false,false,NULL,true);
00250 
00251     int closest_distance = -1;
00252     std::pair<location,location> closest_move;
00253 
00254     //! @todo This undoubtedly could be done more cleanly
00255     for(move_map::const_iterator i = dstsrc.begin(); i != dstsrc.end(); ++i) {
00256       // Must restrict move_map to only unit that is moving.
00257       if(i->second==m->first){
00258         const int distance = distance_between(target,i->first);
00259         //      int distance=10000;
00260         //      std::cout<<"got here\n";
00261         //      const shortest_path_calculator calc(m->second, current_team(),known_units,get_info().teams,get_info().map);
00262         //std::cout<<"got here2\n";
00263         //paths::route route = a_star_search(m->first, target, 1000.0, &calc,
00264         //get_info().map.x(), get_info().map.y());
00265         //      std::cout<<"got here3\n";
00266 
00267         //      distance = route_turns_to_complete(m->second, get_info().map, route, known_units, get_info().teams) + distance_between(target,i->first)/100;
00268 
00269         if(closest_distance == -1 || distance < closest_distance) {
00270               closest_distance = distance;
00271               closest_move = *i;
00272         }
00273       }
00274     }
00275 
00276     LOG_STREAM(info, ai)<<"\tmoving : "<< m->second.underlying_id() <<" "<<" from ("<<closest_move.first.x<<","<<closest_move.first.y<<")"<<" to ("<<target.x<<","<<target.y<<")"<<std::endl;
00277     LOG_STREAM(info, ai)<<"\tdistance: "<<closest_distance<<"\n";
00278 
00279     if(closest_distance != -1) {
00280       gamemap::location to = move_unit_partial(closest_move.second,closest_move.first,possible_moves);
00281       if(to != closest_move.second)
00282         return(false);  // Something unexpected happened
00283     }
00284       }
00285       return(true);
00286   }
00287 
00288   unit_map::iterator dfool_ai::unit(std::string unit_id, unit_map& um){
00289     //    LOG_STREAM(info, ai)<<"unit start:"<<unit_id<<std::endl;
00290     for(unit_map::iterator u = um.begin(); u != um.end(); u++){
00291       if(unit_id == u->second.underlying_id()){
00292     //  LOG_STREAM(info, ai)<<"unit:"<<unit_id<<" , "<< u->second.underlying_id()<<std::endl;
00293     return u;
00294       }
00295     }
00296     //    LOG_STREAM(info, ai)<<"nounit:"<<std::endl;
00297     return(um.end());
00298   }
00299 
00300   unit_memory::unit_memory(const config& cfg) :
00301     units_(),
00302     ids_(),
00303     turns_(),
00304     locations_()
00305   {
00306     const config::child_list mem_list=cfg.get_children("unit_memory");
00307     for(config::child_list::const_iterator mem = mem_list.begin(); mem != mem_list.end(); ++mem) {
00308       config unit_cfg = *((*mem)->child("unit"));
00309 
00310       unit u(unit_cfg);
00311 
00312       int t = atoi((**mem)["turn"].c_str());
00313 
00314       gamemap::location l(atoi((**mem)["x"].c_str())-1,atoi((**mem)["y"].c_str())-1);
00315       add_unit_sighting(u,l,t);
00316     }
00317   }
00318 
00319   void unit_memory::add_unit_sighting(unit u, gamemap::location l, size_t t){
00320     std::string unit_id= u.underlying_id();
00321     // Check if this unit has already been seen
00322     size_t i,j;
00323     for(i=0; i < ids_.size();i++){
00324       if(unit_id == ids_[i]){break;}
00325     }
00326 
00327     if(i == ids_.size()){
00328       // Unit has not been seen
00329       units_.push_back(u);
00330       ids_.push_back(unit_id);
00331       turns_.push_back(t);
00332       locations_.push_back(l);
00333     }else{
00334       // Update unit info
00335       units_[i]=u;
00336       turns_[i]=t;
00337       locations_[i]=l;
00338     }
00339 
00340     // Remove units that are co-located units
00341     std::set<size_t> remove_list;
00342     for(j=0; j < ids_.size();j++){
00343       if(j!=i && locations_[j] == locations_[i]){
00344       remove_list.insert(j);
00345       }
00346     }
00347     for(std::set<size_t>::const_iterator k=remove_list.begin();k!=remove_list.end();k++){
00348       remove_unit_sighting(ids_[*k]);
00349     }
00350   }
00351 
00352   void unit_memory::remove_unit_sighting(std::string id){
00353     size_t i;
00354     for(i=0;i<ids_.size();i++){
00355       if(id == ids_[i]){break;}
00356     }
00357 
00358     if(i == ids_.size()){
00359       // Unit not in memory
00360     }else{
00361       // Remove unit info
00362       units_.erase(units_.begin()+i);
00363       ids_.erase(ids_.begin()+i);
00364       locations_.erase(locations_.begin()+i);
00365       turns_.erase(turns_.begin()+i);
00366     }
00367   }
00368 
00369   void unit_memory::write(config& temp){
00370     //    std::cout<<"ai_write:\n";
00371     for(size_t i = 0; i < units_.size(); i++){
00372       config element;
00373       write_element(i, element);
00374       temp.add_child("unit_memory",element);
00375     }
00376   }
00377 
00378   void unit_memory::write_element(int i, config &temp){
00379     config temp_unit;
00380     std::stringstream ts,xs,ys;
00381     ts << turns_[i];;
00382     temp["turn"] = ts.str();
00383     xs << locations_[i].x;
00384     temp["x"] = xs.str();
00385     ys << locations_[i].y;
00386     temp["y"] = ys.str();
00387     units_[i].write(temp_unit);
00388     temp.add_child("unit",temp_unit);
00389     //    std::cout<<"ai write: "<<temp_unit["id"]<<"\n";
00390   }
00391 
00392   void unit_memory::known_map(unit_map& u, size_t turn){
00393     size_t i;
00394     std::map<gamemap::location,size_t> turn_used;
00395     for(i=0;i<units_.size();i++){
00396       gamemap::location l = locations_[i];
00397       size_t t = turn_used[l];
00398       if(turns_[i] >= turn && turns_[i] >= t){
00399        //      std::cout<<"turn_used: "<< t <<"\n";
00400      //      std::cout<<"turn: "<< turns_[i] <<"\n";
00401       turn_used[l] = t;
00402       if(t != 0){
00403         u.replace(new std::pair<gamemap::location,unit>(l,units_[i]));
00404       }else{
00405         std::cout<<"id: "<< ids_[i] <<"\n";
00406 
00407         u.add(new std::pair<gamemap::location,unit>(l,units_[i]));
00408       }
00409       }
00410     }
00411   }
00412 
00413   std::string evaluator::value(const std::string& val_string){
00414     std::string temp_string = val_string;
00415 
00416     std::vector<std::string> p = utils::paranthetical_split(val_string,0,"(",")");
00417 
00418     // Find function calls designated by @ and evaluate values inside ()
00419     std::string func;
00420     std::stringstream tot;
00421     std::cout<<"got here eval:"<<val_string<<"\n";
00422     bool function=false;
00423     for(size_t i=0;i!=p.size();i++){
00424      std::stringstream ptemp;
00425      if(i%2){
00426        if(function){
00427         std::cout<<"function: "<<func<<"\n";
00428         std::map<std::string, evaluator*>::iterator fmi =
00429           function_map_->find(func);
00430         if(fmi != function_map_->end()){ // evaluate function
00431           std::cout<<"function ::: "<<func<<" ::: "<<fmi->first<<"\n";
00432           evaluator& f=*(fmi->second);
00433           ptemp<<f.value(p[i]);
00434           p[i]=ptemp.str();
00435         }else{ // error
00436           std::cout<<"function undefined: "<<func<<"\n";
00437           LOG_STREAM(info, ai)<<"error: evaluator function undefined: "<<func<<"\n";
00438           p[i]="ERR";
00439         }
00440        }else if(p[i].size()>0 ){
00441         p[i]="("+p[i]+")";
00442        }
00443        function=false;
00444      }else{
00445        std::string t=p[i];
00446        std::cout<<"got here: t :"<<t<<"\n";
00447        std::vector<std::string> temp=utils::split(t,'@');
00448        std::cout<<"got here: temp :"<<temp.size()<<"\n";
00449 
00450        if(std::find(t.begin(),t.end(),'@') != t.end()){
00451         function=true;
00452        }
00453 
00454        if(temp.size()>2){
00455         LOG_STREAM(info, ai)<<"evaluator syntax error:\n\t" << val_string << std::endl;
00456         std::cout<<"evaluator syntax error:\n\t" << val_string << std::endl;
00457        }
00458        std::cout<<"eval size:"<<temp.size()<<"\n";
00459 
00460        if(function && temp.size()>0){
00461         std::cout<<"temp "<<temp[0]<<"\n";
00462         if(temp.size()==2){
00463           p[i]=temp[0];
00464           func=temp[1];
00465         }else{
00466           std::cout<<"got lost::"<<temp[0]<<"\n";
00467           p[i]="";
00468           func=temp[0];
00469         }
00470        }else{
00471         p[i]=temp[0];
00472        }
00473      }
00474      tot<<p[i];
00475     }
00476     return(utils::interpolate_variables_into_string(tot.str(),state));
00477   }
00478 
00479   std::string arithmetic_evaluator::value(const std::string& val_string){
00480     std::string temp = evaluator::value(val_string); // calculate WML variables
00481     std::list<std::string> tokens = parse_tokens(temp);
00482     std::cout<<"tokens:\n";
00483     for(std::list<std::string>::const_iterator i=tokens.begin();i!=tokens.end();i++){
00484      std::cout<<"\t"<<(*i)<<"\n";
00485     }
00486     if(tokens.size()){
00487      std::cout<<"got here tokenless\n";
00488      temp=evaluate_tokens(tokens);
00489     }
00490     std::cout<<"temp:"<<temp<<"\n";
00491     return temp;
00492   }
00493 
00494   std::string arithmetic_evaluator::evaluate_tokens(std::list<std::string> &tlist){
00495     std::vector<std::string> op_priority;
00496     op_priority.push_back("^");
00497     op_priority.push_back("*/%");
00498     op_priority.push_back("+-");
00499     double temp=0;
00500     std::cout<<"got here token\n";
00501     for(size_t i=0;i<op_priority.size();i++){
00502      tlist.remove("");
00503      for(std::list<std::string>::iterator token = tlist.begin();token!=tlist.end();token++){
00504        for(size_t j=0;j<op_priority[i].size();j++){
00505         std::string t;
00506         t+=op_priority[i][j];
00507         if((*token) == t){
00508           std::list<std::string>::iterator a=token;
00509           std::list<std::string>::iterator b=token;
00510           std::cout<<"got here token1\n";
00511           a--;
00512           b++;
00513           std::cout<<"atb:"<<*token<<"\n";
00514           //          std::cout<<"atb:"<<*a<<*token<<*b<<"\n";
00515           if((*token)[0]=='*'){
00516             temp= atof((*a).c_str()) * atof((*b).c_str());
00517           }
00518           if((*token)[0]=='/'){
00519             temp= atof((*a).c_str()) / atof((*b).c_str());
00520           }
00521           if((*token)[0]=='%'){
00522             temp= std::fmod(atof((*a).c_str()), atof((*b).c_str()));
00523           }
00524           if((*token)[0]=='+'){
00525             temp= atof((*a).c_str()) + atof((*b).c_str());
00526           }
00527           if((*token)[0]=='-'){
00528             temp= atof((*a).c_str()) - atof((*b).c_str());
00529           }
00530           if((*token)[0]=='^'){
00531             temp= std::pow(atof((*a).c_str()),atof((*b).c_str()));
00532           }
00533           std::cout<<"got here token2:"<<temp<<"\n";
00534           std::stringstream r;
00535           r<<temp;
00536           *a="";
00537           *token="";
00538           *b=r.str();
00539           token++;
00540           //          tlist.erase(a);
00541           //          tlist.erase(b);
00542           break;
00543         }
00544        }
00545      }
00546     }
00547     tlist.remove("");
00548     return(*(tlist.begin()));
00549   }
00550 
00551   std::list<std::string> arithmetic_evaluator::parse_tokens(const std::string& s){
00552     std::list<std::string> ret;
00553     std::string temp;
00554     std::string str="";
00555     std::string operators = "^*/%+-";
00556     std::string digits = "0123456789";
00557     char dpoint='.';
00558     std::string parenthesis="()";
00559     int count=0;
00560     size_t i;
00561 
00562     for(i=0;i!=s.size();i++){ // strip out spaces
00563      if(s[i]!=' '){
00564        str+=s[i];
00565      }
00566     }
00567 
00568     i=0;
00569     while(i!=str.size()){
00570      std::cout<<"i:"<<i<<"\n";
00571      if(0==count){
00572        ret.push_back("");
00573      }
00574      char c=str[i];
00575      bool dpfound=false;
00576      bool found=false;
00577      for(size_t j=0;j!=digits.size();j++){
00578        if(c==digits[j]){
00579         found=true;
00580         break;
00581        }
00582      }
00583 
00584      if(!found && !dpfound && c==dpoint){ // check for decimal point
00585        dpfound=true;
00586        found=true;
00587      }
00588 
00589      if(found || (0==count && c=='-')){
00590        ret.back()+=c;
00591        count++;
00592      }else if(count){
00593        count=0;
00594        for(size_t j=0;j!=operators.size();j++){
00595         if(c==operators[j]){
00596           found=true;
00597           break;
00598         }
00599        }
00600        if(found){
00601         ret.push_back("");
00602         ret.back()+=c;
00603        }else{
00604         std::cout<<"error in arithmetic operator:"<<c<<":\n\t"<<s<<"\n";
00605         return(ret);
00606        }
00607      }else if(c==parenthesis[0]){
00608        std::vector<std::string> temp=utils::paranthetical_split(str.substr(i,str.size()-i),0);
00609        if(temp.size()%2!=0){
00610         std::cout<<"temp"<<temp[1]<<":"<<i<<"\n";
00611         ret.back()+=value(temp[1]);
00612         i+=temp[1].size()+2;
00613         std::cout<<"\t"<<ret.back()<<"\n";
00614         std::cout<<"temp 2:"<<i<<"\n";
00615         count=0;
00616         c=str[i];
00617         for(size_t j=0;j!=operators.size();j++){
00618           if(c==operators[j]){
00619             found=true;
00620             break;
00621           }
00622         }
00623         if(found){
00624           ret.push_back("");
00625           ret.back()+=c;
00626         }else if(i!=str.size()){
00627           std::cout<<"error in arithmetic operator:"<<str[i]<<":\n\t"<<s<<"\n\t"<<str.substr(0,i)<<"\n\t"<<str.substr(i,str.size()-i)<<"\n";
00628           return(ret);
00629         }
00630        }else{
00631         std::cout<<"error in parenthetical expression:\n\t"<<s<<"\n";
00632        }
00633      }else if(i!=str.size()){
00634        std::cout<<"error in arithmetic expression:\n\t"<<s<<":\n\t"<<str.substr(0,i)<<"\n\t:"<<s[i]<<":\n";
00635        std::cout<<i<<";"<<str.size()<<"\n";
00636        return(ret);
00637      }
00638      if(i!=str.size()){
00639        i++;
00640      }
00641     }
00642     std::cout<<"got here 5\n";
00643     return(ret);
00644   }
00645 
00646   std::string distance_evaluator::value(const std::string& val_string){
00647     std::cout<<"got distance:"<<val_string<<"\n";
00648     std::vector<std::string> vals = utils::split(val_string,',');
00649     if(vals.size()<4){
00650      std::cout<<"error in distance parameters\n";
00651      return("ERR");
00652     }
00653     std::vector<int> coord;
00654     for(size_t i=0;i!=4;i++){
00655      vals[i] = arithmetic_evaluator::value(vals[i]);
00656      std::cout<<"vals["<<i<<"]:"<<vals[i]<<"\n";
00657      coord.push_back(atoi(vals[i].c_str()));
00658     }
00659     std::cout<<"coords:"<<coord[0]<<","<<coord[1]<<"\n";
00660     std::cout<<"coords:"<<coord[2]<<","<<coord[3]<<"\n";
00661     gamemap::location a(coord[0]-1,coord[1]-1);
00662     gamemap::location b(coord[2]-1,coord[3]-1);
00663     std::cout<<"a "<<a.x<<","<<a.y<<"\n";
00664     std::cout<<"b "<<b.x<<","<<b.y<<"\n";
00665     int distance = distance_between(a,b);
00666     std::stringstream t;
00667     t<<distance;
00668     return(t.str());
00669   }
00670 } // end namespace dfool

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs