]> ruin.nu Git - icfp05.git/blob - botsrc/bot.cpp
10fb5447952d3e4bd58c21e80af169cb2fbf7e6e
[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                         if (inter.connections.find(from) == inter.connections.end())
159                                 inter.connections[from] = foot;
160                 }else
161                         _intersections[from].connections[to] = car;
162         }
163         //cerr << "Number of streets: " << streets << endl;
164         getline(cin, input);
165 }
166
167 void Bot::updateWorld(){
168         cerr << "Entered updateWorld function" << endl;
169         string input;
170         getline(cin,input);
171         cerr << input << endl;
172         _world = value<int>(input);
173         cerr << "World: " << _world << endl;
174
175         getline(cin,input);
176         _robbed = value<int>(input);
177         //cerr << "Robbed: " << _robbed << endl;
178         //
179         getline(cin,input);
180         while (true){
181                 getline(cin, input);
182                 if (input == "dc/")
183                         break;
184                 istringstream dirtyCop(input);
185         }
186
187         getline(cin,input);
188         while (true){
189                 getline(cin, input);
190                 if (input == "sc/")
191                         break;
192                 istringstream controlledCop(input);
193         }
194
195         getline(cin,input);
196         while (true){
197                 getline(cin, input);
198                 if (input == "fac/")
199                         break;
200                 istringstream falseAccusation(input);
201         }
202
203         getline(cin,input);
204         while (true){
205                 getline(cin, input);
206                 if (input == "bv/")
207                         break;
208                 istringstream bank(input);
209                 bank >> input;
210                 bank >> input;
211                 bank >> _banks[input];
212         }
213         //cerr << "Number of banks: " << _banks.size() << endl;
214         
215         getline(cin,input);
216         while (true){
217                 getline(cin, input);
218                 if (input == "ev/")
219                         break;
220                 istringstream evidence(input);
221                 int world;
222                 evidence >> input;
223                 evidence >> input;
224                 evidence >> world;
225                 _evidence[world] = input;
226         }
227         
228         getline(cin,input);
229         _smell = value<int>(input);
230
231         _robberLocation = "";
232         getline(cin,input);
233         while (true){
234                 getline(cin, input);
235                 if (input == "pl/")
236                         break;
237                 istringstream player(input);
238                 player >> input;
239                 player >> input;
240                 //cerr << "Player: " << input << endl;
241                 Player& pl = _players[input];
242                 player >> pl.location;
243                 player >> input;
244                 pl.type = _playerTypes[input];
245                 if (pl.type == robber)
246                         _robberLocation = pl.location;
247         }
248         //cerr << "Number of players: " << _players.size() << endl;
249         getline(cin, input);
250 }
251
252 void Bot::move(std::string location){
253         //cerr << "Moving to: " << location << endl;
254         cout << "mov: " << location << " " << _playerTypeNames[_type] << " " << _name << endl;
255 }
256
257 template<class T>
258 T value(std::string input){
259         istringstream istr(input);
260         istr >> input;
261         T s;
262         istr >> s;
263         return s;
264 }
265
266 std::string Bot::turn(){
267         cerr << "Using stupid stand still Bot::turn" << endl;
268         return _location;
269 }
270
271 struct SPInfoComp{
272         bool operator()(const SPInfo* v1, const SPInfo* v2){
273                 return v1->cost > v2->cost;
274         }
275 };
276
277 std::list<std::string> Bot::shortestPath(const std::string& from, PlayerType type, const SPGoal& goal, bool reverse){
278
279         //cerr << "New shortest path from: " << from << endl;
280         
281         priority_queue<SPInfo*, vector<SPInfo* >, SPInfoComp > pq;
282         hash_map<string,SPInfo> nodes;
283
284         SPInfo* node = &nodes[from];
285         node->name = from;
286         node->settled = false;
287         node->parent = 0;
288         node->cost = 0;
289         pq.push(node);
290
291         int g = 0;
292         bool hascar = type == cop_car;
293         ;
294         SPInfo* n = 0;
295         while(!pq.empty()){
296                 node = pq.top();
297                 pq.pop();
298
299                 g = goal(node);
300                 if (g < 0)
301                         break;
302                 else if (g){
303                         list<string> l;
304                         front_insert_iterator<list<string> > ii(l);
305                         do{
306                                 *ii++ = node->name;
307                                 node = node->parent;
308                         }while (node != 0);
309                         return l;
310                 }
311                 node->settled = true;
312
313                 hash_map<string,Intersection>::const_iterator intersection = _intersections.find(node->name);
314                 if (intersection == _intersections.end()){ //Sanity check, should never be true..
315                         cerr << "BUG: Could not find intersection: " << node->name << endl;
316                         continue;
317                 }
318                 for (hash_map<string,StreetType>::const_iterator street = intersection->second.connections.begin();
319                                 street != intersection->second.connections.end(); ++street){
320                         hash_map<string,SPInfo>::iterator newNode = nodes.find(street->first);
321                         bool travelStreet = false;
322                         if (hascar){
323                                 if (reverse){
324                                         if (street->second != foot){
325                                                 hash_map<string,Intersection>::const_iterator newInter = _intersections.find(street->first);
326                                                 if (newInter != _intersections.end()){
327                                                         hash_map<string,StreetType>::const_iterator st = newInter->second.connections.find(node->name);
328                                                         if (st != newInter->second.connections.end())
329                                                                 travelStreet = st->second != foot;
330                                                 }
331                                         }else
332                                                 travelStreet = true;
333                                 }else
334                                         travelStreet = street->second != foot;
335                         }else{
336                                 travelStreet = street->second != car;
337                         }
338                         if (travelStreet){
339                                 //cerr << "Adding street: " << street->first << endl;
340                                 if (newNode == nodes.end()){
341                                         n = &nodes[street->first];
342                                         n->name = street->first;
343                                         n->settled = false;
344                                         n->parent = 0;
345                                         n->cost = 10000;
346                                 }else if (newNode->second.settled)
347                                         continue;
348                                 else
349                                         n = &newNode->second;
350
351                                 if (n->cost > node->cost + 1){
352                                         n->cost = node->cost + 1;
353                                         n->parent = node;
354                                         pq.push(n);
355                                 }
356                         }
357
358                 }
359                 
360         }
361         
362         return list<string>();
363 }
364
365 SimpleSPGoal::SimpleSPGoal(std::string to):_to(to){
366 }
367
368 int SimpleSPGoal::operator()(const SPInfo* node) const{
369         if (node->name == _to)
370                 return 1;
371         return 0;
372 }
373
374 FindPlayer::FindPlayer(const hash_map<string, Player>& players, PlayerType type, int limit) : _players(players), _type(type), _limit(limit){
375 }
376
377 int FindPlayer::operator()(const SPInfo* node) const{
378         if (_limit > 0 && node->cost >= _limit)
379                 return -1;
380         for(hash_map<string, Player>::const_iterator player = _players.begin();
381                         player != _players.end(); ++player){
382                 if (player->second.type == _type && player->second.location == node->name){
383                         return 1;
384                 }
385         }
386         return 0;
387 }
388
389 void Bot::sendInformation(){
390         cout << "inf\\" << endl;
391         cout << "inf/" << endl;
392 }
393
394 void Bot::getInformation(){
395         string input;
396         do{
397                 getline(cin,input);
398         }while(input != "from/");
399 }
400
401 void Bot::sendPlan(){
402         cout << "plan\\" << endl;
403         cout << "plan/" << endl;
404 }
405
406 void Bot::getPlans(){
407         string input;
408         //ignore From-plan
409         do{
410                 getline(cin,input);
411         }while(input != "from/");
412 }
413
414 void Bot::vote(){
415         cout << "vote\\" << endl;
416         cout << "vote: " << _name << endl;
417         priority_queue<pair<int,string> > players;
418         for (hash_map<string,int>::const_iterator player = _winningPlans.begin();
419                         player != _winningPlans.end(); ++player){
420                 players.push(pair<int,string>(-player->second, player->first));
421         }
422         while (players.size() > 0){
423                 const pair<int,string>& player = players.top();
424                 cout << "vote: " << player.second << endl;
425                 //cerr << "voted for " << player.second << " with " << player.first << " previously won plans" << endl;
426                 players.pop();
427         }
428         cout << "vote/" << endl;
429 }
430
431 void Bot::voteResult(){
432         string input;
433         getline(cin,input);
434         if (input != "nowinner:"){
435                 string winner = value<string>(input);
436                 if (winner != _name)
437                         ++_winningPlans[winner];
438         }
439 }