From: Michael Andreen Date: Sat, 25 Jun 2005 12:21:10 +0000 (+0000) Subject: more sane shortest path implementation and more tuning of the robber algorithm X-Git-Url: https://ruin.nu/git/?p=icfp05.git;a=commitdiff_plain;h=f42b544842d9b9f21da3898225a70dec23c57a36 more sane shortest path implementation and more tuning of the robber algorithm --- diff --git a/bot/bot.cpp b/bot/bot.cpp index 1c2b4dc..8450a63 100644 --- a/bot/bot.cpp +++ b/bot/bot.cpp @@ -2,21 +2,25 @@ #include #include #include +#include #include #include "bot.h" using namespace std; using namespace __gnu_cxx; -struct VectComp{ - bool operator()(const vector& v1, const vector& 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 >, 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(input)].type = "robber"; + _players[value(input)]; getline(cin, input); - _players[value(input)].type = "cop-foot"; + _players[value(input)]; getline(cin, input); - _players[value(input)].type = "cop-foot"; + _players[value(input)]; getline(cin, input); - _players[value(input)].type = "cop-foot"; + _players[value(input)]; getline(cin, input); - _players[value(input)].type = "cop-foot"; + _players[value(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 @@ -229,43 +234,77 @@ std::string Bot::turn(){ return _location; } -std::vector Bot::shortestPath(std::string from, std::string to, std::string type){ - - priority_queue, vector >, VectComp > pq; +struct SPInfo{ + string name; + bool settled; + SPInfo* parent; + int cost; +}; - vector 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 settled; +std::list Bot::shortestPath(const std::string& from, const std::string& to, PlayerType type){ + + priority_queue, SPInfoComp > pq; + hash_map 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 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(cerr, " : ")); - if (w.back() == to) - return w; - settled[w.back()] = true; - Intersection& inter = _intersections[w.back()]; + if (node->name == to){ + list l; + front_insert_iterator > 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::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::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(); + return list(); } diff --git a/bot/bot.h b/bot/bot.h index 483cfd5..7d27831 100644 --- a/bot/bot.h +++ b/bot/bot.h @@ -2,9 +2,10 @@ #define __BOT_H__ #include -#include +#include #include #include +#include // 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 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 shortestPath(std::string from, std::string to, std::string type); + std::list shortestPath(const std::string& from, const std::string& to, PlayerType type); __gnu_cxx::hash_map _intersections; __gnu_cxx::hash_map _players; __gnu_cxx::hash_map _banks; + std::map _playerTypeNames; + std::map _playerTypes; std::string _name; - std::string _type; + PlayerType _type; std::string _location; int _world; int _robbed; diff --git a/robber/robber.cpp b/robber/robber.cpp index efe40de..4e2ec89 100644 --- a/robber/robber.cpp +++ b/robber/robber.cpp @@ -11,7 +11,7 @@ string Robber::turn(){ Intersection& inter = _intersections[_location]; for (hash_map::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::const_iterator bank = _banks.begin(); bank != _banks.end(); ++bank){ //cerr << "Handling bank at: " << bank->first << endl; if (bank->second > 0){ - vector v = shortestPath(_location, bank->first,_type); - if (v.size() < 2) + list l = shortestPath(_location, bank->first,_type); + if (l.size() < 1) continue; - streets[v[1]] *= bank->second/v.size(); - + list::iterator i = l.begin(); + streets[*++i] += bank->second/(pow(5.0,double(l.size()))); + } } + /*cerr << "Using route: "; copy(v.begin(), v.end(), ostream_iterator(cerr, " : ")); cerr << endl; @@ -73,6 +77,7 @@ string Robber::turn(){ destination = dest->first; } } + _oldLocation = _location; return destination; diff --git a/robber/robber.h b/robber/robber.h index 11f5668..5dea90a 100644 --- a/robber/robber.h +++ b/robber/robber.h @@ -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 diff --git a/robber/robber.pro b/robber/robber.pro index 027b399..b3f79ad 100644 --- a/robber/robber.pro +++ b/robber/robber.pro @@ -5,6 +5,7 @@ TEMPLATE = app INCLUDEPATH += ../bot CONFIG -= qt +CONFIG += debug unix:LIBS += -lm