/** * Balances red black trees. * @param t tree to balance. * @return balanced tree. */ static tree tree_fix(tree t) { if(IS_RED(t->left) && IS_RED(t->left->left)){ if(IS_RED(t->right)){ /*colour root red and children a,b black*/ t->colour = RED; t->left->colour = BLACK; t->right->colour = BLACK; }else if(IS_BLACK(t->right)){ /*right rotate root , colour new root (a) black, * and new child(old root) red*/ t = right_rotate(t); t->colour = BLACK; t->right->colour = RED;/*old root*/ } }else if(IS_RED(t->left) && IS_RED(t->left->right)){ if(IS_RED(t->right)){ /*colour root red and children a,b black*/ t->colour = RED; t->left->colour = BLACK; t->right->colour = BLACK; } else if(IS_BLACK(t->right)){ /* Left rotate left child (a), right rotate root (r), * colour new root (d) black and new child (R) red */ t->left = left_rotate(t->left); t = right_rotate(t); t->colour = BLACK; t->right->colour = RED;/* old root */ } }else if(IS_RED(t->right) && IS_RED(t->right->left)){ if(IS_RED(t->left)){ /* Colour root (R) red and children (a,b) black*/ t->colour = RED; t->left->colour = BLACK; t->right->colour = BLACK; }else if(IS_BLACK(t->left)){ /* Right rotate right child(b),left rotate root(r), * colour new root (e) black and new child (r) red */ t->right = right_rotate(t->right); t = left_rotate(t); t->colour = BLACK; t->left->colour = RED;/* old root */ } }else if(IS_RED(t->right) && IS_RED(t->right->right)){ if(IS_RED(t->left)){ /* Colour root (R) red and children (A,B) black */ t->colour = RED; t->left->colour = BLACK; t->right->colour = BLACK; } else if(IS_BLACK(t->left)){ /* Left rotate root R, colour new root b black and new child R red */ t = left_rotate(t); t->colour = BLACK; t->left->colour = RED;/*old root*/ } } return t; }
static void __traverse(node_t *n, int d, int _nrb) { int i; if ( n == NULL ) { if ( nrb == -1 ) nrb = _nrb; if ( nrb != _nrb ) printf("Imbalance at depth %d (%d,%d)\n", d, nrb, _nrb); return; } if ( IS_LEAF(n) && (n->k != 0) ) { assert(n->l == NULL); assert(n->r == NULL); assert(IS_BLACK(n->v)); } if ( !IS_LEAF(n) && IS_RED(n->v) ) { assert(IS_BLACK(n->l->v)); assert(IS_BLACK(n->r->v)); } if ( IS_BLACK(n->v) ) _nrb++; __traverse(n->l, d+1, _nrb); if ( valll > n->k ) bug=1; #if 0 for ( i = 0; i < d; i++ ) printf(" "); printf("%c%p K: %5d V: %p P: %p L: %p R: %p depth: %d\n", IS_BLACK(n->v) ? 'B' : 'R', n, n->k, n->v, n->p, n->l, n->r, d); #endif valll = n->k; __traverse(n->r, d+1, _nrb); }
static rbt rbt_fix(rbt r) { if(IS_RED(r->left) && IS_RED(r->left->left)){ if(IS_RED(r->right)){ /*colour root red and children a,b black*/ r->colour = RED; r->left->colour = BLACK; r->right->colour = BLACK; }else if(IS_BLACK(r->right)){ /*right rotate root , colour new root (a) black, and new child(old root) red*/ r = right_rotate(r); r->colour = BLACK; r->right->colour = RED;/*old root?*/ } }else if(IS_RED(r->left) && IS_RED(r->left->right)){ if(IS_RED(r->right)){ /*colour root red and children a,b black*/ r->colour = RED; r->left->colour = BLACK; r->right->colour = BLACK; } else if(IS_BLACK(r->right)){ /*left rotate left child (a), right rotate root (r),colour new root (d) black and new child (R) red*/ r->left = left_rotate(r->left); r = right_rotate(r); r->colour = BLACK; r->right->colour = RED;/*old root?*/ } }else if(IS_RED(r->right) && IS_RED(r->right->left)){ if(IS_RED(r->left)){ /* colour root (R) red and children (a,b) black*/ r->colour = RED; r->left->colour = BLACK; r->right->colour = BLACK; }else if(IS_BLACK(r->left)){ /*right rotate right child(b),left rotate root(r),colour new root (e) black and new child (r) red*/ r->right = right_rotate(r->right); r = left_rotate(r); r->colour = BLACK; r->left->colour = RED;/*old root?*/ } }else if(IS_RED(r->right) && IS_RED(r->right->right)){ if(IS_RED(r->left)){ /*colour root (R) red and children (A,B) black*/ r->colour = RED; r->left->colour = BLACK; r->right->colour = BLACK; } else if(IS_BLACK(r->left)){ /*left rotate root R, colour new root b black and new child R red*/ r = left_rotate(r); r->colour = BLACK; r->left->colour = RED;/*old root?*/ } } return r; }
UWord erts_bfalc_test(UWord op, UWord a1, UWord a2) { switch (op) { case 0x200: return (UWord) ((BFAllctr_t *) a1)->address_order; /* IS_AOBF */ case 0x201: return (UWord) ((BFAllctr_t *) a1)->mbc_root; case 0x202: return (UWord) ((RBTree_t *) a1)->parent; case 0x203: return (UWord) ((RBTree_t *) a1)->left; case 0x204: return (UWord) ((RBTree_t *) a1)->right; case 0x205: return (UWord) LIST_NEXT(a1); case 0x206: return (UWord) IS_BLACK((RBTree_t *) a1); case 0x207: return (UWord) IS_TREE_NODE((RBTree_t *) a1); case 0x208: return (UWord) 1; /* IS_BF_ALGO */ case 0x20a: return (UWord) !((BFAllctr_t *) a1)->address_order; /* IS_BF */ case 0x20b: return (UWord) LIST_PREV(a1); default: ASSERT(0); return ~((UWord) 0); } }
bool View_Board::eventFilter(QObject *target, QEvent *event) { if (event->type() == QEvent::MouseButtonPress && read_flag) { QMouseEvent *mouseEvent = (QMouseEvent*)event; int x = (mouseEvent->pos().x() - 44) / 44, y = (mouseEvent->pos().y() - 44) / 44; FIGURE f = board->gcell(x, y); if (ready == 0) { qDebug() << "if (ready == 0) ..."; result.from.x = x; result.from.y = y; if (0 || (color == WHITE && !IS_WHITE(f)) || (color == BLACK && !IS_BLACK(f)) ) return true; ready = 1; qDebug() << "ready = 1;"; return true; } else if (ready == 1) { qDebug() << "if (ready == 1) ..."; result.to.x = x; result.to.y = y; if (!board->canMove(result)) { result.from.x = x; result.from.y = y; if (0 || (color == WHITE && !IS_WHITE(f)) || (color == BLACK && !IS_BLACK(f)) ) { ready = 0; qDebug() << "ready = 0;"; return true; } ready = 1; qDebug() << "ready = 1;"; return true; } ready = 2; qDebug() << "ready = 2;"; read_flag = false; return true; } return true; } return false; };
static void bst_remove_at(bst *t, bstnode *n) { bstnode *p; /* n has two children */ if (!IS_LEAF(n->left) && !IS_LEAF(n->right)) { static int del_from_left = 1; long tmpkey; void *tmpdata; if (del_from_left) { p = n->left; while (!IS_LEAF(p->right)) p = p->right; } else { p = n->right; while (!IS_LEAF(p->left)) p = p->left; } /* swap key and data and remove swapped node (which has 0 or 1 child) */ tmpkey = p->key, p->key = n->key, n->key = tmpkey; tmpdata = p->data, p->data = n->data, n->data = tmpdata; bst_remove_at(t, p); return; } /* n has no/one child */ p = IS_LEAF(n->left) ? n->right : n->left; /* replace n with p */ p->parent = n->parent; if (n->parent) { if (IS_LEFT_CHILD(n)) n->parent->left = p; else n->parent->right = p; } else t->root = p; if (IS_BLACK(n)) { if (p->color == RED) p->color = BLACK; else bst_remove_repair(t, p); } free(n); return; }
void rb_check( qrb_tree *tree_p ) { if( tree_p->root == NULL ) return; if( ! IS_BLACK(tree_p->root) ){ fprintf(stderr,"OOPS rb_check: root node should be black!?\n"); return; } tree_p->root->depth=0; tree_p->root->black_depth=1; rb_node_scan(tree_p->root); }
static void pn_unmove (struct pan_node *pn) { struct xq_move * move; GtkTreeIter iter[1]; gint nth; int id; GList *last; if (pn->move_count <= 0) { return; } pn->move_count --; move = pn->moves + pn->move_count; pn->cur_pan[move->fromy][move->fromx] = pn->cur_pan[move->toy][move->tox]; pn->cur_pan[move->toy][move->tox] = move->dead; if (move->dead) { memcpy (pn->cur_fen->pan, pn->cur_pan, 10 * 9 * sizeof (char)); pn->cur_fen->half_count = 0; pn->cur_fen->is_redturn = IS_BLACK (move->dead); pn->cur_moves = NULL; for (id = pn->move_count - 1, move = pn->moves + pn->move_count - 1; id >= 0 && move->dead == 0; id --, move = pn->moves + id) { pn->cur_fen->pan[move->fromy][move->fromx] = pn->cur_fen->pan[move->toy][move->tox]; pn->cur_fen->pan[move->toy][move->tox] = move->dead; pn->cur_moves = g_list_prepend (pn->cur_moves, move); pn->cur_fen->is_redturn = IS_RED (pn->cur_fen->pan[move->fromy][move->fromx]); pn->cur_fen->half_count ++; } } else { pn->cur_fen->half_count --; last = g_list_last (pn->cur_moves); pn->cur_moves = g_list_remove_link (pn->cur_moves, last); } nth = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (pn->qipu_list), NULL); gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (pn->qipu_list), iter, NULL, nth - 1); gtk_list_store_remove (GTK_LIST_STORE (pn->qipu_list), iter); }
unsigned long erts_aoffalc_test(unsigned long op, unsigned long a1, unsigned long a2) { switch (op) { case 0x500: return (unsigned long) 0; /* IS_AOBF */ case 0x501: return (unsigned long) ((AOFFAllctr_t *) a1)->mbc_root; case 0x502: return (unsigned long) ((AOFF_RBTree_t *) a1)->parent; case 0x503: return (unsigned long) ((AOFF_RBTree_t *) a1)->left; case 0x504: return (unsigned long) ((AOFF_RBTree_t *) a1)->right; case 0x506: return (unsigned long) IS_BLACK((AOFF_RBTree_t *) a1); case 0x508: return (unsigned long) 1; /* IS_AOFF */ case 0x509: return (unsigned long) ((AOFF_RBTree_t *) a1)->max_sz; default: ASSERT(0); return ~((unsigned long) 0); } }
static void print_tree_aux(AOFF_RBTree_t *x, int indent) { int i; if (x) { print_tree_aux(x->right, indent + INDENT_STEP); for (i = 0; i < indent; i++) { putc(' ', stderr); } fprintf(stderr, "%s: sz=%lu addr=0x%lx max_size=%u\r\n", IS_BLACK(x) ? "BLACK" : "RED", AOFF_BLK_SZ(x), (Uint)x, (unsigned)x->max_sz); print_tree_aux(x->left, indent + INDENT_STEP); } }
void tree_delete(Node* &T, Node *x) { if (NIL == T || NIL == x) return; // y是要删除的节点 Node *y = NULL; if ((NIL == LEFT(x)) || (NIL == RIGHT(x))) y = x; else y = tree_successor(x); if (y != x) KEY(x) = KEY(y); // y肯定只有一个孩子 Node * z = (NIL != LEFT(y))? LEFT(y): RIGHT(y); // 即使z是NIL,也给挂上,否则会影响rb_delete_fixup PARENT(z) = PARENT(y); if (NIL == PARENT(y)) { // 根节点发生变化 T = z; } else if (IS_LEFT(y)){ LEFT(PARENT(y)) = z; } else { RIGHT(PARENT(y)) = z; } // 调整路径上节点的max值 Node *p = PARENT(z); while (NIL != p) { MAX(p) = max(MAX(LEFT(p)), MAX(RIGHT(p)), HIGH(KEY(p))); p = PARENT(p); } // 如果y是黑色,说明破坏红黑树的规则;如果y是红色,则不会破坏 if (IS_BLACK(y)) { rb_delete_fixup(T, z); } free_node(y); }
void tree_delete(Node* &T, Node *x) { if (NIL == T || NIL == x) return; // y是要删除的节点 Node *y = NULL; if ((NIL == LEFT(x)) || (NIL == RIGHT(x))) y = x; else y = tree_successor(x); if (y != x) KEY(x) = KEY(y); // y肯定只有一个孩子 Node * z = (NIL != LEFT(y))? LEFT(y): RIGHT(y); // 即使z是NIL,也给挂上,否则会影响rb_delete_fixup PARENT(z) = PARENT(y); if (NIL == PARENT(y)) { // 根节点发生变化 T = z; } else if (IS_LEFT(y)){ LEFT(PARENT(y)) = z; } else { RIGHT(PARENT(y)) = z; } // 沿着y节点向上,更新路径上每个节点的size Node *p = y; while (NIL != (p=PARENT(p))) { SIZE(p)--; } // 如果y是黑色,说明破坏红黑树的规则;如果y是红色,则不会破坏 if (IS_BLACK(y)) { rb_delete_fixup(T, z); } free_node(y); }
static void print_tree_aux(RBTree_t *x, int indent) { int i; if (!x) { for (i = 0; i < indent; i++) { putc(' ', stderr); } fprintf(stderr, "BLACK: nil\r\n"); } else { print_tree_aux(x->right, indent + INDENT_STEP); for (i = 0; i < indent; i++) { putc(' ', stderr); } fprintf(stderr, "%s: sz=%lu addr=0x%lx\r\n", IS_BLACK(x) ? "BLACK" : "RED", BF_BLK_SZ(x), (Uint) x); print_tree_aux(x->left, indent + INDENT_STEP); } }
UWord erts_aoffalc_test(UWord op, UWord a1, UWord a2) { switch (op) { case 0x500: return (UWord) ((AOFFAllctr_t *) a1)->blk_order == FF_AOBF; case 0x501: { AOFF_RBTree_t *node = ((AOFFAllctr_t *) a1)->mbc_root; Uint size = (Uint) a2; node = node ? rbt_search(node, size) : NULL; return (UWord) (node ? RBT_NODE_TO_MBC(node)->root : NULL); } case 0x502: return (UWord) ((AOFF_RBTree_t *) a1)->parent; case 0x503: return (UWord) ((AOFF_RBTree_t *) a1)->left; case 0x504: return (UWord) ((AOFF_RBTree_t *) a1)->right; case 0x505: return (UWord) LIST_NEXT(a1); case 0x506: return (UWord) IS_BLACK((AOFF_RBTree_t *) a1); case 0x507: return (UWord) IS_TREE_NODE((AOFF_RBTree_t *) a1); case 0x508: return (UWord) 0; /* IS_BF_ALGO */ case 0x509: return (UWord) ((AOFF_RBTree_t *) a1)->max_sz; case 0x50a: return (UWord) ((AOFFAllctr_t *) a1)->blk_order == FF_BF; case 0x50b: return (UWord) LIST_PREV(a1); default: ASSERT(0); return ~((UWord) 0); } }
static void rbt_delete(AOFF_RBTree_t** root, AOFF_RBTree_t* del) { Uint spliced_is_black; AOFF_RBTree_t *x, *y, *z = del; AOFF_RBTree_t null_x; /* null_x is used to get the fixup started when we splice out a node without children. */ HARD_CHECK_IS_MEMBER(*root, del); null_x.parent = NULL; /* Remove node from tree... */ /* Find node to splice out */ if (!z->left || !z->right) y = z; else /* Set y to z:s successor */ for(y = z->right; y->left; y = y->left); /* splice out y */ x = y->left ? y->left : y->right; spliced_is_black = IS_BLACK(y); if (x) { x->parent = y->parent; } else if (spliced_is_black) { x = &null_x; x->flags = 0; SET_BLACK(x); x->right = x->left = NULL; x->max_sz = 0; x->parent = y->parent; y->left = x; } if (!y->parent) { RBT_ASSERT(*root == y); *root = x; } else { if (y == y->parent->left) { y->parent->left = x; } else { RBT_ASSERT(y == y->parent->right); y->parent->right = x; } if (y->parent != z) { lower_max_size(y->parent, (y==z ? NULL : z)); } } if (y != z) { /* We spliced out the successor of z; replace z by the successor */ ASSERT(z != &null_x); replace(root, z, y); lower_max_size(y, NULL); } if (spliced_is_black) { /* We removed a black node which makes the resulting tree violate the Red-Black Tree properties. Fixup tree... */ while (IS_BLACK(x) && x->parent) { /* * x has an "extra black" which we move up the tree * until we reach the root or until we can get rid of it. * * y is the sibbling of x */ if (x == x->parent->left) { y = x->parent->right; RBT_ASSERT(y); if (IS_RED(y)) { RBT_ASSERT(y->right); RBT_ASSERT(y->left); SET_BLACK(y); RBT_ASSERT(IS_BLACK(x->parent)); SET_RED(x->parent); left_rotate(root, x->parent); y = x->parent->right; } RBT_ASSERT(y); RBT_ASSERT(IS_BLACK(y)); if (IS_BLACK(y->left) && IS_BLACK(y->right)) { SET_RED(y); x = x->parent; } else { if (IS_BLACK(y->right)) { SET_BLACK(y->left); SET_RED(y); right_rotate(root, y); y = x->parent->right; } RBT_ASSERT(y); if (IS_RED(x->parent)) { SET_BLACK(x->parent); SET_RED(y); } RBT_ASSERT(y->right); SET_BLACK(y->right); left_rotate(root, x->parent); x = *root; break; } } else { RBT_ASSERT(x == x->parent->right); y = x->parent->left; RBT_ASSERT(y); if (IS_RED(y)) { RBT_ASSERT(y->right); RBT_ASSERT(y->left); SET_BLACK(y); RBT_ASSERT(IS_BLACK(x->parent)); SET_RED(x->parent); right_rotate(root, x->parent); y = x->parent->left; } RBT_ASSERT(y); RBT_ASSERT(IS_BLACK(y)); if (IS_BLACK(y->right) && IS_BLACK(y->left)) { SET_RED(y); x = x->parent; } else { if (IS_BLACK(y->left)) { SET_BLACK(y->right); SET_RED(y); left_rotate(root, y); y = x->parent->left; } RBT_ASSERT(y); if (IS_RED(x->parent)) { SET_BLACK(x->parent); SET_RED(y); } RBT_ASSERT(y->left); SET_BLACK(y->left); right_rotate(root, x->parent); x = *root; break; } } } SET_BLACK(x); if (null_x.parent) { if (null_x.parent->left == &null_x) null_x.parent->left = NULL; else { RBT_ASSERT(null_x.parent->right == &null_x); null_x.parent->right = NULL; } RBT_ASSERT(!null_x.left); RBT_ASSERT(!null_x.right); } else if (*root == &null_x) { *root = NULL; RBT_ASSERT(!null_x.left); RBT_ASSERT(!null_x.right); } } }
static RBTree_t * check_tree(RBTree_t *root, int ao, Uint size) { RBTree_t *res = NULL; Sint blacks; Sint curr_blacks; RBTree_t *x; #ifdef PRINT_TREE print_tree(root, ao); #endif if (!root) return res; x = root; ASSERT(IS_BLACK(x)); ASSERT(!x->parent); curr_blacks = 1; blacks = -1; while (x) { if (!IS_LEFT_VISITED(x)) { SET_LEFT_VISITED(x); if (x->left) { x = x->left; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (!IS_RIGHT_VISITED(x)) { SET_RIGHT_VISITED(x); if (x->right) { x = x->right; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (IS_RED(x)) { ASSERT(IS_BLACK(x->right)); ASSERT(IS_BLACK(x->left)); } ASSERT(x->parent || x == root); if (x->left) { ASSERT(x->left->parent == x); if (ao) { ASSERT(BF_BLK_SZ(x->left) < BF_BLK_SZ(x) || (BF_BLK_SZ(x->left) == BF_BLK_SZ(x) && x->left < x)); } else { ASSERT(IS_TREE_NODE(x->left)); ASSERT(BF_BLK_SZ(x->left) < BF_BLK_SZ(x)); } } if (x->right) { ASSERT(x->right->parent == x); if (ao) { ASSERT(BF_BLK_SZ(x->right) > BF_BLK_SZ(x) || (BF_BLK_SZ(x->right) == BF_BLK_SZ(x) && x->right > x)); } else { ASSERT(IS_TREE_NODE(x->right)); ASSERT(BF_BLK_SZ(x->right) > BF_BLK_SZ(x)); } } if (size && BF_BLK_SZ(x) >= size) { if (ao) { if (!res || BF_BLK_SZ(x) < BF_BLK_SZ(res) || (BF_BLK_SZ(x) == BF_BLK_SZ(res) && x < res)) res = x; } else { if (!res || BF_BLK_SZ(x) < BF_BLK_SZ(res)) res = x; } } UNSET_LEFT_VISITED(x); UNSET_RIGHT_VISITED(x); if (IS_BLACK(x)) curr_blacks--; x = x->parent; } ASSERT(curr_blacks == 0); UNSET_LEFT_VISITED(root); UNSET_RIGHT_VISITED(root); return res; }
int main (int argc, char * argv[]) { parse_opts(argc,argv); if(!doInit()) { printf("Error Initializing Stuff.\n"); exit(EXIT_FAILURE); } else { //o calibrar colores o seguir la linea //bool rotate = true; double pval; bool stop = true; int left, right; while(!ag_psh_is_pushed(&push, &pval)); UDELAY(750000); printf("pval is: %.2f\n", pval); ag_lgt_set_led(&lright, true); ag_lgt_set_led(&lleft, true); if (mode) { //calibrar colores int i = 0; double acumr [calib], minr, maxr, upr, lowr; double acuml [calib], minl, maxl, upl, lowl; for (;i<calib;i++) { acumr[i] = (double)ag_read_int(&lright); acuml[i] = (double)ag_read_int(&lleft); UDELAY(100); } gsl_stats_minmax(&minr, &maxr, acumr, 1, calib); gsl_stats_minmax(&minl, &maxl, acuml, 1, calib); gsl_sort (acumr,1,calib); gsl_sort (acuml,1,calib); upl = gsl_stats_quantile_from_sorted_data (acuml,1,calib,0.95);//uq lowl = gsl_stats_quantile_from_sorted_data (acuml,1,calib,0.05);//lq upr = gsl_stats_quantile_from_sorted_data (acumr,1,calib,0.95);//uq lowr = gsl_stats_quantile_from_sorted_data (acumr,1,calib,0.05);//lq for (i = 0 ; i < 2; i++){ printf("COLOR: %s, SENSOR: %s\n", white ? "WHITE" : "BLACK", i == 0 ? "LEFT" : "RIGHT"); printf("min_v: %d, max_v: %d\n", i == 0 ? (int)minl : (int)minr, i == 0 ? (int)maxl : (int)maxr); printf("low_q: %d, up_q :%d\n", i == 0 ? (int)lowl : (int)lowr, i == 0 ? (int)upl : (int)upr); printf("\n"); } } else { //seguir linea while(!ag_psh_is_pushed(&push, &pval)) { //printf("pval is: %.2f\n", pval); if (stop){ stop = false; move_all(MY_FWD,vel); } right = ag_read_int(&lright); left = ag_read_int(&lleft); if(! IS_WHITE(right) || ! IS_WHITE(left)){ stop_all(); stop = true; if (IS_BLACK(left)){ rotate_robot(vel, true); while(IS_BLACK(ag_read_int(&lleft))); UDELAY(TDELAY); stop_all(); } else if (IS_BLACK(right)) { rotate_robot(vel, false); while(IS_BLACK(ag_read_int(&lright))); UDELAY(TDELAY); stop_all(); } } } } } lego_shutdown(); exit(EXIT_SUCCESS); }
int rbt_add(rbt_t *rbt, void *k, size_t klen, void *v) { int rc = 0; rbt_node_t *node = calloc(1, sizeof(rbt_node_t)); node->key = malloc(klen); memcpy(node->key, k, klen); node->klen = klen; node->value = v; if (!rbt->root) { PAINT_BLACK(node); rbt->root = node; } else { rc = _rbt_add_internal(rbt, rbt->root, node); if (IS_BLACK(node)) { // if the node just added is now black it means // it was already existing and this was only a value update if (!node->parent) { // we need to check also if the root pointer // should be updated as well rbt->root = node; } return 1; } if (!node->parent) { // case 1 PAINT_BLACK(node); rbt->root = node; } else if (IS_BLACK(node->parent)) { // case 2 return rc; } else { // case 3 rbt_node_t *uncle = rbt_uncle(node); rbt_node_t *grandparent = rbt_grandparent(node); if (IS_RED(uncle)) { PAINT_BLACK(node->parent); PAINT_BLACK(uncle); if (grandparent) { PAINT_RED(grandparent); rbt_add(rbt, grandparent->key, grandparent->klen, grandparent->value); } } else if (grandparent) { // case 4 if (node == node->parent->right && node->parent == grandparent->left) { rbt_rotate_left(rbt, node->parent); node = node->left; } else if (node == node->parent->left && node->parent == grandparent->right) { rbt_rotate_right(rbt, node->parent); node = node->right; } // case 5 grandparent = rbt_grandparent(node); if (node->parent) { PAINT_BLACK(node->parent); PAINT_RED(grandparent); if (node == node->parent->left) rbt_rotate_right(rbt, grandparent); else rbt_rotate_left(rbt, grandparent); } else { fprintf(stderr, "Corrupted tree\n"); return -1; } } } } return rc; }
static int is_valid_move( CHAR_DATA * ch, GAME_BOARD_DATA * board, int x, int y, int dx, int dy ) { if ( dx < 0 || dy < 0 || dx > 7 || dy > 7 ) return MOVE_OFFBOARD; if ( board->board[x][y] == NO_PIECE ) return MOVE_INVALID; if ( x == dx && y == dy ) return MOVE_INVALID; if ( IS_WHITE( board->board[x][y] ) && !str_cmp( board->player1, ch->name ) ) return MOVE_WRONGCOLOR; if ( IS_BLACK( board->board[x][y] ) && ( !str_cmp( board->player2, ch->name ) || !ch ) ) return MOVE_WRONGCOLOR; switch ( board->board[x][y] ) { case WHITE_PAWN: case BLACK_PAWN: if ( IS_WHITE( board->board[x][y] ) && dx == x + 2 && x == 1 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x + 1][dy] == NO_PIECE ) return MOVE_OK; else if ( IS_BLACK( board->board[x][y] ) && dx == x - 2 && x == 6 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x - 1][dy] == NO_PIECE ) return MOVE_OK; if ( IS_WHITE( board->board[x][y] ) && dx != x + 1 ) return MOVE_INVALID; else if ( IS_BLACK( board->board[x][y] ) && dx != x - 1 ) return MOVE_INVALID; if ( dy != y && dy != y - 1 && dy != y + 1 ) return MOVE_INVALID; if ( dy == y ) { if ( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; else if ( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; else return MOVE_BLOCKED; } else { if ( board->board[dx][dy] == NO_PIECE ) return MOVE_INVALID; else if ( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; else if ( board->board[dx][dy] != BLACK_KING && board->board[dx][dy] != WHITE_KING ) return MOVE_TAKEN; else return MOVE_INVALID; } break; case WHITE_ROOK: case BLACK_ROOK: { int cnt; if ( dx != x && dy != y ) return MOVE_INVALID; if ( dx == x ) { for ( cnt = y; cnt != dy; ) { if ( cnt != y && board->board[x][cnt] != NO_PIECE ) return MOVE_BLOCKED; if ( dy > y ) cnt++; else cnt--; } } else if ( dy == y ) { for ( cnt = x; cnt != dx; ) { if ( cnt != x && board->board[cnt][y] != NO_PIECE ) return MOVE_BLOCKED; if ( dx > x ) cnt++; else cnt--; } } if ( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if ( !SAME_COLOR( x, y, dx, dy ) ) return MOVE_TAKEN; return MOVE_SAMECOLOR; } break; case WHITE_KNIGHT: case BLACK_KNIGHT: if ( ( dx == x - 2 && dy == y - 1 ) || ( dx == x - 2 && dy == y + 1 ) || ( dx == x - 1 && dy == y - 2 ) || ( dx == x - 1 && dy == y + 2 ) || ( dx == x + 1 && dy == y - 2 ) || ( dx == x + 1 && dy == y + 2 ) || ( dx == x + 2 && dy == y - 1 ) || ( dx == x + 2 && dy == y + 1 ) ) { if ( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if ( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; return MOVE_TAKEN; } return MOVE_INVALID; break; case WHITE_BISHOP: case BLACK_BISHOP: { int l, m, blocked = FALSE; if ( dx == x || dy == y ) return MOVE_INVALID; l = x; m = y; while ( 1 ) { if ( dx > x ) l++; else l--; if ( dy > y ) m++; else m--; if ( l > 7 || m > 7 || l < 0 || m < 0 ) return MOVE_INVALID; if ( l == dx && m == dy ) break; if ( board->board[l][m] != NO_PIECE ) blocked = TRUE; } if ( l != dx || m != dy ) return MOVE_INVALID; if ( blocked ) return MOVE_BLOCKED; if ( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if ( !SAME_COLOR( x, y, dx, dy ) ) return MOVE_TAKEN; return MOVE_SAMECOLOR; } break; case WHITE_QUEEN: case BLACK_QUEEN: { int l, m, blocked = FALSE; l = x; m = y; while ( 1 ) { if ( dx > x ) l++; else if ( dx < x ) l--; if ( dy > y ) m++; else if ( dy < y ) m--; if ( l > 7 || m > 7 || l < 0 || m < 0 ) return MOVE_INVALID; if ( l == dx && m == dy ) break; if ( board->board[l][m] != NO_PIECE ) blocked = TRUE; } if ( l != dx || m != dy ) return MOVE_INVALID; if ( blocked ) return MOVE_BLOCKED; if ( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if ( !SAME_COLOR( x, y, dx, dy ) ) return MOVE_TAKEN; return MOVE_SAMECOLOR; } break; case WHITE_KING: case BLACK_KING: { int sp, sk; if ( dx > x + 1 || dx < x - 1 || dy > y + 1 || dy < y - 1 ) return MOVE_INVALID; sk = board->board[x][y]; sp = board->board[dx][dy]; board->board[x][y] = sp; board->board[dx][dy] = sk; if ( king_in_check( board, sk ) ) { board->board[x][y] = sk; board->board[dx][dy] = sp; return MOVE_CHECK; } board->board[x][y] = sk; board->board[dx][dy] = sp; if ( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if ( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; return MOVE_TAKEN; } break; default: bug( "Invaild piece: %d", board->board[x][y] ); return MOVE_INVALID; } if ( ( IS_WHITE( board->board[x][y] ) && IS_WHITE( board->board[dx][dy] ) ) || ( IS_BLACK( board->board[x][y] ) && IS_BLACK( board->board[dx][dy] ) ) ) return MOVE_SAMECOLOR; return MOVE_OK; }
static bool king_in_check( GAME_BOARD_DATA * board, int piece ) { int x = 0, y = 0, l, m; if ( piece != WHITE_KING && piece != BLACK_KING ) return FALSE; if ( !find_piece( board, &x, &y, piece ) ) return FALSE; if ( x < 0 || y < 0 || x > 7 || y > 7 ) return FALSE; /* * pawns */ if ( IS_WHITE( piece ) && x < 7 && ( ( y > 0 && IS_BLACK( board->board[x + 1][y - 1] ) ) || ( y < 7 && IS_BLACK( board->board[x + 1][y + 1] ) ) ) ) return TRUE; else if ( IS_BLACK( piece ) && x > 0 && ( ( y > 0 && IS_WHITE( board->board[x - 1][y - 1] ) ) || ( y < 7 && IS_WHITE( board->board[x - 1][y + 1] ) ) ) ) return TRUE; /* * knights */ if ( x - 2 >= 0 && y - 1 >= 0 && ( ( board->board[x - 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x - 2 >= 0 && y + 1 < 8 && ( ( board->board[x - 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x - 1 >= 0 && y - 2 >= 0 && ( ( board->board[x - 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x - 1 >= 0 && y + 2 < 8 && ( ( board->board[x - 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x + 1 < 8 && y - 2 >= 0 && ( ( board->board[x + 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x + 1 < 8 && y + 2 < 8 && ( ( board->board[x + 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x + 2 < 8 && y - 1 >= 0 && ( ( board->board[x + 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; if ( x + 2 < 8 && y + 1 < 8 && ( ( board->board[x + 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return TRUE; /* * horizontal/vertical long distance */ for ( l = x + 1; l < 8; l++ ) if ( board->board[l][y] != NO_PIECE ) { if ( SAME_COLOR( x, y, l, y ) ) break; if ( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK ) return TRUE; break; } for ( l = x - 1; l >= 0; l-- ) if ( board->board[l][y] != NO_PIECE ) { if ( SAME_COLOR( x, y, l, y ) ) break; if ( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK ) return TRUE; break; } for ( m = y + 1; m < 8; m++ ) if ( board->board[x][m] != NO_PIECE ) { if ( SAME_COLOR( x, y, x, m ) ) break; if ( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK ) return TRUE; break; } for ( m = y - 1; m >= 0; m-- ) if ( board->board[x][m] != NO_PIECE ) { if ( SAME_COLOR( x, y, x, m ) ) break; if ( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK ) return TRUE; break; } /* * diagonal long distance */ for ( l = x + 1, m = y + 1; l < 8 && m < 8; l++, m++ ) if ( board->board[l][m] != NO_PIECE ) { if ( SAME_COLOR( x, y, l, m ) ) break; if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return TRUE; break; } for ( l = x - 1, m = y + 1; l >= 0 && m < 8; l--, m++ ) if ( board->board[l][m] != NO_PIECE ) { if ( SAME_COLOR( x, y, l, m ) ) break; if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return TRUE; break; } for ( l = x + 1, m = y - 1; l < 8 && m >= 0; l++, m-- ) if ( board->board[l][m] != NO_PIECE ) { if ( SAME_COLOR( x, y, l, m ) ) break; if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return TRUE; break; } for ( l = x - 1, m = y - 1; l >= 0 && m >= 0; l--, m-- ) if ( board->board[l][m] != NO_PIECE ) { if ( SAME_COLOR( x, y, l, m ) ) break; if ( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return TRUE; break; } return FALSE; }
int is_valid_move( char_data * ch, game_board_data * board, int x, int y, int dx, int dy ) { if( !ch ) { bug( "%s: nullptr ch!", __func__ ); return MOVE_INVALID; } if( !board ) { bug( "%s: nullptr board!", __func__ ); return MOVE_INVALID; } if( dx < 0 || dy < 0 || dx > 7 || dy > 7 ) return MOVE_OFFBOARD; if( board->board[x][y] == NO_PIECE ) return MOVE_INVALID; if( x == dx && y == dy ) return MOVE_INVALID; if( IS_WHITE( board->board[x][y] ) && !str_cmp( board->player1, ch->name ) ) return MOVE_WRONGCOLOR; if( IS_BLACK( board->board[x][y] ) && ( !ch || !str_cmp( board->player2, ch->name ) ) ) return MOVE_WRONGCOLOR; switch ( board->board[x][y] ) { case WHITE_PAWN: case BLACK_PAWN: if( IS_WHITE( board->board[x][y] ) && dx == x + 2 && x == 1 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x + 1][dy] == NO_PIECE ) return MOVE_OK; else if( IS_BLACK( board->board[x][y] ) && dx == x - 2 && x == 6 && dy == y && board->board[dx][dy] == NO_PIECE && board->board[x - 1][dy] == NO_PIECE ) return MOVE_OK; if( IS_WHITE( board->board[x][y] ) && dx != x + 1 ) return MOVE_INVALID; else if( IS_BLACK( board->board[x][y] ) && dx != x - 1 ) return MOVE_INVALID; if( dy != y && dy != y - 1 && dy != y + 1 ) return MOVE_INVALID; if( dy == y ) { if( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; else if( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; else return MOVE_BLOCKED; } else { if( board->board[dx][dy] == NO_PIECE ) return MOVE_INVALID; else if( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; else if( board->board[dx][dy] != BLACK_KING && board->board[dx][dy] != WHITE_KING ) return MOVE_TAKEN; else return MOVE_INVALID; } break; case WHITE_ROOK: case BLACK_ROOK: { int cnt; if( dx != x && dy != y ) return MOVE_INVALID; if( dx == x ) { for( cnt = y; cnt != dy; ) { if( cnt != y && board->board[x][cnt] != NO_PIECE ) return MOVE_BLOCKED; if( dy > y ) ++cnt; else --cnt; } } else if( dy == y ) { for( cnt = x; cnt != dx; ) { if( cnt != x && board->board[cnt][y] != NO_PIECE ) return MOVE_BLOCKED; if( dx > x ) ++cnt; else --cnt; } } if( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if( !SAME_COLOR( x, y, dx, dy ) ) return MOVE_TAKEN; return MOVE_SAMECOLOR; } break; case WHITE_KNIGHT: case BLACK_KNIGHT: if( ( dx == x - 2 && dy == y - 1 ) || ( dx == x - 2 && dy == y + 1 ) || ( dx == x - 1 && dy == y - 2 ) || ( dx == x - 1 && dy == y + 2 ) || ( dx == x + 1 && dy == y - 2 ) || ( dx == x + 1 && dy == y + 2 ) || ( dx == x + 2 && dy == y - 1 ) || ( dx == x + 2 && dy == y + 1 ) ) { if( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; return MOVE_TAKEN; } return MOVE_INVALID; break; case WHITE_BISHOP: case BLACK_BISHOP: { int l, m, blocked = false; if( dx == x || dy == y ) return MOVE_INVALID; l = x; m = y; while( 1 ) { if( dx > x ) ++l; else --l; if( dy > y ) ++m; else --m; if( l > 7 || m > 7 || l < 0 || m < 0 ) return MOVE_INVALID; if( l == dx && m == dy ) break; if( board->board[l][m] != NO_PIECE ) blocked = true; } if( l != dx || m != dy ) return MOVE_INVALID; if( blocked ) return MOVE_BLOCKED; if( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if( !SAME_COLOR( x, y, dx, dy ) ) return MOVE_TAKEN; return MOVE_SAMECOLOR; } break; case WHITE_QUEEN: case BLACK_QUEEN: { int l, m, blocked = false; l = x; m = y; while( 1 ) { if( dx > x ) ++l; else if( dx < x ) --l; if( dy > y ) ++m; else if( dy < y ) --m; if( l > 7 || m > 7 || l < 0 || m < 0 ) return MOVE_INVALID; if( l == dx && m == dy ) break; if( board->board[l][m] != NO_PIECE ) blocked = true; } if( l != dx || m != dy ) return MOVE_INVALID; if( blocked ) return MOVE_BLOCKED; if( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if( !SAME_COLOR( x, y, dx, dy ) ) return MOVE_TAKEN; return MOVE_SAMECOLOR; } break; case WHITE_KING: case BLACK_KING: { int sp, sk; if( dx > x + 1 || dx < x - 1 || dy > y + 1 || dy < y - 1 ) return MOVE_INVALID; sk = board->board[x][y]; sp = board->board[dx][dy]; board->board[x][y] = sp; board->board[dx][dy] = sk; if( king_in_check( board, sk ) ) { board->board[x][y] = sk; board->board[dx][dy] = sp; return MOVE_CHECK; } board->board[x][y] = sk; board->board[dx][dy] = sp; if( board->board[dx][dy] == NO_PIECE ) return MOVE_OK; if( SAME_COLOR( x, y, dx, dy ) ) return MOVE_SAMECOLOR; return MOVE_TAKEN; } break; default: bug( "Invaild piece: %d", board->board[x][y] ); return MOVE_INVALID; } if( ( IS_WHITE( board->board[x][y] ) && IS_WHITE( board->board[dx][dy] ) ) || ( IS_BLACK( board->board[x][y] ) && IS_BLACK( board->board[dx][dy] ) ) ) return MOVE_SAMECOLOR; return MOVE_OK; }
bool king_in_check( game_board_data * board, int piece ) { int x = 0, y = 0, l, m; if( piece != WHITE_KING && piece != BLACK_KING ) return false; if( !find_piece( board, &x, &y, piece ) ) return false; if( x < 0 || y < 0 || x > 7 || y > 7 ) return false; /* * pawns */ if( IS_WHITE( piece ) && x < 7 && ( ( y > 0 && IS_BLACK( board->board[x + 1][y - 1] ) ) || ( y < 7 && IS_BLACK( board->board[x + 1][y + 1] ) ) ) ) return true; else if( IS_BLACK( piece ) && x > 0 && ( ( y > 0 && IS_WHITE( board->board[x - 1][y - 1] ) ) || ( y < 7 && IS_WHITE( board->board[x - 1][y + 1] ) ) ) ) return true; /* * knights */ if( x - 2 >= 0 && y - 1 >= 0 && ( ( board->board[x - 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x - 2 >= 0 && y + 1 < 8 && ( ( board->board[x - 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x - 1 >= 0 && y - 2 >= 0 && ( ( board->board[x - 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x - 1 >= 0 && y + 2 < 8 && ( ( board->board[x - 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x - 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x + 1 < 8 && y - 2 >= 0 && ( ( board->board[x + 1][y - 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 1][y - 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x + 1 < 8 && y + 2 < 8 && ( ( board->board[x + 1][y + 2] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 1][y + 2] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x + 2 < 8 && y - 1 >= 0 && ( ( board->board[x + 2][y - 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 2][y - 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; if( x + 2 < 8 && y + 1 < 8 && ( ( board->board[x + 2][y + 1] == BLACK_KNIGHT && IS_WHITE( board->board[x][y] ) ) || ( board->board[x + 2][y + 1] == WHITE_KNIGHT && IS_BLACK( board->board[x][y] ) ) ) ) return true; /* * horizontal/vertical long distance */ for( l = x + 1; l < 8; ++l ) if( board->board[l][y] != NO_PIECE ) { if( SAME_COLOR( x, y, l, y ) ) break; if( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK ) return true; break; } for( l = x - 1; l >= 0; --l ) if( board->board[l][y] != NO_PIECE ) { if( SAME_COLOR( x, y, l, y ) ) break; if( board->board[l][y] == BLACK_QUEEN || board->board[l][y] == WHITE_QUEEN || board->board[l][y] == BLACK_ROOK || board->board[l][y] == WHITE_ROOK ) return true; break; } for( m = y + 1; m < 8; ++m ) if( board->board[x][m] != NO_PIECE ) { if( SAME_COLOR( x, y, x, m ) ) break; if( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK ) return true; break; } for( m = y - 1; m >= 0; --m ) if( board->board[x][m] != NO_PIECE ) { if( SAME_COLOR( x, y, x, m ) ) break; if( board->board[x][m] == BLACK_QUEEN || board->board[x][m] == WHITE_QUEEN || board->board[x][m] == BLACK_ROOK || board->board[x][m] == WHITE_ROOK ) return true; break; } /* * diagonal long distance */ for( l = x + 1, m = y + 1; l < 8 && m < 8; ++l, ++m ) if( board->board[l][m] != NO_PIECE ) { if( SAME_COLOR( x, y, l, m ) ) break; if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return true; break; } for( l = x - 1, m = y + 1; l >= 0 && m < 8; --l, ++m ) if( board->board[l][m] != NO_PIECE ) { if( SAME_COLOR( x, y, l, m ) ) break; if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return true; break; } for( l = x + 1, m = y - 1; l < 8 && m >= 0; ++l, --m ) if( board->board[l][m] != NO_PIECE ) { if( SAME_COLOR( x, y, l, m ) ) break; if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return true; break; } for( l = x - 1, m = y - 1; l >= 0 && m >= 0; --l, --m ) if( board->board[l][m] != NO_PIECE ) { if( SAME_COLOR( x, y, l, m ) ) break; if( board->board[l][m] == BLACK_QUEEN || board->board[l][m] == WHITE_QUEEN || board->board[l][m] == BLACK_BISHOP || board->board[l][m] == WHITE_BISHOP ) return true; break; } return false; }
void rbt_paint_onremove(rbt_t *rbt, rbt_node_t *node) { if (!node) return; // delete case 1 if (node->parent != NULL) { // delete case 2 rbt_node_t *sibling = rbt_sibling(node); if (IS_RED(sibling)) { PAINT_RED(node->parent); PAINT_BLACK(sibling); if (node == node->parent->left) { rbt_rotate_left(rbt, node->parent); } else { rbt_rotate_right(rbt, node->parent); } } // delete case 3 if (IS_BLACK(node->parent) && sibling && IS_BLACK(sibling) && IS_BLACK(sibling->left) && IS_BLACK(sibling->right)) { PAINT_RED(sibling); rbt_paint_onremove(rbt, node->parent); } else { // delete case 4 if (IS_RED(node->parent) && sibling && IS_BLACK(sibling) && IS_BLACK(sibling->left) && IS_BLACK(sibling->right)) { PAINT_RED(sibling); PAINT_BLACK(node->parent); } else { // delete case 5 if (IS_BLACK(sibling)) { if (node == node->parent->left && sibling && IS_BLACK(sibling->right) && IS_RED(sibling->left)) { PAINT_RED(sibling); PAINT_BLACK(sibling->left); rbt_rotate_right(rbt, sibling); } else if (node == node->parent->right && sibling && IS_BLACK(sibling->left) && IS_RED(sibling->right)) { PAINT_RED(sibling); PAINT_BLACK(sibling->right); rbt_rotate_left(rbt, sibling); } } // delete case 6 if (sibling) sibling->color = node->parent->color; PAINT_BLACK(node->parent); if (node == node->parent->left) { if (sibling) PAINT_BLACK(sibling->right); rbt_rotate_left(rbt, node->parent); } else { if (sibling) PAINT_BLACK(sibling->left); rbt_rotate_right(rbt, node->parent); } } } } }
int rbt_remove(rbt_t *rbt, void *k, size_t klen, void **v) { rbt_node_t *node = _rbt_find_internal(rbt, rbt->root, k, klen); if (!node) return -1; if (node->left || node->right) { // the node is not a leaf // now check if it has two children or just one if (node->left && node->right) { // two children case rbt_node_t *n = NULL; static int prevnext = 0; int isprev = (prevnext++%2 == 0); if (isprev) n = rbt_find_prev(rbt, node); else n = rbt_find_next(rbt, node); node->key = realloc(node->key, n->klen); memcpy(node->key, n->key, n->klen); void *prev_value = node->value; node->value = n->value; if (isprev) { if (n == node->left) { node->left = n->left; } else { n->parent->right = n->left; } if (n->left) { n->left->parent = node; } } else { if (n == node->right) { node->right = n->right; } else { n->parent->left = n->right; } if (n->right) { n->right->parent = node; } } free(n->key); if (v) *v = prev_value; else if (rbt->free_value_cb) rbt->free_value_cb(prev_value); free(n); return 0; } else { // one child case rbt_node_t *child = node->right ? node->right : node->left; // replace node with child child->parent = node->parent; if (child->parent) { if (node == node->parent->left) node->parent->left = child; else node->parent->right = child; } if (IS_BLACK(node)) { if (IS_RED(child)) { PAINT_BLACK(child); } else { rbt_paint_onremove(rbt, child); } } if (v) *v = node->value; else if (rbt->free_value_cb) rbt->free_value_cb(node->value); free(node->key); free(node); return 0; } } // if it's not the root node we need to update the parent if (node->parent) { if (node == node->parent->left) node->parent->left = NULL; else node->parent->right = NULL; } if (v) *v = node->value; else if (rbt->free_value_cb && node->value) rbt->free_value_cb(node->value); free(node->key); free(node); return 0; }
static void bst_remove_repair(bst *t, bstnode *n) { bstnode *sib; /* case 1: n is root */ if (!n->parent) return; sib = SIBLING(n); /* case 2: n's sibling is red */ if (IS_RED(sib)) { n->parent->color = RED; sib->color = BLACK; if (IS_LEFT_CHILD(n)) bst_rotate_left(t, n->parent); else bst_rotate_right(t, n->parent); sib = SIBLING(n); } /* case 3: parent sib and sib's children are black */ if (n->parent->color == BLACK && sib->color == BLACK && IS_BLACK(sib->left) && IS_BLACK(sib->right)) { sib->color = RED; bst_remove_repair(t, n->parent); return; } /* case 4: parent is red, sib and sib's children are black */ if (n->parent->color == RED && sib->color == BLACK && IS_BLACK(sib->left) && IS_BLACK(sib->right)) { sib->color = RED; n->parent->color = BLACK; return; } /* case 5: a) n is left child, sib and sib->right child are black, sib->left is red b) n is right child, sib and sib->left child are black, sib->right is red */ if (IS_LEFT_CHILD(n) && sib->color == BLACK && IS_RED(sib->left) && IS_BLACK(sib->right)) { sib->color = RED; sib->left->color = BLACK; bst_rotate_right(t, sib); sib = SIBLING(n); } else if (IS_RIGHT_CHILD(n) && sib->color == BLACK && IS_RED(sib->right) && IS_BLACK(sib->left)) { sib->color = RED; sib->right->color = BLACK; bst_rotate_left(t, sib); sib = SIBLING(n); } /* case 6: */ sib->color = n->parent->color; n->parent->color = BLACK; if (IS_LEFT_CHILD(n)) { sib->right->color = BLACK; bst_rotate_left(t, n->parent); } else { sib->left->color = BLACK; bst_rotate_right(t, n->parent); } }
void rb_delete(rbtree* tree, int data) { int color = RED; rbnode* dn = tree->root; rbnode* x = 0; rbnode* y = 0; //parent of deleted node rbnode* s = 0; //sibling rbnode* p = 0; //parent rbnode* ln =0; //left nephew rbnode* rn = 0; //right nephew int delcolor = 0; while (dn) { if (dn->data == data) break; else if (data < dn->data) dn = dn->left; else dn = dn->right; } if (!dn) return; delcolor = dn->color; y = dn->parent; if (!dn->left && !dn->right) { REPLACE(tree, dn, ((rbnode*)0)); x = 0; } else if (!dn->left) { REPLACE(tree, dn, dn->right); x = dn->right; } else if (!dn->right) { REPLACE(tree, dn, dn->left); x = dn->left; } else { rbnode* rl = dn->right; while (rl->left) rl = rl->left; x = rl->right; y = rl == dn->right ? rl : rl->parent; delcolor = rl->color; REPLACE(tree, rl, rl->right); REPLACE(tree, dn, rl); rl->left = dn->left; rl->right = dn->right; rl->color = dn->color; } if (delcolor == RED) { destory_rbnode(dn); return; } while (IS_BLACK(x) && x != tree->root) { p = x ? x->parent : y; if ((!x && !y->left) || IS_LEFT(x)) { s = p->right;//s != 0,because x is black, the path to from s to null must has at least a black node if (s->color == RED) { LEFT_ROTATE(tree,p); p->color = RED; s->color = BLACK; continue; } else if (IS_BLACK(s->left) && IS_BLACK(s->right)) { s->color = RED; x = p; continue; } ln = s->left; rn = s->right; if (IS_BLACK(rn)) { RIGHT_ROTATE(tree,s); s->color = RED; ln->color = BLACK; continue; } else { LEFT_ROTATE(tree,p); s->color = p->color; p->color = BLACK; x = rn; break; } } else if ((!x && !y->right) || IS_RIGHT(x)) { s = p->left;//s != 0,because x is black, the path to from s to null must has at least a black node if (s->color == RED) { RIGHT_ROTATE(tree,p); p->color = RED; s->color = BLACK; continue; } else if (IS_BLACK(s->left) && IS_BLACK(s->left)) { s->color = RED; x = p; continue; } ln = s->left; rn = s->left; if (IS_BLACK(ln)) { LEFT_ROTATE(tree,s); s->color = RED; rn->color = BLACK; continue; } else { RIGHT_ROTATE(tree,p); s->color = p->color; p->color = BLACK; x = ln; break; } } } if (x) x->color = BLACK; destory_rbnode(dn); return; }
static void tree_insert_fixup(RBTree_t **root, RBTree_t *blk) { RBTree_t *x = blk, *y; /* * Rearrange the tree so that it satisfies the Red-Black Tree properties */ RBT_ASSERT(x != *root && IS_RED(x->parent)); do { /* * x and its parent are both red. Move the red pair up the tree * until we get to the root or until we can separate them. */ RBT_ASSERT(IS_RED(x)); RBT_ASSERT(IS_BLACK(x->parent->parent)); RBT_ASSERT(x->parent->parent); if (x->parent == x->parent->parent->left) { y = x->parent->parent->right; if (IS_RED(y)) { SET_BLACK(y); x = x->parent; SET_BLACK(x); x = x->parent; SET_RED(x); } else { if (x == x->parent->right) { x = x->parent; left_rotate(root, x); } RBT_ASSERT(x == x->parent->parent->left->left); RBT_ASSERT(IS_RED(x)); RBT_ASSERT(IS_RED(x->parent)); RBT_ASSERT(IS_BLACK(x->parent->parent)); RBT_ASSERT(IS_BLACK(y)); SET_BLACK(x->parent); SET_RED(x->parent->parent); right_rotate(root, x->parent->parent); RBT_ASSERT(x == x->parent->left); RBT_ASSERT(IS_RED(x)); RBT_ASSERT(IS_RED(x->parent->right)); RBT_ASSERT(IS_BLACK(x->parent)); break; } } else { RBT_ASSERT(x->parent == x->parent->parent->right); y = x->parent->parent->left; if (IS_RED(y)) { SET_BLACK(y); x = x->parent; SET_BLACK(x); x = x->parent; SET_RED(x); } else { if (x == x->parent->left) { x = x->parent; right_rotate(root, x); } RBT_ASSERT(x == x->parent->parent->right->right); RBT_ASSERT(IS_RED(x)); RBT_ASSERT(IS_RED(x->parent)); RBT_ASSERT(IS_BLACK(x->parent->parent)); RBT_ASSERT(IS_BLACK(y)); SET_BLACK(x->parent); SET_RED(x->parent->parent); left_rotate(root, x->parent->parent); RBT_ASSERT(x == x->parent->right); RBT_ASSERT(IS_RED(x)); RBT_ASSERT(IS_RED(x->parent->left)); RBT_ASSERT(IS_BLACK(x->parent)); break; } } } while (x != *root && IS_RED(x->parent)); SET_BLACK(*root); }
static AOFF_RBTree_t * check_tree(Carrier_t* within_crr, enum AOFFSortOrder order, AOFF_RBTree_t* root, Uint size) { AOFF_RBTree_t *res = NULL; Sint blacks; Sint curr_blacks; AOFF_RBTree_t *x; Carrier_t* crr; Uint depth, max_depth, node_cnt; #ifdef PRINT_TREE print_tree(root); #endif ASSERT((within_crr && order >= FF_AOFF) || (!within_crr && order <= FF_AOFF)); if (!root) return res; x = root; ASSERT(IS_BLACK(x)); ASSERT(!x->parent); curr_blacks = 1; blacks = -1; depth = 1; max_depth = 0; node_cnt = 0; while (x) { if (!IS_LEFT_VISITED(x)) { SET_LEFT_VISITED(x); if (x->left) { x = x->left; ++depth; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } if (!IS_RIGHT_VISITED(x)) { SET_RIGHT_VISITED(x); if (x->right) { x = x->right; ++depth; if (IS_BLACK(x)) curr_blacks++; continue; } else { if (blacks < 0) blacks = curr_blacks; ASSERT(blacks == curr_blacks); } } ++node_cnt; if (depth > max_depth) max_depth = depth; if (within_crr) { crr = FBLK_TO_MBC(&x->hdr); ASSERT(crr == within_crr); ASSERT((char*)x > (char*)crr); ASSERT(((char*)x + AOFF_BLK_SZ(x)) <= ((char*)crr + CARRIER_SZ(crr))); } if (order == FF_BF) { AOFF_RBTree_t* y = x; AOFF_RBTree_t* nxt = LIST_NEXT(y); ASSERT(IS_TREE_NODE(x)); while (nxt) { ASSERT(IS_LIST_ELEM(nxt)); ASSERT(AOFF_BLK_SZ(nxt) == AOFF_BLK_SZ(x)); ASSERT(FBLK_TO_MBC(&nxt->hdr) == within_crr); ASSERT(LIST_PREV(nxt) == y); y = nxt; nxt = LIST_NEXT(nxt); } } if (IS_RED(x)) { ASSERT(IS_BLACK(x->right)); ASSERT(IS_BLACK(x->left)); } ASSERT(x->parent || x == root); if (x->left) { ASSERT(x->left->parent == x); ASSERT(cmp_blocks(order, x->left, x) < 0); ASSERT(x->left->max_sz <= x->max_sz); } if (x->right) { ASSERT(x->right->parent == x); ASSERT(cmp_blocks(order, x->right, x) > 0); ASSERT(x->right->max_sz <= x->max_sz); } ASSERT(x->max_sz >= AOFF_BLK_SZ(x)); ASSERT(x->max_sz == AOFF_BLK_SZ(x) || x->max_sz == (x->left ? x->left->max_sz : 0) || x->max_sz == (x->right ? x->right->max_sz : 0)); if (size && AOFF_BLK_SZ(x) >= size) { if (!res || cmp_blocks(order, x, res) < 0) { res = x; } } UNSET_LEFT_VISITED(x); UNSET_RIGHT_VISITED(x); if (IS_BLACK(x)) curr_blacks--; x = x->parent; --depth; } ASSERT(depth == 0 || (!root && depth==1)); ASSERT(curr_blacks == 0); ASSERT((1 << (max_depth/2)) <= node_cnt); UNSET_LEFT_VISITED(root); UNSET_RIGHT_VISITED(root); return res; }
/* * The argument types of "Allctr_t *" and "Block_t *" have been * chosen since we then can use tree_delete() as unlink_free_block * callback function in the address order case. */ static void tree_delete(Allctr_t *allctr, Block_t *del) { BFAllctr_t *bfallctr = (BFAllctr_t *) allctr; Uint spliced_is_black; RBTree_t **root = &bfallctr->mbc_root; RBTree_t *x, *y, *z = (RBTree_t *) del; RBTree_t null_x; /* null_x is used to get the fixup started when we splice out a node without children. */ null_x.parent = NULL; #ifdef HARD_DEBUG check_tree(*root, bfallctr->address_order, 0); #endif /* Remove node from tree... */ /* Find node to splice out */ if (!z->left || !z->right) y = z; else /* Set y to z:s successor */ for(y = z->right; y->left; y = y->left); /* splice out y */ x = y->left ? y->left : y->right; spliced_is_black = IS_BLACK(y); if (x) { x->parent = y->parent; } else if (!x && spliced_is_black) { x = &null_x; x->flags = 0; SET_BLACK(x); x->right = x->left = NULL; x->parent = y->parent; y->left = x; } if (!y->parent) { RBT_ASSERT(*root == y); *root = x; } else if (y == y->parent->left) y->parent->left = x; else { RBT_ASSERT(y == y->parent->right); y->parent->right = x; } if (y != z) { /* We spliced out the successor of z; replace z by the successor */ replace(root, z, y); } if (spliced_is_black) { /* We removed a black node which makes the resulting tree violate the Red-Black Tree properties. Fixup tree... */ while (IS_BLACK(x) && x->parent) { /* * x has an "extra black" which we move up the tree * until we reach the root or until we can get rid of it. * * y is the sibbling of x */ if (x == x->parent->left) { y = x->parent->right; RBT_ASSERT(y); if (IS_RED(y)) { RBT_ASSERT(y->right); RBT_ASSERT(y->left); SET_BLACK(y); RBT_ASSERT(IS_BLACK(x->parent)); SET_RED(x->parent); left_rotate(root, x->parent); y = x->parent->right; } RBT_ASSERT(y); RBT_ASSERT(IS_BLACK(y)); if (IS_BLACK(y->left) && IS_BLACK(y->right)) { SET_RED(y); x = x->parent; } else { if (IS_BLACK(y->right)) { SET_BLACK(y->left); SET_RED(y); right_rotate(root, y); y = x->parent->right; } RBT_ASSERT(y); if (IS_RED(x->parent)) { SET_BLACK(x->parent); SET_RED(y); } RBT_ASSERT(y->right); SET_BLACK(y->right); left_rotate(root, x->parent); x = *root; break; } } else { RBT_ASSERT(x == x->parent->right); y = x->parent->left; RBT_ASSERT(y); if (IS_RED(y)) { RBT_ASSERT(y->right); RBT_ASSERT(y->left); SET_BLACK(y); RBT_ASSERT(IS_BLACK(x->parent)); SET_RED(x->parent); right_rotate(root, x->parent); y = x->parent->left; } RBT_ASSERT(y); RBT_ASSERT(IS_BLACK(y)); if (IS_BLACK(y->right) && IS_BLACK(y->left)) { SET_RED(y); x = x->parent; } else { if (IS_BLACK(y->left)) { SET_BLACK(y->right); SET_RED(y); left_rotate(root, y); y = x->parent->left; } RBT_ASSERT(y); if (IS_RED(x->parent)) { SET_BLACK(x->parent); SET_RED(y); } RBT_ASSERT(y->left); SET_BLACK(y->left); right_rotate(root, x->parent); x = *root; break; } } } SET_BLACK(x); if (null_x.parent) { if (null_x.parent->left == &null_x) null_x.parent->left = NULL; else { RBT_ASSERT(null_x.parent->right == &null_x); null_x.parent->right = NULL; } RBT_ASSERT(!null_x.left); RBT_ASSERT(!null_x.right); } else if (*root == &null_x) { *root = NULL; RBT_ASSERT(!null_x.left); RBT_ASSERT(!null_x.right); } } DESTROY_TREE_NODE(del); #ifdef HARD_DEBUG check_tree(root, bfallctr->address_order, 0); #endif }
static void mapnode_remove(map_t *map, mapnode_t *node) { allocator_t *alloc = map->allocator; mapnode_t *destroyed, *y, *z; if (node->left == NIL) { destroyed = node; y = node->right; } else if (node->right == NIL) { destroyed = node; y = node->left; } else { destroyed = node->left; while (destroyed->right != NIL) destroyed = destroyed->right; y = destroyed->left; node->key = destroyed->key; node->p = destroyed->p; } z = destroyed->parent; if (y != NIL) y->parent = z; if (z == NIL) { map->root = y; goto finish_removal; } if (destroyed == z->left) { z->left = y; } else { z->right = y; } if (IS_BLACK(destroyed)) { while (y != map->root && IS_BLACK(y)) { mapnode_t *sibling; int dir = !(y == z->left); sibling = OPP_NODE(z, dir); if (IS_RED(sibling)) { sibling->color = BLACK; z->color = RED; g_rotations[dir](map, z); sibling = OPP_NODE(z, dir); } if (IS_BLACK(sibling->left) && IS_BLACK(sibling->right)) { sibling->color = RED; y = z; z = z->parent; } else { if (IS_BLACK(OPP_NODE(sibling, dir))) { DIR_NODE(sibling, dir)->color = BLACK; sibling->color = RED; g_rotations[!dir](map, sibling); sibling = OPP_NODE(z, dir); } sibling->color = z->color; z->color = BLACK; OPP_NODE(sibling, dir)->color = BLACK; g_rotations[dir](map, z); y = map->root; } } y->color = BLACK; } finish_removal: com_free(alloc, destroyed); map->size -= 1; #if !defined(NDEBUG) map_test(map->root); #endif }