00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00045
00046
00047
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
00055
00056
00057
00058
00059
00060
00061
00062
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
00071 LOG_STREAM(info, ai)<<"\t\t"<<u->second.underlying_id()<<std::endl;
00072
00073
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
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
00093
00094
00095 if(filter.size()){
00096 for(config::child_list::const_iterator f = filter.begin(); f != filter.end(); ++f) {
00097 config ff=**f;
00098
00099 unit_list filtered_units=filter_units(ff,my_units,get_info().units);
00100
00101
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
00109
00110 bool used=(ais.size() > 0);
00111 if(used){
00112
00113 }else{
00114 ui->second.assign_ai_special(order_id);
00115 order_units.push_back(*i);
00116
00117
00118 }
00119 }
00120 }
00121 }
00122 }else{
00123 order_units=my_units;
00124 }
00125 }
00126
00127
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
00188 unit_list filtered_units_;
00189 for(unit_list::const_iterator i = ul.begin(); i != ul.end(); ++i) {
00190
00191 unit_map::iterator j = unit(*i,um);
00192
00193 if(j->second.underlying_id().size()>0){
00194
00195 if(j->second.matches_filter(&filter,j->first)) {
00196
00197 filtered_units_.push_back(*i);
00198 }
00199 }
00200 }
00201
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
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
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
00255 for(move_map::const_iterator i = dstsrc.begin(); i != dstsrc.end(); ++i) {
00256
00257 if(i->second==m->first){
00258 const int distance = distance_between(target,i->first);
00259
00260
00261
00262
00263
00264
00265
00266
00267
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);
00283 }
00284 }
00285 return(true);
00286 }
00287
00288 unit_map::iterator dfool_ai::unit(std::string unit_id, unit_map& um){
00289
00290 for(unit_map::iterator u = um.begin(); u != um.end(); u++){
00291 if(unit_id == u->second.underlying_id()){
00292
00293 return u;
00294 }
00295 }
00296
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
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
00329 units_.push_back(u);
00330 ids_.push_back(unit_id);
00331 turns_.push_back(t);
00332 locations_.push_back(l);
00333 }else{
00334
00335 units_[i]=u;
00336 turns_[i]=t;
00337 locations_[i]=l;
00338 }
00339
00340
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
00360 }else{
00361
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
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
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
00400
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
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()){
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{
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);
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
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
00541
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++){
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){
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 }