]> ruin.nu Git - icfp05.git/blob - bot/bot.cpp
some restructuring
[icfp05.git] / bot / 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         while (true){
45                 getline(cin, input);
46                 if (input == "game-over")
47                         return;
48                 updateWorld();
49                 _type = _players[_name].type;
50                 _location = _players[_name].location;
51                 cerr << "New turn" << endl;
52                 move(turn());
53                 cerr << "Done with turn." << endl;
54         }
55 }
56
57 void Bot::getPlayers(){
58         string input;
59         //robber and 5 cops
60         getline(cin, input);
61         _players[value<string>(input)].type = robber;
62         getline(cin, input);
63         _players[value<string>(input)].type = cop_foot;
64         getline(cin, input);
65         _players[value<string>(input)].type = cop_foot;
66         getline(cin, input);
67         _players[value<string>(input)].type = cop_foot;
68         getline(cin, input);
69         _players[value<string>(input)].type = cop_foot;
70 }
71
72 /**
73                                 nod\ eol        
74                                 ( nod: loc node-tag coordinate coordinate eol )*        
75                                 nod/ eol        
76                                 edg\ eol        
77                                 ( edg: loc loc edge-type eol )* 
78                                 edg/ eol        
79 */
80 void Bot::buildGraph(){
81         string input;
82         getline(cin, input);
83         if (input != "nod\\")
84                 return;
85
86         cerr << "Getting intersections" << endl;
87         while (true){
88                 getline(cin, input);
89                 if (input == "nod/")
90                         break;
91                 istringstream node(input);
92                 node >> input;
93                 node >> input;
94                 Intersection& inter = _intersections[input];
95                 node >> input;
96                 if (input == "bank")
97                         inter.type = bank;
98                 else if (input == "hq")
99                         inter.type = hq;
100                 else if (input == "robber-start")
101                         inter.type = robber_start;
102                 else
103                         inter.type = ordinary;
104                 node >> inter.x;
105                 node >> inter.y;
106         }
107
108         cerr << "Number of intersections: " << _intersections.size() << endl;
109
110         getline(cin, input);
111         if (input != "edg\\")
112                 return;
113
114         cerr << "Getting streets" << endl;
115         int streets = 0;
116         while (true){
117                 getline(cin, input);
118                 if (input == "edg/")
119                         break;
120                 ++streets;
121                 istringstream street(input);
122                 string from;
123                 street >> from;
124                 street >> from;
125                 string to;
126                 street >> to;
127                 string type;
128                 street >> type;
129                 //cerr << "Street between: " << from << " and " << to << " of type: " << type << endl;
130                 if (type == "foot"){
131                         _intersections[from].connections[to] = both;
132                         Intersection& inter = _intersections[to];
133                         if (inter.connections.find(from) == inter.connections.end())
134                                 inter.connections[from] = foot;
135                 }else
136                         _intersections[from].connections[to] = car;
137         }
138         cerr << "Number of streets: " << streets << endl;
139         getline(cin, input);
140 }
141
142 void Bot::updateWorld(){
143         string input;
144         getline(cin,input);
145         _world = value<int>(input);
146         //cerr << "World: " << _world << endl;
147
148         getline(cin,input);
149         _robbed = value<int>(input);
150         //cerr << "Robbed: " << _robbed << endl;
151
152         getline(cin,input);
153         while (true){
154                 getline(cin, input);
155                 if (input == "bv/")
156                         break;
157                 istringstream bank(input);
158                 bank >> input;
159                 bank >> input;
160                 bank >> _banks[input];
161         }
162         //cerr << "Number of banks: " << _banks.size() << endl;
163         
164         getline(cin,input);
165         while (true){
166                 getline(cin, input);
167                 if (input == "ev/")
168                         break;
169                 istringstream evidence(input);
170                 int world;
171                 evidence >> input;
172                 evidence >> input;
173                 evidence >> world;
174                 _evidence[world] = input;
175         }
176         
177         getline(cin,input);
178         _smell = value<int>(input);
179
180         getline(cin,input);
181         while (true){
182                 getline(cin, input);
183                 if (input == "pl/")
184                         break;
185                 istringstream player(input);
186                 player >> input;
187                 player >> input;
188                 //cerr << "Player: " << input << endl;
189                 Player& pl = _players[input];
190                 player >> pl.location;
191                 player >> input;
192                 pl.type = _playerTypes[input];
193         }
194         //cerr << "Number of players: " << _players.size() << endl;
195         getline(cin, input);
196 }
197
198 void Bot::move(std::string location){
199         cerr << "Moving to: " << location << endl;
200         cout << "mov: " << location << " " << _playerTypeNames[_type] << endl;
201 }
202
203 template<class T>
204 T value(std::string input){
205         istringstream istr(input);
206         istr >> input;
207         T s;
208         istr >> s;
209         return s;
210 }
211
212 std::string Bot::turn(){
213         cerr << "Using stupid stand still Bot::turn" << endl;
214         return _location;
215 }
216
217 struct SPInfoComp{
218         bool operator()(const SPInfo* v1, const SPInfo* v2){
219                 return v1->cost > v2->cost;
220         }
221 };
222
223 std::list<std::string> Bot::shortestPath(const std::string& from, PlayerType type, const SPGoal& goal, bool reverse){
224
225         //cerr << "New shortest path from: " << from << endl;
226         
227         priority_queue<SPInfo*, vector<SPInfo* >, SPInfoComp > pq;
228         hash_map<string,SPInfo> nodes;
229
230         SPInfo* node = &nodes[from];
231         node->name = from;
232         node->settled = false;
233         node->parent = 0;
234         node->cost = 0;
235         pq.push(node);
236
237         int g = 0;
238         bool hascar = type == cop_car;
239         while(!pq.empty()){
240                 node = pq.top();
241                 pq.pop();
242                 //cerr << "Vector with size: " << w.size() << endl;
243                 //cerr << "Looking at: " << node->name << endl;
244                 //copy(w.begin(), w.end(), ostream_iterator<string>(cerr, " : "));
245
246                 g = goal(node);
247                 if (g < 0)
248                         break;
249                 else if (g){
250                         list<string> l;
251                         front_insert_iterator<list<string> > ii(l);
252                         do{
253                                 *ii++ = node->name;
254                                 node = node->parent;
255                         }while (node != 0);
256                         return l;
257                 }
258                 node->settled = true;
259
260                 Intersection& inter = _intersections[node->name];
261                 for (hash_map<string,StreetType>::const_iterator street = inter.connections.begin();
262                                 street != inter.connections.end(); ++street){
263                         hash_map<string,SPInfo>::iterator newNode = nodes.find(street->first);
264                         bool travelStreet = false;
265                         if (hascar){
266                                 if (reverse){
267                                         if (street->second != foot){
268                                                 hash_map<string,StreetType>::const_iterator st = _intersections[street->first].connections.find(node->name);
269                                                 if (st != _intersections[street->first].connections.end())
270                                                         travelStreet = st->second != foot;
271                                                 else
272                                                         travelStreet = false;
273                                         }else
274                                                 travelStreet = true;
275                                 }else
276                                         travelStreet = street->second != foot;
277                         }else{
278                                 travelStreet = street->second != car;
279                         }
280                         if (travelStreet){
281                                 //cerr << "Adding street: " << street->first << endl;
282                                 SPInfo* n = 0;
283                                 if (newNode == nodes.end()){
284                                         n = &nodes[street->first];
285                                         n->name = street->first;
286                                         n->settled = false;
287                                         n->parent = 0;
288                                         n->cost = 10000;
289                                 }else if (newNode->second.settled)
290                                         continue;
291                                 else
292                                         n = &newNode->second;
293
294                                 if (n->cost > node->cost + 1){
295                                         n->cost = node->cost + 1;
296                                         n->parent = node;
297                                         pq.push(n);
298                                 }
299                         }
300
301                 }
302                 
303         }
304         
305         return list<string>();
306 }
307
308 SimpleSPGoal::SimpleSPGoal(std::string to):_to(to){
309 }
310
311 int SimpleSPGoal::operator()(const SPInfo* node) const{
312         if (node->name == _to)
313                 return 1;
314         return 0;
315 }
316
317 FindPlayer::FindPlayer(const hash_map<string, Player>& players, PlayerType type, int limit) : _players(players), _type(type), _limit(limit){
318 }
319
320 int FindPlayer::operator()(const SPInfo* node) const{
321         if (_limit > 0 && node->cost >= _limit)
322                 return -1;
323         for(hash_map<string, Player>::const_iterator player = _players.begin();
324                         player != _players.end(); ++player){
325                 if (player->second.type == _type && player->second.location == node->name){
326                         return 1;
327                 }
328         }
329         return 0;
330 }