]> ruin.nu Git - icfp05.git/blobdiff - copsrc/cop.cpp
added license
[icfp05.git] / copsrc / cop.cpp
index f5a7f3f3e23f369c2291be78ee3042ea85a2678f..411c11122365b89e0d16a5c3fa01fcd9b765357d 100644 (file)
 #include "cop.h"
 #include <iostream>
+#include <sstream>
 #include <iterator>
+#include <queue>
 #include <cmath>
 
 using namespace std;
 using namespace __gnu_cxx;
 
-string Cop::turn(){
-       string input;
+void Cop::preGamePreparations(){
+       //cerr << "Preparing.." << endl;
+       _copTargets[_name].first = _robberLocation;
+       _copTargets[_name].second = cop_foot;
+
+       priority_queue<pair<int,string> > banks;
+       //cerr << "Number of banks: " << endl;
+       for(hash_map<string,int>::const_iterator bank = _banks.begin();
+                               bank != _banks.end(); ++bank){
+               //cerr << "Finding bank: " << bank->first << endl;
+               list<string> bankRoute  = shortestPath(_robberLocation, robber, SimpleSPGoal(bank->first));
+               //cerr << "Pushing bank" << endl;
+               banks.push(pair<int,string>(-bankRoute.size(), bank->first));
+       }
+       //cerr << "Done finding banks.." << endl;
+       priority_queue<pair<int,string> > banks2;
+       for (int i = 0; i < 4 && banks.size() > 0;++i){
+               const pair<int,string>& bank = banks.top();
+               //cerr << "Going to bank: " << bank.second << ", distance" << -bank.first << endl;
+               list<string> bankRouteFoot = shortestPath(_copHq, cop_foot, SimpleSPGoal(bank.second));
+               list<string> bankRouteCar = shortestPath(_copHq, cop_car, SimpleSPGoal(bank.second));
+               banks2.push(pair<int,string>(bankRouteCar.size() - bankRouteFoot.size(), bank.second));
+               banks.pop();
+       }
+       for (hash_map<string,Player>::const_iterator player = _players.begin();
+                       player != _players.end(); ++player){
+               //cerr << "Inital plan for player: " << player->first << endl;
+               if (player->second.type == robber){
+                       _robber = player->first;
+                       continue;
+               }else if (banks2.size() <= 0 || player->first == _name)
+                       continue;
 
-       sendInformation();
-       getInformation();
+               const pair<int,string>& bank = banks2.top();
+               _copTargets[player->first].first = bank.second;
+               //cerr << "Sending: " << player->first << " to: " << bank.second;
+               if (banks2.size() <= 2)
+                       _copTargets[player->first].second = cop_car;
+               else
+                       _copTargets[player->first].second = cop_foot;
+               //cerr << " on: " << _copTargets[player->first].second << endl;
+               _winningPlans[player->first] = 0;
+               banks2.pop();
+       }
+       _maybeRobber.push_back(hash_map<string,int>());
+}
 
-       sendPlan();
-       getPlans();
+void Cop::sendInformation(){
+       _maybeRobber.push_back(hash_map<string,int>());
+       hash_map<string,int>& maybeRobber = _maybeRobber.back();
+       int possibilities = 0;
+       if (_robberLocation.empty()){
 
-       vote();
+               hash_map<string, Intersection>::const_iterator intersection = _intersections.find(_location);
 
-       //Ignore vote
-       getline(cin,input);
+               for (hash_map<string,StreetType>::const_iterator adj = intersection->second.connections.begin();
+                               adj != intersection->second.connections.end(); ++adj){
 
-       return _location;
-}
+                       if (_smell == 1){
+                               hash_map<string,int>::iterator location = maybeRobber.find(adj->first);
+                               if (location == maybeRobber.end()){
+                                       hash_map<string, Intersection>::const_iterator intersection = _intersections.find(adj->first);
+                                       int neigh = maybeAtNeighbor(intersection->second);
+                                       if (neigh > -1){
+                                               maybeRobber[adj->first] = 100 + neigh;
+                                               ++possibilities;
+                                       }else
+                                               maybeRobber[adj->first] = -100;
+                               }
+                       }else{
+                               if (_smell == 0)
+                                       maybeRobber[adj->first] = -100;
+                               hash_map<string, Intersection>::const_iterator intersection = _intersections.find(adj->first);
+                               for (hash_map<string,StreetType>::const_iterator adj = intersection->second.connections.begin();
+                                               adj != intersection->second.connections.end(); ++adj){
+                                       hash_map<string,int>::iterator location = maybeRobber.find(adj->first);
+                                       if (location == maybeRobber.end()){
+                                               if (_smell == 0)
+                                                       maybeRobber[adj->first] = -100;
+                                               else {
+                                                       hash_map<string, Intersection>::const_iterator intersection = _intersections.find(adj->first);
+                                                       int neigh = maybeAtNeighbor(intersection->second);
+                                                       if (neigh > -1){
+                                                               maybeRobber[adj->first] = 100 + neigh;
+                                                               ++possibilities;
+                                                       }
+                                                       else
+                                                               maybeRobber[adj->first] = -100;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       } else {
+               maybeRobber[_robberLocation] = 100;
+               possibilities = 1;
+               hash_map<string, Intersection>::const_iterator intersection = _intersections.find(_location);
 
-void Cop::sendInformation(){
+               for (hash_map<string,StreetType>::const_iterator adj = intersection->second.connections.begin();
+                               adj != intersection->second.connections.end(); ++adj){
+                       maybeRobber[adj->first] = -100;
+                       for (hash_map<string,StreetType>::const_iterator adj = intersection->second.connections.begin();
+                                       adj != intersection->second.connections.end(); ++adj){
+                               hash_map<string,int>::iterator location = maybeRobber.find(adj->first);
+                               if (location != maybeRobber.end())
+                                       maybeRobber[adj->first] = -100;
+                       }
+
+               }
+
+
+       }
        cout << "inf\\" << endl;
+       for (hash_map<string,int>::iterator location = maybeRobber.begin();
+                       location != maybeRobber.end(); ++location){
+               if (location->second > 0)
+                       location->second /= possibilities;
+               cout << "inf: " << _robber << " " << location->first << " " << _playerTypeNames[robber] << " "
+                       << _world << " " << location->second << endl;
+       }
        cout << "inf/" << endl;
 }
 
 void Cop::getInformation(){
        string input;
+       if (_robberLocation.empty()){
+               hash_map<string,int>& maybeRobber = _maybeRobber.back();
+               while (true){
+                       getline(cin, input);
+                       if (input == "from/")
+                               break;
 
-       //ignore From-inform
-       do{
-               getline(cin,input);
-       }while(input != "from/");
-}
+                       getline(cin, input);
+                       getline(cin, input);
 
-void Cop::sendPlan(){
-       cout << "plan\\" << endl;
-       //cout << "plan: " << _name << endl;
-       cout << "plan/" << endl;
+                       while (true){
+                               getline(cin, input);
+                               if (input == "inf/")
+                                       break;
+                               istringstream inf(input);
+                               inf >> input;
+                               string bot;
+                               inf >> bot;
+                               string loc;
+                               inf >> loc;
+                               string type;
+                               inf >> type;
+                               if (type != _playerTypeNames[robber])
+                                       continue;
+                               int world;
+                               inf >> world;
+                               if (world != _world)
+                                       continue;
+                               int certainty;
+                               inf >> certainty;
+
+                               hash_map<string,int>::iterator location = maybeRobber.find(loc);
+                               if (location == maybeRobber.end()){
+                                       hash_map<string, Intersection>::const_iterator intersection = _intersections.find(loc);
+                                       if (intersection != _intersections.end())
+                                               continue; //The intersection doesn't exist, so ignore it.
+                                       int neigh = maybeAtNeighbor(intersection->second);
+                                       if (neigh >= 0)
+                                               maybeRobber[loc] = certainty + neigh;
+                                       else
+                                               maybeRobber[loc] = -200;
+                               }else if (location->second > 0)
+                                       location->second += certainty;
+                       }
+               }
+       }else{
+               do{
+                       getline(cin,input);
+               }while(input != "from/");
+       }
+       _maybeRobber.pop_front();
+       
 }
 
-void Cop::getPlans(){
-       string input;
+int Cop::maybeAtNeighbor(const Intersection& intersection){
+       int possibility = -1;
+       for (hash_map<string,StreetType>::const_iterator adj = intersection.connections.begin();
+                       adj != intersection.connections.end(); ++adj){
+               hash_map<string,int>::iterator oldLoc = _maybeRobber.front().find(adj->first);
+               if (oldLoc == _maybeRobber.front().end() || oldLoc->second > 0){
+                       if (possibility < 0){
+                               possibility = 0;
+                       }
+                       if (oldLoc != _maybeRobber.front().end())
+                               possibility += oldLoc->second;
+               }
+       }
+       return possibility;
+}
 
-       //ignore From-plan
-       do{
-               getline(cin,input);
-       }while(input != "from/");
+void Cop::sendPlan(){
+       //cerr << "Planning" << endl;
+       list<string> locations;
+       if (_robberLocation.empty()){
+               priority_queue<pair<int,string> > positions;
+               for (hash_map<string,int>::iterator location = _maybeRobber.front().begin();
+                               location != _maybeRobber.front().end(); ++location){
+                       if (location->second > 0)
+                               positions.push(pair<int,string>(location->second,location->first));
 
+               }
+               if (positions.size() > 0){
+                       _robberLocation = positions.top().second;
+                       //cerr << "Sending myself to: " << _robberLocation << ", probability of robber: " << positions.top().first << endl;
+               }
+               for (int i = 0; i < 2 && positions.size() > 1; ++i ){
+                       positions.pop();
+                       locations.push_back(positions.top().second);
+                       //cerr << "Sending another cop to: " << locations.back() << ", probability of robber: " << positions.top().first << endl;
+               }
+       }else{
+               locations.push_back(_robberLocation);
+               locations.push_back(_robberLocation);
+       }
+       if (!_robberLocation.empty()){
+               //cerr << "Robber found at " << _robberLocation << endl;
+               _copTargets[_name].first = _robberLocation;
+               
+               vector<string> busyCops;
+               busyCops.push_back(_name);
+               while (locations.size() > 0){
+                       string cop;
+                       int dist = 1000000;
+                       for (hash_map<string,Player>::const_iterator player = _players.begin();
+                                       player != _players.end();++player){
+                               if (player->second.type == robber || find(busyCops.begin(), busyCops.end(), player->first) != busyCops.end())
+                                       continue;
+                               list<string> l = shortestPath(player->second.location, player->second.type,SimpleSPGoal(locations.front(), dist-1));
+                               if (l.size() > 0 && l.size() < dist){
+                                       dist = l.size();
+                                       cop = player->first;
+                                       if (dist == 1)
+                                               break;
+                               }
+                       }
+                       if (!cop.empty()){
+                               //cerr << "Sending " << cop << " to " << locations.front() << endl;
+                               _copTargets[cop].first = locations.front();
+                               busyCops.push_back(cop);
+                       }
+                       locations.pop_front();
+               }
+       }
+       //cerr << "Sending plan." << endl;
+       cout << "plan\\" << endl;
+       for(hash_map<string, pair<string, PlayerType> >::iterator player = _copTargets.begin();
+                       player != _copTargets.end(); ++player){
+                       Player& pl = _players[player->first];
+               if (pl.type != player->second.second
+                               && pl.location != _copHq)
+                       player->second.second = pl.type;
+               list<string> playerRoute = shortestPath(pl.location, player->second.second, SimpleSPGoal(player->second.first));
+               if (playerRoute.size() > 1){
+                       list<string>::iterator i = playerRoute.begin();
+                       ++i;
+                       if (*i == _robberLocation || !(playerRoute.size() == 2 && _intersections[*i].type == bank)){
+                               if (player->first == _name)
+                                       _location = *i;
+                               //cerr << "Sending " << player->first << " to " << *i << " by " << player->second.second << endl;
+                               cout << "plan: " << player->first << " " << *i << " " << _playerTypeNames[player->second.second] << " " << _world+1 << endl;
+                       }
+               }
+       }
 
+       cout << "plan/" << endl;
 }
 
-void Cop::vote(){
-       cout << "vote\\" << endl;
-       cout << "vote: " << _name << endl;
-       for (hash_map<string,Player>::const_iterator player = _players.begin();
-                       player != _players.end(); ++player){
-               if (player->second.type != robber && player->first != _name){
-                       cout << "vote: " << player->first << endl;
-                       cerr << "voted for " << player->first << " of type: " << player->second.type << endl;
-               }
-       }
-       cout << "vote/" << endl;
+void Cop::move(std::string location){
+       cout << "cmov\\" << endl;
+       cout << "straight-arrow:" << endl;
+       cout << "mov\\" << endl;
+       Bot::move(location);
+       cout << "mov/" << endl;
+       cout << "acc\\" << endl;
+       cout << "acc/" << endl;
+       cout << "cmov/" << endl;
 }
 
 int main(){
-       Cop cop("cop");
+       Cop cop("harvCop");
        cop.play();
 
        return 0;
 }
+
+#include "../botsrc/shortestPath.cpp"