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