/* * Rebalance a tree, starting at p and up. * F == 0 means we've come from p's left child. * D == 1 means we've just done a delete, otherwise an insert. */ static void balance(struct varent *p, int f, int d) { struct varent *pp; #ifndef lint struct varent *t; /* used by the rotate macros */ #endif /* !lint */ int ff; #ifdef lint ff = 0; /* Sun's lint is dumb! */ #endif /* * Ok, from here on, p is the node we're operating on; pp is it's parent; f * is the branch of p from which we have come; ff is the branch of pp which * is p. */ for (; (pp = p->v_parent) != 0; p = pp, f = ff) { ff = pp->v_right == p; if (f ^ d) { /* right heavy */ switch (p->v_bal) { case -1: /* was left heavy */ p->v_bal = 0; break; case 0: /* was balanced */ p->v_bal = 1; break; case 1: /* was already right heavy */ switch (p->v_right->v_bal) { case 1: /* single rotate */ pp->v_link[ff] = rleft(p); p->v_left->v_bal = 0; p->v_bal = 0; break; case 0: /* single rotate */ pp->v_link[ff] = rleft(p); p->v_left->v_bal = 1; p->v_bal = -1; break; case -1: /* double rotate */ (void) rright(p->v_right); pp->v_link[ff] = rleft(p); p->v_left->v_bal = p->v_bal < 1 ? 0 : -1; p->v_right->v_bal = p->v_bal > -1 ? 0 : 1; p->v_bal = 0; break; default: break; } break; default: break; } } else { /* left heavy */ switch (p->v_bal) { case 1: /* was right heavy */ p->v_bal = 0; break; case 0: /* was balanced */ p->v_bal = -1; break; case -1: /* was already left heavy */ switch (p->v_left->v_bal) { case -1: /* single rotate */ pp->v_link[ff] = rright(p); p->v_right->v_bal = 0; p->v_bal = 0; break; case 0: /* single rotate */ pp->v_link[ff] = rright(p); p->v_right->v_bal = -1; p->v_bal = 1; break; case 1: /* double rotate */ (void) rleft(p->v_left); pp->v_link[ff] = rright(p); p->v_left->v_bal = p->v_bal < 1 ? 0 : -1; p->v_right->v_bal = p->v_bal > -1 ? 0 : 1; p->v_bal = 0; break; default: break; } break; default: break; } } /* * If from insert, then we terminate when p is balanced. If from * delete, then we terminate when p is unbalanced. */ if ((p->v_bal == 0) ^ d) break; } }
int play(void) { int i; Mouse om; int s; Rune r; Alt alts[NALT+1]; alts[TIMER].c = timerc; alts[TIMER].v = nil; alts[TIMER].op = CHANRCV; alts[MOUSE].c = mousec; alts[MOUSE].v = &mouse; alts[MOUSE].op = CHANRCV; alts[SUSPEND].c = suspc; alts[SUSPEND].v = &s; alts[SUSPEND].op = CHANRCV; alts[RESHAPE].c = mousectl->resizec; alts[RESHAPE].v = nil; alts[RESHAPE].op = CHANRCV; alts[KBD].c = kbdc; alts[KBD].v = &r; alts[KBD].op = CHANRCV; alts[NALT].op = CHANEND; dt = 64; lastmx = -1; lastmx = movemouse(); choosepiece(); lastmx = warp(mouse.xy, lastmx); for(;;) switch(alt(alts)) { case MOUSE: if(suspended) { om = mouse; break; } if(lastmx < 0) lastmx = mouse.xy.x; if(mouse.xy.x > lastmx+DMOUSE) { mright(); lastmx = mouse.xy.x; } if(mouse.xy.x < lastmx-DMOUSE) { mleft(); lastmx = mouse.xy.x; } if(mouse.buttons&1 && !(om.buttons&1)) rleft(); if(mouse.buttons&2 && !(om.buttons&2)) if(drop(1)) return 1; if(mouse.buttons&4 && !(om.buttons&4)) rright(); om = mouse; break; case SUSPEND: if (!suspended && s) suspend(1); else if (suspended && !s) { suspend(0); lastmx = warp(mouse.xy, lastmx); } break; case RESHAPE: redraw(1); break; case KBD: if(suspended) break; switch(r) { case 'f': case ';': mright(); break; case 'a': case 'j': mleft(); break; case 'd': case 'l': rright(); break; case 's': case 'k': rleft(); break; case ' ': if(drop(1)) return 1; break; } break; case TIMER: if(suspended) break; dt -= tsleep; if(dt < 0) { i = 1; dt = 16 * (points+nrand(10000)-5000) / 10000; if(dt >= 32) { i += (dt-32)/16; dt = 32; } dt = 52-dt; while(i-- > 0) if(movepiece()==0 && ++fusst==40) { if(drop(0)) return 1; break; } } break; } }