template <class D> AVL_RES avl_tree<D>::internal_remove(avl_node<D> **node,D *data) { AVL_RES result=AVL_BALANCE; if(!(*node)) return AVL_ERROR; long diff=compare(*node,data); if(diff<0) { if((result=internal_remove(&(*node)->left,data))==AVL_BALANCE) { return leftshrunk(node); } return result; } if(diff>0) { if((result=internal_remove(&(*node)->right,data))==AVL_BALANCE) { return rightshrunk(node); } return result; } node_count--; if((*node)->left) { if(findhighest(*node,&((*node)->left),&result)) { if(result==AVL_BALANCE) { result=leftshrunk(node); } return result; } } if((*node)->right) { if(findlowest(*node,&((*node)->right),&result)) { if(result==AVL_BALANCE) { result=rightshrunk(node); } return result; } } delete *node; *node=NULL; return AVL_BALANCE; }
template <class D> int avl_tree<D>::findlowest(avl_node<D> *target,avl_node<D> **node,AVL_RES *res) { avl_node<D> *tmp; D *tmp_data; *res=AVL_BALANCE; if(!(*node)) return 0; if((*node)->left) { if(!findlowest(target,&(*node)->left,res)) return 0; if(*res==AVL_BALANCE) { *res=leftshrunk(node); } return 1; } tmp_data=target->data; target->data=(*node)->data; (*node)->data=tmp_data; tmp=*node; *node=(*node)->right; delete tmp; return 1; }
int see(int color, int square, int from) { int sside; int caps[2]; int value; int origpiece; int ourbestvalue; int hisbestvalue; /* reset data */ see_num_attackers[WHITE] = 0; see_num_attackers[BLACK] = 0; /* remove original capturer from board, exposing his first xray-er */ origpiece = board[from]; board[from] = npiece; see_num_attackers[color]++; see_attackers[color][0].piece = origpiece; see_attackers[color][0].square = from; /* calculate all attackers to square */ setup_attackers(square); /* initially we gain the piece we are capturing */ value = abs(material[board[square]]); /* free capture ? */ if (!see_num_attackers[!color]) { board[from] = origpiece; return value; } else { /* we can never get a higher SEE score than the piece we just captured */ /* so that is the current best value for our opponent */ /* we arent sure of anything yet, so -INF */ hisbestvalue = value; ourbestvalue = -INF; } caps[color] = 1; caps[!color] = 0; /* start with recapture */ sside = !color; /* continue as long as there are attackers */ while (caps[sside] < see_num_attackers[sside]) { /* resort capturelist of sside to put lowest attacker in next position */ findlowest(sside, caps[sside]); if (sside == color) { /* capturing more */ /* we capture the opponents recapturer */ value += abs(material[see_attackers[!sside][caps[!sside]-1].piece]); /* if the opp ran out of attackers we can stand pat now! */ if (see_num_attackers[!sside] <= caps[!sside] && value > ourbestvalue) ourbestvalue = value; /* our opponent can always stand pat now */ if (value < hisbestvalue) hisbestvalue = value; } else { /* recapture by opp */ /* we lose whatever we captured with in last iteration */ value -= abs(material[see_attackers[!sside][caps[!sside]-1].piece]); /* we can stand pat if we want to now */ /* our best score goes up, opponent is unaffected */ if (value > ourbestvalue) { ourbestvalue = value; } if (see_num_attackers[!sside] <= caps[!sside] && value < hisbestvalue) hisbestvalue = value; } /* keep track of capture count */ caps[sside]++; /* switch sides */ sside ^= 1; } /* restore capturer */ board[from] = origpiece; /* we return our best score now, keeping in mind that it can never we better than the best for our opponent */ return (ourbestvalue > hisbestvalue) ? hisbestvalue : ourbestvalue; }