|
|
|
@ -37,6 +37,81 @@ int Railways::UnLock() {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// data must be mutex looked before use
|
|
|
|
|
struct s_findway_data Railways::NextPos(struct s_findway_data pos, int dirtype) {
|
|
|
|
|
struct s_findway_data np = { x: -1, y: -1, enterfrom: -1, parma: pos.parma }; // newpos
|
|
|
|
|
|
|
|
|
|
if (dirtype == 1) {
|
|
|
|
|
if (pos.enterfrom == EF_NORTH) {
|
|
|
|
|
np.x = pos.x;
|
|
|
|
|
np.y = pos.y + 1 ;
|
|
|
|
|
np.enterfrom = EF_NORTH;
|
|
|
|
|
} else if (pos.enterfrom == EF_SOUTH) {
|
|
|
|
|
np.x = pos.x;
|
|
|
|
|
np.y = pos.y - 1;
|
|
|
|
|
np.enterfrom = EF_SOUTH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (dirtype == 2) {
|
|
|
|
|
if (pos.enterfrom == EF_WEST) {
|
|
|
|
|
np.x = pos.x + 1;
|
|
|
|
|
np.y = pos.y;
|
|
|
|
|
np.enterfrom = EF_WEST;
|
|
|
|
|
} else if (pos.enterfrom == EF_EAST) {
|
|
|
|
|
np.x = pos.x - 1;
|
|
|
|
|
np.y = pos.y;
|
|
|
|
|
np.enterfrom = EF_EAST;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (dirtype == 3) {
|
|
|
|
|
if (pos.enterfrom == EF_WEST) {
|
|
|
|
|
np.x = pos.x;
|
|
|
|
|
np.y = pos.y - 1;
|
|
|
|
|
np.enterfrom = EF_SOUTH;
|
|
|
|
|
} else if (pos.enterfrom == EF_NORTH){
|
|
|
|
|
np.x = pos.x - 1;
|
|
|
|
|
np.y = pos.y;
|
|
|
|
|
np.enterfrom = EF_EAST;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (dirtype == 4) {
|
|
|
|
|
if (pos.enterfrom == EF_NORTH) {
|
|
|
|
|
np.x = pos.x + 1;
|
|
|
|
|
np.y = pos.y;
|
|
|
|
|
np.enterfrom = EF_WEST;
|
|
|
|
|
} else if (pos.enterfrom == EF_EAST){
|
|
|
|
|
np.x = pos.x;
|
|
|
|
|
np.y = pos.y - 1;
|
|
|
|
|
np.enterfrom = EF_SOUTH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (dirtype == 5) {
|
|
|
|
|
if (pos.enterfrom == EF_SOUTH) {
|
|
|
|
|
np.x = pos.x + 1;
|
|
|
|
|
np.y = pos.y;
|
|
|
|
|
np.enterfrom = EF_WEST;
|
|
|
|
|
} else if (pos.enterfrom == EF_EAST){
|
|
|
|
|
np.x = pos.x;
|
|
|
|
|
np.y = pos.y + 1;
|
|
|
|
|
np.enterfrom = EF_NORTH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (dirtype == 6) {
|
|
|
|
|
if (pos.enterfrom == EF_WEST) {
|
|
|
|
|
np.x = pos.x;
|
|
|
|
|
np.y = pos.y + 1;
|
|
|
|
|
np.enterfrom = EF_NORTH;
|
|
|
|
|
} else if (pos.enterfrom == EF_SOUTH){
|
|
|
|
|
np.x = pos.x - 1;
|
|
|
|
|
np.y = pos.y;
|
|
|
|
|
np.enterfrom = EF_EAST;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return np;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// return index inside the array (clip to boundery)
|
|
|
|
@ -319,7 +394,8 @@ void Railways::ClearLockedby(string name) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Railways::FindReference(int *x, int *y, string name) {
|
|
|
|
|
|
|
|
|
|
int Railways::_FindReference(int *x, int *y, string name) {
|
|
|
|
|
int found = 0;
|
|
|
|
|
if (x == NULL || y == NULL) return 0;
|
|
|
|
|
if (*x < 0 || *y < 0) {
|
|
|
|
@ -327,7 +403,8 @@ int Railways::FindReference(int *x, int *y, string name) {
|
|
|
|
|
*y = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
printf ("%s:%d find reference (%d,%d,%s)\n", __FILE__, __LINE__, *x, *y, name.c_str());
|
|
|
|
|
|
|
|
|
|
for (; found == 0 && *y < height; (*y)++) {
|
|
|
|
|
if (*x >= width) *x = 0;
|
|
|
|
|
else (*x)++;
|
|
|
|
@ -338,15 +415,269 @@ int Railways::FindReference(int *x, int *y, string name) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (found) break;
|
|
|
|
|
}
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d found (%d,%d)\n", __FILE__, __LINE__, *x, *y);
|
|
|
|
|
|
|
|
|
|
if (*x < width && *y < height) return 1;
|
|
|
|
|
else return 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int FindWay(string blockstart, string blockend, string lockedfor, string *next) {
|
|
|
|
|
int Railways::FindReference(int *x, int *y, string name) {
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
res = _FindReference (x, y, name);
|
|
|
|
|
UnLock();
|
|
|
|
|
return res;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Railways::DebugPrintFindWay(struct s_findway_map *fw) {
|
|
|
|
|
string c;
|
|
|
|
|
int x, y;
|
|
|
|
|
int idx;
|
|
|
|
|
char chr;
|
|
|
|
|
|
|
|
|
|
printf (" ");
|
|
|
|
|
for (x = 0; x < width && x < 80; x++)
|
|
|
|
|
printf ("%c", (char) ((x % 10) + '0'));
|
|
|
|
|
printf ("\n");
|
|
|
|
|
for (y = 0; y < height && y < 40; y++) {
|
|
|
|
|
printf ("%c ", (char) ((y % 10) + '0'));
|
|
|
|
|
for (x = 0; x < width && x < 80; x++) {
|
|
|
|
|
idx = GetRIdx(x, y);
|
|
|
|
|
if (railways[idx].dir == 1) c = "│";
|
|
|
|
|
if (railways[idx].dir == 2) c = "─";
|
|
|
|
|
if (railways[idx].dir == 3) c = "╯";
|
|
|
|
|
if (railways[idx].dir == 4) c = "╰";
|
|
|
|
|
if (railways[idx].dir == 5) c = "╭";
|
|
|
|
|
if (railways[idx].dir == 6) c = "╮";
|
|
|
|
|
if (railways[idx].type == RAILWAY_CROSSING) c = "+";
|
|
|
|
|
if (railways[idx].type == RAILWAY_TURNOUT) c = "t";
|
|
|
|
|
if (railways[idx].type == RAILWAY_CONNECTOR) c = "◯";
|
|
|
|
|
if (railways[idx].type == RAILWAY_BLOCK && railways[idx].dir == 1) c = "┃";
|
|
|
|
|
if (railways[idx].type == RAILWAY_BLOCK && railways[idx].dir == 2) c = "━";
|
|
|
|
|
|
|
|
|
|
if (fw != NULL) {
|
|
|
|
|
if ((fw[idx].e & 15) > 0) {
|
|
|
|
|
chr = (char)('0' + (fw[idx].e & 15));
|
|
|
|
|
if (chr > '9') chr = chr - ('0' + 10) + 'A';
|
|
|
|
|
c = chr;
|
|
|
|
|
}
|
|
|
|
|
else if (fw[idx].e != 0) {
|
|
|
|
|
c = "?";
|
|
|
|
|
printf ("---%d---", fw[idx].e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
printf ("%s", c.c_str());
|
|
|
|
|
c = " ";
|
|
|
|
|
}
|
|
|
|
|
printf ("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < width && x < 80; x++)
|
|
|
|
|
printf ("%c", (char) ((x % 10) + '0'));
|
|
|
|
|
printf ("\n");
|
|
|
|
|
|
|
|
|
|
printf ("Debug Finished\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// return 0 if no way found
|
|
|
|
|
int Railways::FindWay(string blockstart, string blockend, string lockedfor, string *next) {
|
|
|
|
|
// direction 0 ... RIGHT and DOWN
|
|
|
|
|
// direction 1 ... LEFT and UP
|
|
|
|
|
|
|
|
|
|
struct s_findway_data fd_pos;
|
|
|
|
|
struct s_findway_data fd_tmp;
|
|
|
|
|
struct s_findway_data fd_start;
|
|
|
|
|
struct s_findway_data fd_end;
|
|
|
|
|
Railway *rpos, *rnext;
|
|
|
|
|
std::list<struct s_findway_data> fd_list;
|
|
|
|
|
struct s_findway_map *fd_data = NULL;
|
|
|
|
|
string lockedby;
|
|
|
|
|
int i, x ,y;
|
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
|
|
// check blocklen
|
|
|
|
|
if (blockstart.length() <= 3 || blockend.length() <= 3) return 0;
|
|
|
|
|
|
|
|
|
|
// allocate and clear memory for checked data
|
|
|
|
|
fd_data = (struct s_findway_map *) malloc (sizeof(struct s_findway_map) * width * height);
|
|
|
|
|
if (fd_data == NULL) {
|
|
|
|
|
printf ("%s:%d (%s) FATAL ERROR: could not allocate enough memory\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
memset (fd_data, 0x0, sizeof(struct s_findway_map) * width*height);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// find start and endpoint mark on fd_data, also startpoint to fd_list
|
|
|
|
|
fd_end.x = fd_start.x = -1;
|
|
|
|
|
fd_end.y = fd_start.y = -1;
|
|
|
|
|
fd_end.enterfrom = fd_start.enterfrom = -1;
|
|
|
|
|
fd_end.parma = fd_start.parma = -1;
|
|
|
|
|
|
|
|
|
|
if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) {
|
|
|
|
|
if (Get(fd_start.x, fd_start.y).dir == 1) {
|
|
|
|
|
if (blockstart[0] == '+') fd_start.enterfrom = 0;
|
|
|
|
|
else fd_start.enterfrom = 2;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (blockstart[0] == '+') fd_start.enterfrom = 3;
|
|
|
|
|
else fd_start.enterfrom = 1;
|
|
|
|
|
}
|
|
|
|
|
fd_data[GetRIdx(fd_start.x, fd_start.y)].e = (1 << fd_start.enterfrom);
|
|
|
|
|
fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1;
|
|
|
|
|
fd_start.parma = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
debug (0, "Railway::FindWay could not find startblock (%s).", blockstart.c_str());
|
|
|
|
|
free (fd_data);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FindReference(&fd_end.x, &fd_end.y, blockend.substr(2, string::npos))) {
|
|
|
|
|
if (Get(fd_end.x, fd_end.y).dir == 1) {
|
|
|
|
|
if (blockend[0] == '+') fd_end.enterfrom = 0;
|
|
|
|
|
else fd_end.enterfrom = 2;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (blockend[0] == '+') fd_end.enterfrom = 3;
|
|
|
|
|
else fd_end.enterfrom = 1;
|
|
|
|
|
}
|
|
|
|
|
fd_data[GetRIdx(fd_end.x, fd_end.y)].e = (1 << fd_end.enterfrom);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
debug (0, "Railway::FindWay could not find endblock (%s).", blockend.c_str());
|
|
|
|
|
free (fd_data);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fd_pos = NextPos(fd_start, Get(fd_start.x, fd_start.y).dir);
|
|
|
|
|
// fd_list.push_back(fd_pos);
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// loop through the map; if found next needs to be filled in
|
|
|
|
|
while ((fd_list.size() > 0 || fd_pos.enterfrom >= 0) && found == 0) {
|
|
|
|
|
DebugPrintFindWay(fd_data);
|
|
|
|
|
if (fd_pos.enterfrom < 0) {
|
|
|
|
|
std::list<struct s_findway_data>::iterator iter;
|
|
|
|
|
|
|
|
|
|
iter = fd_list.begin();
|
|
|
|
|
if (iter != fd_list.end()) {
|
|
|
|
|
fd_pos = *iter;
|
|
|
|
|
fd_list.pop_front();
|
|
|
|
|
printf ("get from stack (%d,%d)\n", fd_pos.x, fd_pos.y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d fd_start (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_start.x, fd_start.y, fd_start.enterfrom);
|
|
|
|
|
printf ("%s:%d fd_end (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_end.x, fd_end.y, fd_end.enterfrom);
|
|
|
|
|
printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
|
|
|
|
|
if (fd_pos.enterfrom < 0 && fd_pos.enterfrom > 3) {
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
else if (fd_pos.enterfrom >= 0 && fd_end.x == fd_pos.x && fd_pos.y == fd_end.y && fd_pos.enterfrom == fd_end.enterfrom) {
|
|
|
|
|
// destination found
|
|
|
|
|
printf ("%s:%d destination found fd_pos (%d,%d) fd_end (%d,%d)\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_end.x, fd_end.y);
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
else if (fd_pos.enterfrom >= 0 && fd_start.x == fd_pos.x && fd_start.y == fd_pos.y && fd_start.enterfrom == fd_pos.enterfrom) {
|
|
|
|
|
// start found
|
|
|
|
|
printf ("%s:%d start found fd_pos (%d,%d) fd_start (%d,%d)\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_start.x, fd_start.y);
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
else if (fd_data[GetRIdx(fd_pos.x, fd_pos.y)].e & (1 << fd_pos.enterfrom)) {
|
|
|
|
|
// old entry found
|
|
|
|
|
printf ("old entry found (%d,%d)\n", fd_pos.x, fd_pos.y);
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
else if (fd_pos.enterfrom >= 0) {
|
|
|
|
|
rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
|
|
|
|
|
fd_data[GetRIdx(fd_pos.x, fd_pos.y)].e |= (1 << fd_pos.enterfrom);
|
|
|
|
|
|
|
|
|
|
if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) {
|
|
|
|
|
fd_pos = NextPos(fd_pos, rpos->dir);
|
|
|
|
|
fd_pos.parma++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (rpos->type == RAILWAY_TURNOUT) {
|
|
|
|
|
fd_tmp = NextPos(fd_pos, rpos->altdir);
|
|
|
|
|
printf ("%s:%d turnout dir:%d altdir:%d fd_pos (%d,%d -> %d) fd_tmp (%d,%d -> %d)\n", __FILE__, __LINE__, rpos->dir, rpos->altdir, fd_pos.x, fd_pos.y, fd_pos.enterfrom, fd_tmp.x, fd_tmp.y, fd_tmp.enterfrom);
|
|
|
|
|
fd_tmp.parma++;
|
|
|
|
|
fd_list.push_back(fd_tmp);
|
|
|
|
|
fd_pos = NextPos(fd_pos, rpos->dir);
|
|
|
|
|
fd_pos.parma++;
|
|
|
|
|
printf ("%s:%d turnout fd_newpos (%d,%d -> %d)\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (rpos->type == RAILWAY_CONNECTOR) {
|
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d connector found Reference:'%s'\n", __FILE__, __LINE__, rpos->name);
|
|
|
|
|
|
|
|
|
|
while (found == 0 && _FindReference(&x, &y, rpos->name) == 1) {
|
|
|
|
|
if (fd_pos.x != x || fd_pos.y != y) {
|
|
|
|
|
printf ("%s:%d found %d,%d\n", __FILE__, __LINE__, x, y);
|
|
|
|
|
fd_pos.x = x;
|
|
|
|
|
fd_pos.y = y;
|
|
|
|
|
rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
|
|
|
|
|
fd_pos = NextPos(fd_pos, rpos->dir);
|
|
|
|
|
fd_pos.parma++;
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found == 0) {
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
// if block is off ignore it completly
|
|
|
|
|
else if (rpos->type == RAILWAY_BLOCK) {
|
|
|
|
|
printf ("%s:%d block found\n", __FILE__, __LINE__);
|
|
|
|
|
if (server->blocks.IsOff(rpos->name)) {
|
|
|
|
|
printf ("%s:%d block is off\n", __FILE__, __LINE__);
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// lockedby = server->blocks.GetLockedby(rpos->name);
|
|
|
|
|
fd_pos = NextPos(fd_pos, rpos->dir);
|
|
|
|
|
fd_pos.parma++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else { // finished
|
|
|
|
|
printf ("%s:%d finished?\n", __FILE__, __LINE__);
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
fd_pos.y = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
|
|
|
|
|
}
|
|
|
|
|
if (found == 0) *next = "";
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
free (fd_data);
|
|
|
|
|
|
|
|
|
|
return found;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|