/* Pair : row,column */ int lee_algo(Pair* source, Pair* target){ int i, j, v1, v2; Pair p, v, step[4] = {{1,0},{0,1},{-1,0},{0,-1}}; /* initialize all cells like unvisited */ for(i=0; i<sz.r; ++i){ for(j=0; j<sz.c; ++j){ W[i][j] = -1; } } q_clear(); p_set(W,source,0); q_push(source); while(!q_empty()){ p = q_pop(); for(i=0; i<4; ++i){ v = p_sum(step+i,&p); v1 = p_get(Z,&p); v2 = p_get(Z,&v); #ifdef DEBUG printf("try: %d,%d\n",v.r,v.c); #endif if(p_in(&v) && p_get(W,&v)==-1 && (v1-v2 <= 3) && (v1-v2 >= -1) && can_go(&v)){ #ifdef DEBUG printf("from: %d,%d go: %d,%d\n",p.r,p.c,v.r,v.c); #endif p_set(W,&v,p_get(W,&p)+1); q_push(&v); if(p_eq(&v,target)) break; } } if(p_eq(&v,target)) break; } #ifdef DEBUG printf("q: %d\n",q_empty()); #endif return p_get(W,target); }
int hadlock_algo(Pair* source, Pair* target){ int i, j, v1, v2, res; Pair p, v, step[4] = {{1,0},{0,1},{-1,0},{0,-1}}; /* initialize all cells like unvisited */ for(i=0; i<sz.r; ++i){ for(j=0; j<sz.c; ++j){ W[i][j] = -1; } } q_clear(); p_set(W,source,0); q_push(source); while(!q_empty()){ p = q_pop(); for(i=0; i<4; ++i){ v = p_sum(step+i,&p); v1 = p_get(Z,&p); v2 = p_get(Z,&v); if(p_in(&v) && (p_get(W,&v)==-1 || (p_get(W,&v)>p_get(W,&p))) && (v1-v2 <= 3) && (v1-v2 >= -1) && can_go(&v)){ if(p_mhtn_norm(&v,target) < p_mhtn_norm(&p,target)){ p_set(W,&v,p_get(W,&p)); q_push_back(&v); }else{ /* > */ /*if(!(p_get(W,&v)!=-1 || (p_get(W,&v)==p_get(W,&p)+1))){ */ p_set(W,&v,p_get(W,&p)+1); q_push_front(&v); } if(p_eq(&v,target)){ break; } } } if(p_eq(&v,target)) break; } res = p_get(W,target); if(res != -1) res = 2*res+p_mhtn_norm(source,target); return res; }
int can_go(Pair* p){ Pair *b = bts; Pair s, t, md, mv, mh, next, buf1, buf2, buf3; int v, h, ver, hor; /* coordinate steps */ double val; int vis; while(b != bts+2){ ln_init(b,p_get(Z,b)+0.5,p,p_get(Z,p)+0.5); /* go from the bottom up */ if(p_get(Z,p) < p_get(Z,b)){ s = *p; t = *b; }else{ s = *b; t = *p; } hor = (s.c > t.c) ? -1 : 1; ver = (s.r > t.r) ? -1 : 1; #ifdef DEBUG printf("v: %d, h: %d\n",ver,hor); #endif h = (hor>0) ? 0 : 1; v = (ver>0) ? 0 : 1; vis = 1; while(!p_eq(&s,&t)){ md = p_new(ver,hor); md = p_sum(&s,&md); buf1 = p_new(md.r+v,md.c+h); if(ln_rc_val(&buf1)==0){ val = ln_z_by_r(buf1.r); next = md; }else{ mv = p_new(ver,0); mv = p_sum(&s,&mv); buf2 = p_new(mv.r+v,mv.c+h); if(!ln_rc_on_same_side(&buf1,&buf2)){ val = ln_z_by_r(buf2.r); next = mv; }else{ mh = p_new(0,hor); mh = p_sum(&s,&mh); buf3 = p_new(mh.r+v,mh.c+h); val = ln_z_by_c(buf3.c); next = mh; } } #ifdef DEBUG printf("next %d,%d\n",next.r,next.c); #endif if(p_get(Z,&next) > val){ #ifdef DEBUG printf("bad p: %d,%d val: %f\n",next.r,next.c,val); #endif vis = 0; break; } s = next; } if(vis) break; ++b; /* take next bts */ } return vis; }
static void tracecolor (int xstart, int ystart, int xend, int yend, register int x, register int y) { int dir = RIGHT, fill = 0; register unsigned char *calc; int peri = 0; cpixeldata_t c = (cpixeldata_t) calculatepixel (x, y, 0); cpixeldata_t w = (cpixeldata_t) 0; cpixeldata_t inset = (cpixeldata_t) cpalette.pixels[0]; putpixel (x, y, c); calc = calculated + x + y * CALCWIDTH; *calc = (unsigned char) 1; while (x > xstart && getpixel (x - 1, y) == c) x--, calc--; *calc = (unsigned char) 2; if (c == inset) peri = 1; do { if (!fill && !*calc) { *calc = (unsigned char) 1; putpixel (x, y, c); } switch (dir) { case RIGHT: if (y > ystart) { if (!*(calc - CALCWIDTH)) { w = (cpixeldata_t) calculatepixel (x, y - 1, peri); putpixel (x, y - 1, w); *(calc - CALCWIDTH) = (unsigned char) 1; } else w = getpixel (x, y - 1); if (w == c) { dir = UP; calc -= CALCWIDTH; y--; break; } } if (x < xend) { if (!*(calc + 1)) { w = (cpixeldata_t) calculatepixel (x + 1, y, peri); putpixel (x + 1, y, w); *(calc + 1) = (unsigned char) 1; } else w = getpixel (x + 1, y); if (w == c) { calc++; x++; break; } } if (y < yend) { if (!*(calc + CALCWIDTH)) { w = (cpixeldata_t) calculatepixel (x, y + 1, peri); putpixel (x, y + 1, w); *(calc + CALCWIDTH) = (unsigned char) 1; } else w = getpixel (x, y + 1); if (w == c) { dir = DOWN; calc += CALCWIDTH; y++; break; } } if (*calc == (unsigned char) 2) { *calc = (unsigned char) 1; return; } dir = LEFT; x--; calc--; break; case LEFT: if (y < yend) { if (!*(calc + CALCWIDTH)) { w = (cpixeldata_t) calculatepixel (x, y + 1, peri); putpixel (x, y + 1, w); *(calc + CALCWIDTH) = (unsigned char) 1; } else w = getpixel (x, y + 1); if (w == c) { dir = DOWN; calc += CALCWIDTH; y++; break; } } if (x > xstart) { if (!*(calc - 1)) { w = (cpixeldata_t) calculatepixel (x - 1, y, peri); putpixel (x - 1, y, w); *(calc - 1) = (unsigned char) 1; } else w = getpixel (x - 1, y); if (w == c) { calc--; x--; break; } } if (y > ystart) { if (!*(calc - CALCWIDTH)) { w = (cpixeldata_t) calculatepixel (x, y - 1, peri); putpixel (x, y - 1, w); *(calc - CALCWIDTH) = (unsigned char) 1; } else w = getpixel (x, y - 1); if (w == c) { dir = UP; calc -= CALCWIDTH; y--; break; } } dir = RIGHT; x++; calc++; break; case UP: if (fill) { unsigned char *calc1; cpixel_t *pixel1; calc1 = calc + 1; pixel1 = p_add ((cpixel_t *) cimage.currlines[y], x + 1); while (pixel1 <= p_add ((cpixel_t *) cimage.currlines[y], xend)) { if (!*calc1) *calc1 = (unsigned char) 1, p_set (pixel1, c); else if (p_get (pixel1) != c) break; p_inc (pixel1, 1); calc1++; } } if (x > xstart) { if (!*(calc - 1)) { w = (cpixeldata_t) calculatepixel (x - 1, y, peri); putpixel (x - 1, y, w); *(calc - 1) = (unsigned char) 1; } w = getpixel (x - 1, y); if (w == c) { dir = LEFT; calc--; x--; break; } } if (y > ystart) { if (!*(calc - CALCWIDTH)) { w = (cpixeldata_t) calculatepixel (x, y - 1, peri); putpixel (x, y - 1, w); *(calc - CALCWIDTH) = (unsigned char) 1; } w = getpixel (x, y - 1); if (w == c) { calc -= CALCWIDTH; y--; break; } } if (x < xend) { if (!*(calc + 1)) { w = (cpixeldata_t) calculatepixel (x + 1, y, peri); putpixel (x + 1, y, w); *(calc + 1) = (unsigned char) 1; } else w = getpixel (x + 1, y); if (w == c) { dir = RIGHT; calc++; x++; break; } } dir = DOWN; y++; calc += CALCWIDTH; break; case DOWN: if (x < xend) { if (!*(calc + 1)) { w = (cpixeldata_t) calculatepixel (x + 1, y, peri); putpixel (x + 1, y, w); *(calc + 1) = (unsigned char) 1; } else w = getpixel (x + 1, y); if (w == c) { dir = RIGHT; calc++; x++; break; } } if (y < yend) { if (!*(calc + CALCWIDTH)) { w = (cpixeldata_t) calculatepixel (x, y + 1, peri); putpixel (x, y + 1, w); *(calc + CALCWIDTH) = (unsigned char) 1; } else w = getpixel (x, y + 1); if (w == c) { dir = DOWN; calc += CALCWIDTH; y++; break; } } if (x > xstart) { if (!*(calc - 1)) { w = (cpixeldata_t) calculatepixel (x - 1, y, peri); putpixel (x - 1, y, w); *(calc - 1) = (unsigned char) 1; } else w = getpixel (x - 1, y); if (w == c) { dir = LEFT; calc--; x--; break; } } dir = UP; calc -= CALCWIDTH; y--; break; } if (*calc == (unsigned char) 2) { if (fill) { *calc = (unsigned char) 1; return; } fill = 1; dir = RIGHT; } } while (1); }