]> ruin.nu Git - icfp05.git/commitdiff
more sane shortest path implementation and more tuning of the robber algorithm
authorMichael Andreen <harv@ruin.nu>
Sat, 25 Jun 2005 12:21:10 +0000 (12:21 +0000)
committerMichael Andreen <harv@ruin.nu>
Sat, 25 Jun 2005 12:21:10 +0000 (12:21 +0000)
bot/bot.cpp
bot/bot.h
robber/robber.cpp
robber/robber.h
robber/robber.pro

index 1c2b4dccf9adaf079abcdb2038aecf96ebd24020..8450a6321c0c462f99d4b142be4de931a27d78e5 100644 (file)
@@ -2,21 +2,25 @@
 #include <sstream>
 #include <iterator>
 #include <queue>
+#include <vector>
 #include <utility>
 #include "bot.h"
 
 using namespace std;
 using namespace __gnu_cxx;
 
-struct VectComp{
-       bool operator()(const vector<string>& v1, const vector<string>& v2){
-               return v1.size() > v2.size();
-       }
-};
-Bot::Bot(string name, string type){
+
+Bot::Bot(const string& name, PlayerType type){
        _name = name;
        _type = type;
 
+       _playerTypeNames[robber] = "robber";
+       _playerTypeNames[cop_foot] = "cop-foot";
+       _playerTypeNames[cop_car] = "cop-car";
+
+       _playerTypes["robber"] = robber;
+       _playerTypes["cop-foot"] = cop_foot;
+       _playerTypes["cop-car"] = cop_car;
        /*
        priority_queue<vector<string>, vector<vector<string> >, VectComp> pq;
 
@@ -56,7 +60,7 @@ Bot::Bot(string name, string type){
 }
 
 void Bot::play(){
-       cout << "reg: " << _name << " " << _type << endl;
+       cout << "reg: " << _name << " " << _playerTypeNames[_type] << endl;
 
        string input;
        getline(cin, input);
@@ -68,15 +72,15 @@ void Bot::play(){
 
        //robber and 5 cops
        getline(cin, input);
-       _players[value<string>(input)].type = "robber";
+       _players[value<string>(input)];
        getline(cin, input);
-       _players[value<string>(input)].type = "cop-foot";
+       _players[value<string>(input)];
        getline(cin, input);
-       _players[value<string>(input)].type = "cop-foot";
+       _players[value<string>(input)];
        getline(cin, input);
-       _players[value<string>(input)].type = "cop-foot";
+       _players[value<string>(input)];
        getline(cin, input);
-       _players[value<string>(input)].type = "cop-foot";
+       _players[value<string>(input)];
 
        cerr << "Got players, building graph." << endl;
        getline(cin, input);
@@ -149,7 +153,7 @@ void Bot::buildGraph(){
                street >> to;
                string type;
                street >> type;
-               cerr << "Street between: " << from << " and " << to << " of type: " << type << endl;
+               //cerr << "Street between: " << from << " and " << to << " of type: " << type << endl;
                if (type == "foot"){
                        _intersections[from].connections[to] = both;
                        Intersection& inter = _intersections[to];
@@ -205,14 +209,15 @@ void Bot::updateWorld(){
                //cerr << "Player: " << input << endl;
                Player& pl = _players[input];
                player >> pl.location;
-               player >> pl.type;
+               player >> input;
+               pl.type = _playerTypes[input];
        }
        //cerr << "Number of players: " << _players.size() << endl;
 }
 
 void Bot::move(std::string location){
        cerr << "Moving to: " << location << endl;
-       cout << "mov: " << location << " " << _type << endl;
+       cout << "mov: " << location << " " << _playerTypeNames[_type] << endl;
 }
 
 template<class T>
@@ -229,43 +234,77 @@ std::string Bot::turn(){
        return _location;
 }
 
-std::vector<std::string> Bot::shortestPath(std::string from, std::string to, std::string type){
-       
-       priority_queue<vector<string>, vector<vector<string> >, VectComp > pq;
+struct SPInfo{
+       string name;
+       bool settled;
+       SPInfo* parent;
+       int cost;
+};
 
-       vector<string> v;
-       v.push_back(from);
+struct SPInfoComp{
+       bool operator()(const SPInfo* v1, const SPInfo* v2){
+               return v1->cost > v2->cost;
+       }
+};
 
-       pq.push(v);
-       hash_map<string,bool> settled;
+std::list<std::string> Bot::shortestPath(const std::string& from, const std::string& to, PlayerType type){
+       
+       priority_queue<SPInfo*, vector<SPInfo* >, SPInfoComp > pq;
+       hash_map<string,SPInfo> nodes;
+
+       SPInfo* node = &nodes[from];
+       node->name = from;
+       node->settled = false;
+       node->parent = 0;
+       node->cost = 0;
+       pq.push(node);
 
        while(!pq.empty()){
-               const vector<string> w = pq.top();
+               node = pq.top();
                pq.pop();
                //cerr << "Vector with size: " << w.size() << endl;
                //cerr << "Looking at: " << w.back() << endl;
                //copy(w.begin(), w.end(), ostream_iterator<string>(cerr, " : "));
-               if (w.back() == to)
-                       return w;
-               settled[w.back()] = true;
-               Intersection& inter = _intersections[w.back()];
+               if (node->name == to){
+                       list<string> l;
+                       front_insert_iterator<list<string> > ii(l);
+                       do{
+                               *ii++ = node->name;
+                               node = node->parent;
+                       }while (node != 0);
+                       return l;
+               }
+               node->settled = true;
+
+               Intersection& inter = _intersections[node->name];
                for (hash_map<string,StreetType>::const_iterator street = inter.connections.begin();
                                street != inter.connections.end(); ++street){
-                       if (settled.find(street->first) != settled.end())
-                               continue;
-                       //cerr << "Adding: " << street->first << endl;
-                       bool hascar = type == "cop-car";
+                       hash_map<string,SPInfo>::iterator newNode = nodes.find(street->first);
+                       bool hascar = type == cop_car;
                        if ( (hascar &&  (street->second == car || street->second == both)) ||
                                        (!hascar && (street->second == foot || street->second == both))){
-                               
-                               v = w;
-                               v.push_back(street->first);
-                               pq.push(v);
+                               SPInfo* n = 0;
+                               if (newNode == nodes.end()){
+                                       n = &nodes[street->first];
+                                       n->name = street->first;
+                                       n->settled = false;
+                                       n->parent = 0;
+                                       n->cost = 10000;
+                               }else if (newNode->second.settled)
+                                       continue;
+                               else
+                                       n = &newNode->second;
+
+                               if (n->cost > node->cost + 1){
+                                       n->cost = node->cost + 1;
+                                       n->parent = node;
+                                       pq.push(n);
+                               }
                        }
 
                }
                
        }
        
-       return vector<string>();
+       return list<string>();
 }
index 483cfd5f6418e4850e91312319cd2d034c05e816..7d278319332a6c9e2c416d9fa3d3f6aef5f34a41 100644 (file)
--- a/bot/bot.h
+++ b/bot/bot.h
@@ -2,9 +2,10 @@
 #define __BOT_H__
 
 #include <ext/hash_map>
-#include <vector>
+#include <list>
 #include <string>
 #include <locale>
+#include <map>
 // These are needed to be able to use std::string as key in a hash_map.
 namespace __gnu_cxx {
        template< typename CharT, typename Traits, typename Alloc >
@@ -33,6 +34,8 @@ namespace __gnu_cxx {
 };
 
 enum StreetType{foot, car, both};
+enum PlayerType{robber, cop_foot, cop_car};
+enum IntersectionType{hq, bank, robber_start, ordinary};
 
 struct Intersection{
        __gnu_cxx::hash_map<std::string,StreetType> connections;
@@ -42,7 +45,7 @@ struct Intersection{
 };
 
 struct Player{
-       std::string type;
+       PlayerType type;
        std::string location;
 };
 
@@ -56,7 +59,7 @@ T value(std::string input);
 
 class Bot {
        public:
-               Bot(std::string name, std::string type);
+               Bot(const std::string& name, PlayerType type);
                virtual ~Bot();
 
                virtual void play();
@@ -66,13 +69,15 @@ class Bot {
                void updateWorld();
                virtual std::string turn();
                void move(std::string location);
-               std::vector<std::string> shortestPath(std::string from, std::string to, std::string type);
+               std::list<std::string> shortestPath(const std::string& from, const std::string& to, PlayerType type);
 
        __gnu_cxx::hash_map<std::string, Intersection> _intersections;
        __gnu_cxx::hash_map<std::string, Player> _players;
        __gnu_cxx::hash_map<std::string, int> _banks;
+       std::map<PlayerType, std::string> _playerTypeNames;
+       std::map<std::string, PlayerType> _playerTypes;
        std::string _name;
-       std::string _type;
+       PlayerType _type;
        std::string _location;
        int _world;
        int _robbed;
index efe40ded9ece7b52f43049d1529699e1c9c999d6..4e2ec89521436121c22d5f62cc8f4bc2233a94cc 100644 (file)
@@ -11,7 +11,7 @@ string Robber::turn(){
        Intersection& inter = _intersections[_location];
        for (hash_map<string,StreetType>::const_iterator street = inter.connections.begin();
                street != inter.connections.end(); ++street){
-               double goodness = 100;
+               double goodness = 10;
                int curx = _intersections[_location].x;
                int cury = _intersections[_location].y;
 
@@ -27,36 +27,40 @@ string Robber::turn(){
 
                        double dist1 = sqrt(pow((curx-px),2.0)+pow((cury-py),2.0));
                        double dist2 = sqrt(pow((newx-px),2.0)+pow((newy-py),2.0));
-                       cerr << "Original distance: " << dist1 << endl;
+                       /*cerr << "Original distance: " << dist1 << endl;
                        cerr << "New distance: " << dist2 << endl;
+                       */
 
 
-                       if (dist2 > dist1)
-                               goodness *= 4;
-                       else
-                               goodness /= 4;
+                       if (dist2 < 50 && dist2 < dist1)
+                               goodness *= 0.95;
 
-                       if (player->second.type == "cop-foot" && dist2 <= 3)
-                               goodness /= 10;
-                       else if (player->second.type == "cop-car" && dist2 <= 2)
-                               goodness /= 10;
+                       if (player->second.type == cop_foot && dist2 <= 3)
+                               goodness /= 100;
+                       else if (player->second.type == cop_car && dist2 <= 2)
+                               goodness /= 100;
 
 
                }
+               
+               cerr << "Street: " << street->first << " goodness: " << goodness << endl;
                streets[street->first] = goodness;
        }
+       streets[_oldLocation] /= 10;
 
        for(hash_map<string,int>::const_iterator bank = _banks.begin();
                        bank != _banks.end(); ++bank){
                //cerr << "Handling bank at: " << bank->first << endl;
                if (bank->second > 0){
-                       vector<string> v = shortestPath(_location, bank->first,_type);
-                       if (v.size() < 2)
+                       list<string> l = shortestPath(_location, bank->first,_type);
+                       if (l.size() < 1)
                                continue;
-                       streets[v[1]] *= bank->second/v.size();
-                       
+                       list<string>::iterator i = l.begin();
+                       streets[*++i] += bank->second/(pow(5.0,double(l.size())));
+
                }
        }
+
        /*cerr << "Using route: ";
        copy(v.begin(), v.end(), ostream_iterator<string>(cerr, " : "));
        cerr << endl;
@@ -73,6 +77,7 @@ string Robber::turn(){
                        destination = dest->first;
                }
        }
+       _oldLocation = _location;
                
        return destination;
        
index 11f5668d0b5c61db93fc7c1cb205c7600069a5fd..5dea90a2e251608abf0107ea41ae6bf3ff84ace1 100644 (file)
@@ -5,8 +5,12 @@
 
 class Robber : public Bot {
        public:
-               Robber(std::string name):Bot(name,"robber"){};
+               Robber(std::string name):Bot(name,robber){};
                
                std::string turn();
+
+       protected:
+               std::string _oldLocation;
+               std::string _maybeNextLocation;
 };
 #endif
index 027b399991f9c16e57f05fa94e97268512efb18a..b3f79ad7a02073fd3b1c06604dc6150f15f47a7a 100644 (file)
@@ -5,6 +5,7 @@
 TEMPLATE = app
 INCLUDEPATH += ../bot
 CONFIG -= qt
+CONFIG += debug
 unix:LIBS += -lm