]> ruin.nu Git - icfp05.git/blob - botsrc/bot.cpp
fixed bug in the graph-building
[icfp05.git] / botsrc / bot.cpp
1 #include <iostream>
2 #include <sstream>
3 #include <iterator>
4 #include <queue>
5 #include <vector>
6 #include <utility>
7 #include "bot.h"
8
9 using namespace std;
10 using namespace __gnu_cxx;
11
12
13 Bot::Bot(const string& name, PlayerType type){
14         _name = name;
15         _type = type;
16
17         _playerTypeNames[robber] = "robber";
18         _playerTypeNames[cop_foot] = "cop-foot";
19         _playerTypeNames[cop_car] = "cop-car";
20
21         _playerTypes["robber"] = robber;
22         _playerTypes["cop-foot"] = cop_foot;
23         _playerTypes["cop-car"] = cop_car;
24
25 }
26
27 void Bot::play(){
28         cout << "reg: " << _name << " " << _playerTypeNames[_type] << endl;
29
30         string input;
31         getline(cin, input);
32         if (input != "wsk\\")
33                 return;
34         getline(cin, input);
35         _name = value<string>(input);
36         //cerr << "Got name: " << _name << endl;
37
38         getPlayers();
39
40         //cerr << "Got players, building graph." << endl;
41         getline(cin, input);
42         buildGraph();
43
44         preGamePreparations();
45
46         while (true){
47                 getline(cin, input);
48                 if (input == "game-over")
49                         return;
50                 //cerr << input << endl;
51                 //cerr << "Updating world" << endl;
52                 updateWorld();
53                 //cerr << "Done updating world" << endl;
54                 _type = _players[_name].type;
55                 _location = _players[_name].location;
56                 //cerr << "New turn" << endl;
57                 //
58                 string input;
59
60                 sendInformation();
61                 //cerr << "Getting information " << endl;
62                 getInformation();
63
64                 sendPlan();
65                 getPlans();
66
67                 vote();
68                 voteResult();
69
70                 move(turn());
71                 //cerr << "Done with turn." << endl;
72         }
73 }
74
75 void Bot::getPlayers(){
76         string input;
77         //robber and 5 cops
78         getline(cin, input);
79         _players[value<string>(input)].type = robber;
80         getline(cin, input);
81         _players[value<string>(input)].type = cop_foot;
82         getline(cin, input);
83         _players[value<string>(input)].type = cop_foot;
84         getline(cin, input);
85         _players[value<string>(input)].type = cop_foot;
86         getline(cin, input);
87         _players[value<string>(input)].type = cop_foot;
88 }
89
90 /**
91                                 nod\ eol        
92                                 ( nod: loc node-tag coordinate coordinate eol )*        
93                                 nod/ eol        
94                                 edg\ eol        
95                                 ( edg: loc loc edge-type eol )* 
96                                 edg/ eol        
97 */
98 void Bot::buildGraph(){
99         string input;
100         getline(cin, input);
101         if (input != "nod\\")
102                 return;
103
104         //cerr << "Getting intersections" << endl;
105         while (true){
106                 getline(cin, input);
107                 if (input == "nod/")
108                         break;
109                 istringstream node(input);
110                 node >> input;
111                 string name;
112                 node >> name;
113                 Intersection& inter = _intersections[name];
114                 node >> input;
115                 if (input == "bank"){
116                         inter.type = bank;
117                         _banks[name] = 0;
118                 }
119                 else if (input == "hq"){
120                         inter.type = hq;
121                         _copHq = name;
122                 }
123                 else if (input == "robber-start"){
124                         inter.type = robber_start;
125                         _robberLocation = name;
126                 }
127                 else
128                         inter.type = ordinary;
129                 node >> inter.x;
130                 node >> inter.y;
131         }
132
133         //cerr << "Number of intersections: " << _intersections.size() << endl;
134
135         getline(cin, input);
136         if (input != "edg\\")
137                 return;
138
139         //cerr << "Getting streets" << endl;
140         int streets = 0;
141         while (true){
142                 getline(cin, input);
143                 if (input == "edg/")
144                         break;
145                 ++streets;
146                 istringstream street(input);
147                 string from;
148                 street >> from;
149                 street >> from;
150                 string to;
151                 street >> to;
152                 string type;
153                 street >> type;
154                 //cerr << "Street between: " << from << " and " << to << " of type: " << type << endl;
155                 if (type == "foot"){
156                         _intersections[from].connections[to] = both;
157                         Intersection& inter = _intersections[to];
158                         hash_map<string,StreetType>::iterator conn = inter.connections.find(from);
159                         if (conn == inter.connections.end())
160                                 inter.connections[from] = foot;
161                         else if (conn->second == car)
162                                 inter.connections[from] = both;
163                 }else{
164                         Intersection& inter = _intersections[from];
165                         hash_map<string,StreetType>::iterator conn = inter.connections.find(to);
166                         if (conn == inter.connections.end())
167                                 inter.connections[from] = car;
168                         else if (conn->second == foot)
169                                 inter.connections[from] = both;
170                 }
171         }
172         //cerr << "Number of streets: " << streets << endl;
173         getline(cin, input);
174 }
175
176 void Bot::updateWorld(){
177         string input;
178         getline(cin,input);
179         _world = value<int>(input);
180         //cerr << "World: " << _world << endl;
181
182         getline(cin,input);
183         _robbed = value<int>(input);
184         //cerr << "Robbed: " << _robbed << endl;
185         //
186         getline(cin,input);
187         while (true){
188                 getline(cin, input);
189                 if (input == "dc/")
190                         break;
191                 istringstream dirtyCop(input);
192         }
193
194         getline(cin,input);
195         while (true){
196                 getline(cin, input);
197                 if (input == "sc/")
198                         break;
199                 istringstream controlledCop(input);
200         }
201
202         getline(cin,input);
203         while (true){
204                 getline(cin, input);
205                 if (input == "fac/")
206                         break;
207                 istringstream falseAccusation(input);
208         }
209
210         getline(cin,input);
211         while (true){
212                 getline(cin, input);
213                 if (input == "bv/")
214                         break;
215                 istringstream bank(input);
216                 bank >> input;
217                 bank >> input;
218                 bank >> _banks[input];
219         }
220         //cerr << "Number of banks: " << _banks.size() << endl;
221         
222         getline(cin,input);
223         while (true){
224                 getline(cin, input);
225                 if (input == "ev/")
226                         break;
227                 istringstream evidence(input);
228                 int world;
229                 evidence >> input;
230                 evidence >> input;
231                 evidence >> world;
232                 _evidence[world] = input;
233         }
234         
235         getline(cin,input);
236         _smell = value<int>(input);
237
238         _robberLocation = "";
239         getline(cin,input);
240         while (true){
241                 getline(cin, input);
242                 if (input == "pl/")
243                         break;
244                 istringstream player(input);
245                 player >> input;
246                 player >> input;
247                 //cerr << "Player: " << input << endl;
248                 Player& pl = _players[input];
249                 player >> pl.location;
250                 player >> input;
251                 pl.type = _playerTypes[input];
252                 if (pl.type == robber)
253                         _robberLocation = pl.location;
254         }
255         //cerr << "Number of players: " << _players.size() << endl;
256         getline(cin, input);
257 }
258
259 void Bot::move(std::string location){
260         //cerr << "Moving to: " << location << endl;
261         cout << "mov: " << location << " " << _playerTypeNames[_type] << " " << _name << endl;
262 }
263
264 template<class T>
265 T value(std::string input){
266         istringstream istr(input);
267         istr >> input;
268         T s;
269         istr >> s;
270         return s;
271 }
272
273 std::string Bot::turn(){
274         //cerr << "Using stupid stand still Bot::turn" << endl;
275         return _location;
276 }
277
278 struct SPInfoComp{
279         bool operator()(const SPInfo* v1, const SPInfo* v2){
280                 return v1->cost > v2->cost;
281         }
282 };
283
284 std::list<std::string> Bot::shortestPath(const std::string& from, PlayerType type, const SPGoal& goal, bool reverse){
285
286         //cerr << "New shortest path from: " << from << endl;
287         
288         priority_queue<SPInfo*, vector<SPInfo* >, SPInfoComp > pq;
289         hash_map<string,SPInfo> nodes;
290
291         SPInfo* node = &nodes[from];
292         node->name = from;
293         node->settled = false;
294         node->parent = 0;
295         node->cost = 0;
296         pq.push(node);
297
298         int g = 0;
299         bool hascar = type == cop_car;
300         ;
301         SPInfo* n = 0;
302         while(!pq.empty()){
303                 node = pq.top();
304                 pq.pop();
305
306                 g = goal(node);
307                 if (g < 0)
308                         break;
309                 else if (g){
310                         list<string> l;
311                         front_insert_iterator<list<string> > ii(l);
312                         do{
313                                 *ii++ = node->name;
314                                 node = node->parent;
315                         }while (node != 0);
316                         return l;
317                 }
318                 node->settled = true;
319
320                 hash_map<string,Intersection>::const_iterator intersection = _intersections.find(node->name);
321                 if (intersection == _intersections.end()){ //Sanity check, should never be true..
322                         cerr << "BUG: Could not find intersection: " << node->name << endl;
323                         continue;
324                 }
325                 for (hash_map<string,StreetType>::const_iterator street = intersection->second.connections.begin();
326                                 street != intersection->second.connections.end(); ++street){
327                         hash_map<string,SPInfo>::iterator newNode = nodes.find(street->first);
328                         bool travelStreet = false;
329                         if (hascar){
330                                 if (reverse){
331                                         if (street->second != foot){
332                                                 hash_map<string,Intersection>::const_iterator newInter = _intersections.find(street->first);
333                                                 if (newInter != _intersections.end()){
334                                                         hash_map<string,StreetType>::const_iterator st = newInter->second.connections.find(node->name);
335                                                         if (st != newInter->second.connections.end())
336                                                                 travelStreet = st->second != foot;
337                                                 }
338                                         }else
339                                                 travelStreet = true;
340                                 }else
341                                         travelStreet = street->second != foot;
342                         }else{
343                                 travelStreet = street->second != car;
344                         }
345                         if (travelStreet){
346                                 //cerr << "Adding street: " << street->first << endl;
347                                 if (newNode == nodes.end()){
348                                         n = &nodes[street->first];
349                                         n->name = street->first;
350                                         n->settled = false;
351                                         n->parent = 0;
352                                         n->cost = 10000;
353                                 }else if (newNode->second.settled)
354                                         continue;
355                                 else
356                                         n = &newNode->second;
357
358                                 if (n->cost > node->cost + 1){
359                                         n->cost = node->cost + 1;
360                                         n->parent = node;
361                                         pq.push(n);
362                                 }
363                         }
364
365                 }
366                 
367         }
368         
369         return list<string>();
370 }
371
372 SimpleSPGoal::SimpleSPGoal(std::string to):_to(to){
373 }
374
375 int SimpleSPGoal::operator()(const SPInfo* node) const{
376         if (node->name == _to)
377                 return 1;
378         return 0;
379 }
380
381 FindPlayer::FindPlayer(const hash_map<string, Player>& players, PlayerType type, int limit) : _players(players), _type(type), _limit(limit){
382 }
383
384 int FindPlayer::operator()(const SPInfo* node) const{
385         if (_limit > 0 && node->cost >= _limit)
386                 return -1;
387         for(hash_map<string, Player>::const_iterator player = _players.begin();
388                         player != _players.end(); ++player){
389                 if (player->second.type == _type && player->second.location == node->name){
390                         return 1;
391                 }
392         }
393         return 0;
394 }
395
396 void Bot::sendInformation(){
397         cout << "inf\\" << endl;
398         cout << "inf/" << endl;
399 }
400
401 void Bot::getInformation(){
402         string input;
403         do{
404                 getline(cin,input);
405         }while(input != "from/");
406 }
407
408 void Bot::sendPlan(){
409         cout << "plan\\" << endl;
410         cout << "plan/" << endl;
411 }
412
413 void Bot::getPlans(){
414         string input;
415         //ignore From-plan
416         do{
417                 getline(cin,input);
418         }while(input != "from/");
419 }
420
421 void Bot::vote(){
422         cout << "vote\\" << endl;
423         cout << "vote: " << _name << endl;
424         priority_queue<pair<int,string> > players;
425         for (hash_map<string,int>::const_iterator player = _winningPlans.begin();
426                         player != _winningPlans.end(); ++player){
427                 players.push(pair<int,string>(-player->second, player->first));
428         }
429         while (players.size() > 0){
430                 const pair<int,string>& player = players.top();
431                 cout << "vote: " << player.second << endl;
432                 //cerr << "voted for " << player.second << " with " << player.first << " previously won plans" << endl;
433                 players.pop();
434         }
435         cout << "vote/" << endl;
436 }
437
438 void Bot::voteResult(){
439         string input;
440         getline(cin,input);
441         if (input != "nowinner:"){
442                 string winner = value<string>(input);
443                 if (winner != _name)
444                         ++_winningPlans[winner];
445         }
446 }