-
Notifications
You must be signed in to change notification settings - Fork 1
/
PathMap.cpp
161 lines (144 loc) · 4.54 KB
/
PathMap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
///////////////////////////////////////////////////////////////////////////////////////////////
//
// -- GNU -- open source
// Please read and agree to the mb_gnu_license.txt file
// (the file is located in the marine_bot source folder)
// before editing or distributing this source code.
// This source code is free for use under the rules of the GNU General Public License.
// For more information goto:: http://www.gnu.org/licenses/
//
// credits to - valve, botman.
//
// Marine Bot - code by Frank McNeil, Kota@, Mav, Shrike.
//
// (http://www.marinebot.tk)
//
//
// PathMap.cpp
//
////////////////////////////////////////////////////////////////////////////////////////////////
#include "PathMap.h"
#include <stdio.h>
PathMap::PathMap()
{
}
PathMap::~PathMap()
{
}
/*
* add new path for brain analyzer.
*/
void PathMap::add(int from, int to, int weight,
int from_flags, int from_border,
int to_flags, int to_border) {
if (from < 0) return;
Info info;
//this is not quite average, but it is simpler.
(*this)[from][to].weight_own += weight;
(*this)[from].flags = from_flags;
(*this)[from].border = from_border;
//add reverse path with original weight too.
//We aren't sure this path is reliable, that is why
//we only add weight once.
(*this)[to][from].weight_own = weight;
(*this)[to].flags = to_flags;
(*this)[to].border = to_border;
}
/*
* Load pathmap for brain analyzer from presaved/stored file.
*/
bool PathMap::load(FILE *f) {
if (f==NULL) return false;
int i, from, to, weight;
int from_flags, from_border;
while ((i = fscanf(f, "from=%d to=%d num=%d | flags=%d border=%d\n",
&from, &to, &weight, &from_flags, &from_border))!=EOF) {
if (from < 0) continue;
Info info;
(*this)[from][to].weight_own = weight;
(*this)[from].flags = from_flags;
(*this)[from].border = from_border;
}
return true;
}
void PathMap::save(const string file_name) const {
FILE *path_f = fopen(file_name.c_str(), "w+");
if (path_f == NULL) {
return;
}
for (PathMap_CI pm_ci = begin(); pm_ci != end(); ++pm_ci) {
for (NeighbourMap_CI nbm_ci = pm_ci->second.begin();
nbm_ci != pm_ci->second.end(); ++nbm_ci) {
fprintf(path_f, "from=%d to=%d num=%d | flags=%d border=%d\n",
pm_ci->first, nbm_ci->first, nbm_ci->second.weight_own,
pm_ci->second.flags, pm_ci->second.border);
}
}
fclose(path_f);
}
/*
Find the easiest way to the wpt with parameters in "to"
This way can be not the shortest (sometimes).
You can deside this by functor "to"
*/
int PathMap::findPath(const int from, const equalWpt &to, PointList *pl, const int steps) {
static int ticket = 1;
++ticket;
NeighbourMap round0, round1;
NeighbourMap *cur_round=&round0, *next_round=&round1, *tmp_round;
(*cur_round)[from];
(*cur_round)[from];
(*this)[from].parent=-1;
(*this)[from].ticket=ticket;
(*this)[from].weight=1;
for (int i=0; i<steps; ++i) {
next_round->clear();
for (NeighbourMap_I pl_i = cur_round->begin();
pl_i != cur_round->end(); ++pl_i) {
if (to(pl_i->first, (*this)[pl_i->first])) { //WE FOUND THE WAY!!!
//create chance (point way).
if (pl!=NULL) {
pl->push_front(pl_i->first);
}
int cur_num = pl_i->first;
int right_way=pl_i->first;
while ((*this)[cur_num].parent != -1) {
right_way = cur_num;
cur_num = (*this)[cur_num].parent;
if (pl!=NULL) {
pl->push_front(cur_num);
}
}
return right_way;
}
//find neighbourgs of current border.
//and push their into border for next round.
//@@@@ cerr<<"look point " << pl_i->first << " weight="
//<< (*this)[pl_i->first].weight << endl;
for (NeighbourMap_I nm_i = (*this)[pl_i->first].begin();
nm_i != (*this)[pl_i->first].end(); ++nm_i) {
//number of steps is prefered, but weight is important too.
//+1.0 - we add step, 1.0/weight_own - weight of current step.
double new_weight = (*this)[pl_i->first].weight + 1.0 + 1.0/nm_i->second.weight_own;
if ((*this)[nm_i->first].ticket != ticket) { /*don't use wpt before*/
(*next_round)[nm_i->first];
(*this)[nm_i->first].weight = new_weight;
(*this)[nm_i->first].parent = pl_i->first;
(*this)[nm_i->first].ticket = ticket;
}
else if (new_weight < (*this)[nm_i->first].weight) {
(*next_round)[nm_i->first];
(*this)[nm_i->first].weight = new_weight;
(*this)[nm_i->first].parent = pl_i->first;
//cerr << "overload" <<endl;
}
}
}
//we create new border, make it current.
tmp_round = cur_round;
cur_round = next_round;
next_round= tmp_round;
}
return -1;
}
TeamPathMap teamPathMap;