void Surface_mesh:: garbage_collection() { if (!garbage_) return; int i, i0, i1, nV(vertices_size()), nE(edges_size()), nH(halfedges_size()), nF(faces_size()); Vertex v; Halfedge h; Face f; if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false); if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false); if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false); // setup handle mapping Vertex_property<Vertex> vmap = add_vertex_property<Vertex>("v:garbage-collection"); Halfedge_property<Halfedge> hmap = add_halfedge_property<Halfedge>("h:garbage-collection"); Face_property<Face> fmap = add_face_property<Face>("f:garbage-collection"); for (i=0; i<nV; ++i) vmap[Vertex(i)] = Vertex(i); for (i=0; i<nH; ++i) hmap[Halfedge(i)] = Halfedge(i); for (i=0; i<nF; ++i) fmap[Face(i)] = Face(i); // remove deleted vertices if (nV > 0) { i0=0; i1=nV-1; while (1) { // find first deleted and last un-deleted while (!vdeleted_[Vertex(i0)] && i0 < i1) ++i0; while ( vdeleted_[Vertex(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap vprops_.swap(i0, i1); //add for(unsigned int j = 0;j<map_2skel.size();j++) { if(map_2skel[j] == i0) map_2skel[j] = i1; else if(map_2skel[j] == i1) map_2skel[j] = i0; } //end }; // remember new size nV = vdeleted_[Vertex(i0)] ? i0 : i0+1; } // remove deleted edges if (nE > 0) { i0=0; i1=nE-1; while (1) { // find first deleted and last un-deleted while (!edeleted_[Edge(i0)] && i0 < i1) ++i0; while ( edeleted_[Edge(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap eprops_.swap(i0, i1); hprops_.swap(2*i0, 2*i1); hprops_.swap(2*i0+1, 2*i1+1); }; // remember new size nE = edeleted_[Edge(i0)] ? i0 : i0+1; nH = 2*nE; } // remove deleted faces if (nF > 0) { i0=0; i1=nF-1; while (1) { // find 1st deleted and last un-deleted while (!fdeleted_[Face(i0)] && i0 < i1) ++i0; while ( fdeleted_[Face(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap fprops_.swap(i0, i1); }; // remember new size nF = fdeleted_[Face(i0)] ? i0 : i0+1; } // update vertex connectivity for (i=0; i<nV; ++i) { v = Vertex(i); if (!is_isolated(v)) set_halfedge(v, hmap[halfedge(v)]); } // update halfedge connectivity for (i=0; i<nH; ++i) { h = Halfedge(i); set_vertex(h, vmap[to_vertex(h)]); set_next_halfedge(h, hmap[next_halfedge(h)]); if (!is_boundary(h)) set_face(h, fmap[face(h)]); } // update handles of faces for (i=0; i<nF; ++i) { f = Face(i); set_halfedge(f, hmap[halfedge(f)]); } // remove handle maps remove_vertex_property(vmap); remove_halfedge_property(hmap); remove_face_property(fmap); // finally resize arrays vprops_.resize(nV); vprops_.free_memory(); hprops_.resize(nH); hprops_.free_memory(); eprops_.resize(nE); eprops_.free_memory(); fprops_.resize(nF); fprops_.free_memory(); deleted_vertices_ = deleted_edges_ = deleted_faces_ = 0; garbage_ = false; }
void moveall() /* move all comp ships */ { struct ship *sp, *sq; /* r11, r10 */ int n; /* r9 */ int k, l; /* r8, r7 */ int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; char moved[NSHIP]; /* * first try to create moves for OUR ships */ foreachship(sp) { struct ship *closest; int ma, ta; char af; if (sp->file->captain[0] || sp->file->dir == 0) continue; if (!sp->file->struck && windspeed && !snagged(sp) && sp->specs->crew3) { ta = maxturns(sp, &af); ma = maxmove(sp, sp->file->dir, 0); closest = closestenemy(sp, 0, 0); if (closest == 0) *sp->file->movebuf = '\0'; else closeon(sp, closest, sp->file->movebuf, sizeof sp->file->movebuf, ta, ma, af); } else *sp->file->movebuf = '\0'; } /* * Then execute the moves for ALL ships (dead ones too), * checking for collisions and snags at each step. * The old positions are saved in row[], col[], dir[]. * At the end, we compare and write out the changes. */ n = 0; foreachship(sp) { if (snagged(sp)) (void) strlcpy(sp->file->movebuf, "d", sizeof sp->file->movebuf); else if (*sp->file->movebuf != 'd') (void) strlcat(sp->file->movebuf, "d", sizeof sp->file->movebuf); row[n] = sp->file->row; col[n] = sp->file->col; dir[n] = sp->file->dir; drift[n] = sp->file->drift; moved[n] = 0; n++; } /* * Now resolve collisions. * This is the tough part. */ for (k = 0; stillmoving(k); k++) { /* * Step once. * And propagate the nulls at the end of sp->file->movebuf. */ n = 0; foreachship(sp) { if (!sp->file->movebuf[k]) sp->file->movebuf[k+1] = '\0'; else if (sp->file->dir) step(sp->file->movebuf[k], sp, &moved[n]); n++; } /* * The real stuff. */ n = 0; foreachship(sp) { if (sp->file->dir == 0 || is_isolated(sp)) goto cont1; l = 0; foreachship(sq) { char snap = 0; if (sp == sq) goto cont2; if (sq->file->dir == 0) goto cont2; if (!push(sp, sq)) goto cont2; if (snagged2(sp, sq) && range(sp, sq) > 1) snap++; if (!range(sp, sq) && !fouled2(sp, sq)) { makesignal(sp, "collision with $$", sq); if (die() < 4) { makesignal(sp, "fouled with $$", sq); Write(W_FOUL, sp, l, 0, 0, 0); Write(W_FOUL, sq, n, 0, 0, 0); } snap++; } if (snap) { sp->file->movebuf[k + 1] = 0; sq->file->movebuf[k + 1] = 0; sq->file->row = sp->file->row - 1; if (sp->file->dir == 1 || sp->file->dir == 5) sq->file->col = sp->file->col - 1; else sq->file->col = sp->file->col; sq->file->dir = sp->file->dir; } cont2: l++; } cont1: n++; } } /* * Clear old moves. And write out new pos. */ n = 0; foreachship(sp) { if (sp->file->dir != 0) { *sp->file->movebuf = 0; if (row[n] != sp->file->row) Write(W_ROW, sp, sp->file->row, 0, 0, 0); if (col[n] != sp->file->col) Write(W_COL, sp, sp->file->col, 0, 0, 0); if (dir[n] != sp->file->dir) Write(W_DIR, sp, sp->file->dir, 0, 0, 0); if (drift[n] != sp->file->drift) Write(W_DRIFT, sp, sp->file->drift, 0, 0, 0); } n++; } }