Exemplo n.º 1
0
Arquivo: tree.c Projeto: lchish/cosc
/**
 * 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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
Arquivo: rbt.c Projeto: lchish/cosc
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;
}
Exemplo n.º 4
0
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);
    }
}
Exemplo n.º 5
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;
};
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
Arquivo: rbtree.c Projeto: nasa/QuIP
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);
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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);
    }
}
Exemplo n.º 10
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);
    }
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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);
}
Exemplo n.º 13
0
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);
    }
}
Exemplo n.º 14
0
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);
    }
}
Exemplo n.º 15
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);
	}
    }
}
Exemplo n.º 16
0
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;

}
Exemplo n.º 17
0
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);
  
} 
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
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);
                }
            }
        }
    }
}
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
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);
    }
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
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);

}
Exemplo n.º 28
0
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;

}
Exemplo n.º 29
0
/*
 * 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

}
Exemplo n.º 30
0
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
}