/** * 移動範囲検索. */ void MapManager::findDist(int x, int y, int dist, bool first) { assert(vaildateInit()); // 初期位置は移動対象外とする制御 if (!first) { // 移動可能範囲に追加 addDistCursor(x, y, dist); } if (dist == 0) { return; } // 上にいけるか? if (y > map_data_.map_data_setting.top && chkMove(x, y - 1, dist)) { findDist(x, y - 1, dist - 1, false); } // 下にいけるか? if (y < (map_data_.map_data_setting.bottom - 1) && chkMove(x, y + 1, dist)) { findDist(x, y + 1, dist - 1, false); } // 左にいけるか? if (x > map_data_.map_data_setting.left && chkMove(x - 1, y, dist)) { findDist(x - 1, y, dist - 1, false); } // 右にいけるか? if (x < (map_data_.map_data_setting.right - 1) && chkMove(x + 1, y, dist)) { findDist(x + 1, y, dist - 1, false); } }
/* the real thing */ int delta(char* src, long n_src, char* tar, long n_tar, int delfd) { register char *sp, *tp, *esrc, *etar; register long size, addr; Suftree *tree; Move *moves, *last; char inst, buf[BUFSIZE]; /* initialize the output area */ delinit(buf,delfd); /* output file sizes */ inst = DELTA_TYPE | ((NBYTE(n_src)&07) << 3) | (NBYTE(n_tar)&07); if(delputc(inst) < 0) return -1; if(delputl(NBYTE(n_src),n_src) < 0 || delputl(NBYTE(n_tar),n_tar) < 0) return -1; /* bases */ Bsrc = src; Btar = tar; esrc = src + n_src - 1; etar = tar + n_tar - 1; /* initialize list and last block */ moves = 0; last = 0; /* try making suffix tree */ if(!(tree = n_tar > 0 ? bldsuftree(src,n_src) : (Suftree*)0)) { /* not enough space for tree, remove matching prefix and suffix */ for(; src <= esrc && tar <= etar; ++src, ++tar) if(*src != *tar) break; if((size = src-Bsrc) > 0) { register int cost_m, cost_a; cost_m = NBYTE(size) + NBYTE(0); cost_a = NBYTE(size) + size; if(cost_m < cost_a) { moves = newMove(DELTA_MOVE,size,0L,NiL); if(!moves) return -1; n_src -= src-Bsrc; n_tar -= tar-Btar; } else { src = Bsrc; tar = Btar; } } for(sp = esrc, tp = etar; sp >= src && tp >= tar; --sp, --tp) if(*sp != *tp) break; if((size = esrc-sp) > 0) { addr = sp+1-Bsrc; if(chkMove(size,addr,0L) > 0) { last = newMove(DELTA_MOVE,size,addr,NiL); if(!last) return -1; esrc = sp; etar = tp; n_tar = etar-tar+1; n_src = esrc-src+1; } } /* try making the tree again */ tree = n_tar > 0 ? bldsuftree(src,n_src) : (Suftree*)0; } /* compute block moves */ tp = 0; while(n_tar > 0) { char *match; if(tree) size = mtchsuftree(tree,tar,n_tar,&match); else size = mtchstring(src,n_src,tar,n_tar,&match); if(size < 0) return -1; if(size > 0) size = chkMove(size,(long)(match-Bsrc),(long)(tp ? tp-tar : 0)); /* output a block move */ if(size > 0) { if(tp) { moves = makeAdd(tp,tar,moves); if(!moves) return -1; tp = 0; } moves = newMove(DELTA_MOVE,size,(long)(match-Bsrc),moves); if(!moves) return -1; tar += size; n_tar -= size; } else { if(!tp) tp = tar; tar += 1; n_tar -= 1; } } /* add any remaining blocks */ if(tp) { if(last && chkMove(last->size,last->addr,(long)(tar-tp)) <= 0) { tar += last->size; last = delMove(last); } moves = makeAdd(tp,tar,moves); if(!moves) return -1; } if(last) { moves->next = last; last->last = moves; } /* release space use for string matching */ if(tree) delsuftree(tree); else mtchstring(NiL,0L,NiL,0L,NiL); /* optimize move instructions */ if(moves) { register Move *ip; ip = moves; while(ip->last) ip = ip->last; for(; ip; ip = ip->next) if(ip->type == DELTA_MOVE && ip->size <= (M_MAX+A_MAX)) moves = ip = optMove(ip); while(moves->last) moves = moves->last; } /* write out the move instructions */ addr = 0L; while(moves) { if(moves->type == DELTA_ADD) moves->addr = addr; addr += moves->size; if(putMove(moves) < 0) return -1; moves = delMove(moves); } /* write ending token */ delputc((char)DELTA_TYPE); /* flush buffer */ return delflush(); }