Esempio n. 1
0
BOOL test_alt_move_gen() {

    BOOL ok = TRUE;
    struct t_move_list moves[1], xmoves[2];

    set_fen(position, "5rN1/4P3/1B6/1B3k2/8/4P3/6PP/2RQK2R w K -");
    generate_captures(position, moves);
    generate_quiet_checks(position, moves);
    generate_no_capture_no_checks(position, moves);

    generate_moves(position, xmoves);

    ok &= (equal_move_lists(xmoves, moves));

    flip_board(position);
    generate_captures(position, moves);
    generate_quiet_checks(position, moves);
    generate_no_capture_no_checks(position, moves);

    generate_moves(position, xmoves);
    ok &= (equal_move_lists(xmoves, moves));

    return ok;

}
Esempio n. 2
0
File: perft.cpp Progetto: pd/benthos
void
do_perft(position_t *pos, scored_move_t *ms, int ply, int depth)
{
	scored_move_t *msbase = ms;
	uint8 stm = Stm(ply);
	scored_move_t *mv;

	if (Checked(stm^1))
		return;

	if (Checked(stm)) {
		ms = generate_evasions(pos, ms, ply);
		for (mv = msbase; mv < ms; mv++)
			if (PieceType(Capture(mv->move)) == KING)
				return;
	} else {
		ms = generate_captures(pos, ms, ply);
		for (mv = msbase; mv < ms; mv++)
			if (PieceType(Capture(mv->move)) == KING)
				return;
		ms = generate_noncaptures(pos, ms, ply);
	}

	for (mv = msbase; mv < ms; mv++) {
		make_move(pos, mv->move, ply);
		if (depth - 1)
			do_perft(pos, ms, ply + 1, depth - 1);
		else if (!Checked(stm))
			total_moves++;
		unmake_move(pos, mv->move, ply);
	}
}
MoveStack* generate_moves(const Position& pos, MoveStack* mlist, bool pseudoLegal) {

  assert(pos.is_ok());

  MoveStack *last, *cur = mlist;
  Bitboard pinned = pos.pinned_pieces(pos.side_to_move());

  // Generate pseudo-legal moves
  if (pos.is_check())
      last = generate_evasions(pos, mlist);
  else
      last = generate_noncaptures(pos, generate_captures(pos, mlist));

  if (pseudoLegal)
      return last;

  // Remove illegal moves from the list
  while (cur != last)
      if (pos.pl_move_is_legal(cur->move, pinned))
          cur++;
      else
          cur->move = (--last)->move;

  return last;
}
Esempio n. 4
0
BOOL test_capture_gen() {

    BOOL ok = TRUE;
    struct t_move_list moves[1];

    set_fen(position, "8/pppr2pp/3pKp2/2Q3bn/8/b6k/PPP1P2P/3R2n1 w - -");
    generate_captures(position, moves);
    ok &= (moves->count == 12);

    flip_board(position);
    generate_captures(position, moves);
    ok &= (moves->count == 12);

    return ok;

}
Esempio n. 5
0
int quiescence(int alpha, int beta)
{
    int static_evaluation = evaluate(alpha, beta);
    if(static_evaluation >= beta)
        return beta;
    if(static_evaluation > alpha)
        alpha = static_evaluation;
    
    Move movelist[256];
    int n = generate_captures(movelist);
    sorting_captures(movelist, n);
    for(int i = 0; i < n; i += 1)
    {
        Move i_move = movelist[i];
        make_move(i_move);
        int score = -quiescence(-beta, -alpha);
        unmake_move(i_move);
        
        if(score >= beta)
        {
            return beta;
        }
        if(score > alpha)
        {
            alpha = score;
        }
    }
    return alpha;
}
Esempio n. 6
0
BOOL test_hash_table()
{
	t_move_list moves[1];
	t_hash_record *h;
	BOOL ok = TRUE;

	set_fen(position, "8/pppr2pp/3pKp2/2Q3bn/8/b6k/PPP1P2P/3R2n1 w - -");
	generate_captures(position, moves);

	poke(position->hash, 1, 2, 2, HASH_LOWER, moves->move[0]);

	h = probe(position->hash);

	if (h != NULL){
		ok &= h->bound == HASH_LOWER;
		ok &= h->depth == 2;
		ok &= h->score == 1;
		ok &= h->move == moves->move[0];
		ok &= h->key == position->hash;
	}

	return ok;
}
Move MovePicker::get_next_move() {
  Move move;

  while(true) {
    // If we already have a list of generated moves, pick the best move from
    // the list, and return it:
    move = this->pick_move_from_list();
    if(move != MOVE_NONE) {
      assert(move_is_ok(move));
      return move;
    }

    // Next phase:
    phaseIndex++;
    switch(PhaseTable[phaseIndex]) {

    case PH_TT_MOVE:
      if(ttMove != MOVE_NONE) {
        assert(move_is_ok(ttMove));
        Move m = generate_move_if_legal(*pos, ttMove, pinned);
        if(m != MOVE_NONE) {
          assert(m == ttMove);
          return m;
        }
      }
      break;

    case PH_MATE_KILLER:
      if(mateKiller != MOVE_NONE) {
        assert(move_is_ok(mateKiller));
        Move m = generate_move_if_legal(*pos, mateKiller, pinned);
        if(m != MOVE_NONE) {
          assert(m == mateKiller);
          return m;
        }
      }
      break;

    case PH_GOOD_CAPTURES:
      // pinned = pos->pinned_pieces(pos->side_to_move());
      numOfMoves = generate_captures(*pos, moves);
      this->score_captures();
      movesPicked = 0;
      break;

    case PH_BAD_CAPTURES:
      badCapturesPicked = 0;
      break;

    case PH_NONCAPTURES:
      numOfMoves = generate_noncaptures(*pos, moves);
      this->score_noncaptures();
      movesPicked = 0;
      break;

    case PH_EVASIONS:
      assert(pos->is_check());
      // pinned = pos->pinned_pieces(pos->side_to_move());
      numOfMoves = generate_evasions(*pos, moves);
      this->score_evasions();
      movesPicked = 0;
      break;

    case PH_QCAPTURES:
      // pinned = pos->pinned_pieces(pos->side_to_move());
      numOfMoves = generate_captures(*pos, moves);
      this->score_qcaptures();
      movesPicked = 0;
      break;

    case PH_QCHECKS:
      numOfMoves = generate_checks(*pos, moves, dc);
      movesPicked = 0;
      break;

    case PH_STOP:
      return MOVE_NONE;

    default:
      assert(false);
      return MOVE_NONE;
    }
  }

  assert(false);

  return MOVE_NONE;
}
Esempio n. 8
0
t_chess_value qsearch(struct t_board *board, int ply, int depth, t_chess_value alpha, t_chess_value beta) {

    //-- Principle Variation
    struct t_pv_data *pv = &(board->pv_data[ply]);

    //-- Has the maximum depth been reached
    if (ply >= MAXPLY || uci.stop)
        return pv->eval->static_score;

    //-- Increment the node count
    qnodes++;

    //-- Is this the deepest?
    if (ply > deepest) {
        deepest = ply;
        do_uci_depth();
    }

    //-- Mate Distance Pruning
    if (CHECKMATE - ply <= alpha) {
        return alpha;
    }
    else if (-CHECKMATE + ply >= beta) {
        return beta;
    }

    //-- PV of Next Ply
    struct t_pv_data *next_pv = &(board->pv_data[ply + 1]);

    //-- Define the local variables
    pv->legal_moves_played = 0;
    t_chess_value best_score;
    t_chess_value a = alpha;
    t_chess_value b = beta;
    t_chess_value e;


    // Declare local variables
    t_undo undo[1];

    //-- Generate All Moves
    struct t_move_list moves[1];
    moves->hash_move = NULL;

    //-----------------------------------------------
    //-- Handling In-Check (e.g. Cannot Stand-Pat)
    //-----------------------------------------------
    if (board->in_check) {

        best_score = -CHECKMATE;

        //-- Generate moves which get out of check
        generate_evade_check(board, moves);

        // Are we in checkmate?
        if (moves->count == 0) {
            pv->best_line_length = ply;
            return -CHECKMATE + ply;
        }

        //-- Order the moves
        order_evade_check(board, moves, ply);

        //-- Play moves
        while (make_next_best_move(board, moves, undo)) {

            //-- Increment the "legal_moves_played" counter
            pv->legal_moves_played++;
            pv->current_move = moves->current_move;

            //-- Evaluate the new board position
            evaluate(board, next_pv->eval);

            //-- Search the next ply at reduced depth
            e = -qsearch(board, ply + 1, depth - 1, -b - 1, -a);

            //-- Is a research required?
            if (alpha + 1 != beta && e > a && a + 1 == b)
                e = -qsearch(board, ply + 1, depth - 1, -beta, -a);

            unmake_move(board, undo);

            //-- Is it good enough to cut-off?
            if (e >= beta) {
                update_check_killers(pv, 0);
                return e;
            }

            //-- Is it the best so far?
            if (e > best_score) {
                best_score = e;

                //-- Does it improve upon alpha (i.e. is it part of the PV)?
                if (e > a) {
                    a = e;

                    //-- Update the Principle Variation
                    update_best_line(board, ply);
                }
            }

            // Reset the zero width window
            b = a + 1;

        }

    }
    else {
        //--------------------------------------------------------
        //-- Normal moves handled differently (e.g. can stand-pat)
        //--------------------------------------------------------

        //-- Does stand-pat cause a cutoff?
        e = pv->eval->static_score;
        if (e >= beta)
            return e;

        //-- Does the current value raise alpha?
        best_score = e;
        if (e > alpha) {
            a = e;
            pv->best_line_length = ply;
        }

        //-- Generate all captures
        generate_captures(board, moves);

        //-- Order the moves
        order_captures(board, moves);

		//-- Only search break even captures during the PV
		//int threshold = 10;
		//if (beta != alpha + 1)
		int threshold = 0;

        //-- Play moves
        while (make_next_see_positive_move(board, moves, threshold, undo)) {

            //-- Increment the "legal_moves_played" counter
            pv->legal_moves_played++;
            pv->current_move = moves->current_move;

            //-- Evaluate the new board position
            evaluate(board, next_pv->eval);

            //-- Search the next ply at reduced depth
            e = -qsearch(board, ply + 1, depth - 1, -b, -a);

            //-- Is a research required?
            if (alpha + 1 != beta && e > a && a + 1 == b)
                e = -qsearch(board, ply + 1, depth - 1, -beta, -a);

            unmake_move(board, undo);

            //-- Is it good enough to cut-off?
            if (e >= beta)
                return e;

            //-- Is it the best so far?
            if (e > best_score) {
                best_score = e;

                //-- Does it improve upon alpha (i.e. is it part of the PV)?
                if (e > a) {
                    a = e;
                    update_best_line(board, ply);
                }
            }

            // Reset the zero width window
            b = a + 1;

        }
    }

    // Return Best Score found
    return best_score;

}
Esempio n. 9
0
t_chess_value qsearch_plus(struct t_board *board, int ply, int depth, t_chess_value alpha, t_chess_value beta) {

    //-- Principle Variation
    struct t_pv_data *pv = &(board->pv_data[ply]);

    //-- Has the maximum depth been reached
    if (ply >= MAXPLY || uci.stop)
        return pv->eval->static_score;

    //-- Increment the node count
    qnodes++;

    /* check to see if this is a repeated position or draw by 50 moves */
    if (repetition_draw(board)) {
        pv->best_line_length = ply;
        return 0;
    }

    //-- Mate Distance Pruning
    if (CHECKMATE - ply <= alpha) {
        return alpha;
    }
    else if (-CHECKMATE + ply >= beta) {
        return beta;
    }
    else if ((!board->in_check) && (-CHECKMATE + ply + 2 >= beta)) {
        return beta;
    }

    //-- Next Principle Variation
    struct t_pv_data *next_pv = &(board->pv_data[ply + 1]);

    //-- Define the local variables
    pv->legal_moves_played = 0;
    t_chess_value best_score;
    t_chess_value a = alpha;
    t_chess_value b = beta;
	t_chess_value e;

    // Declare local variables
    t_undo undo[1];

    //-- Generate All Moves
    struct t_move_list moves[1];
    moves->hash_move = NULL;

    //-----------------------------------------------
    //-- Handling In-Check (e.g. Cannot Stand-Pat)
    //-----------------------------------------------
    if (board->in_check) {

        best_score = -CHECKMATE;

        //-- Generate moves which get out of check
        generate_evade_check(board, moves);

        // Are we in checkmate?
        if (moves->count == 0) {
            pv->best_line_length = ply;
            return -CHECKMATE + ply;
        }

        t_chess_value(*q_search)(struct t_board *board, int ply, int depth, t_chess_value alpha, t_chess_value beta);

        if (moves->count == 1)
            q_search = &qsearch_plus;
        else {
            q_search = &qsearch;
            //-- Order the moves
            order_evade_check(board, moves, ply);
        }

        //-- Play moves
        while (make_next_best_move(board, moves, undo)) {

            //-- Increment the "legal_moves_played" counter
            pv->legal_moves_played++;
            pv->current_move = moves->current_move;

            //-- Evaluate the new board position
            evaluate(board, next_pv->eval);

            //-- More than one move out of check so just use "vanilla" qsearch
            e = -q_search(board, ply + 1, depth - 1, -b, -a);

            //-- Is a research required?
            if (alpha + 1 != beta && e > a && a + 1 == b)
                e = -q_search(board, ply + 1, depth - 1, -beta, -a);

            unmake_move(board, undo);

            //-- Is it good enough to cut-off?
            if (e >= beta) {
                update_check_killers(pv, 0);
                poke(board->hash, e, ply, depth, HASH_LOWER, pv->current_move);
                return e;
            }

            //-- Is it the best so far?
            if (e > best_score) {
                best_score = e;

                //-- Does it improve upon alpha (i.e. is it part of the PV)?
                if (e > a) {
                    a = e;

                    //-- Update the Principle Variation
                    update_best_line(board, ply);
                }
            }

            // Reset the zero width window
            b = a + 1;

        }
    }
    else {
        //--------------------------------------------------------
        //-- Normal moves handled differently (e.g. can stand-pat)
        //--------------------------------------------------------

        //-- Does stand-pat cause a cut-off?
        e = pv->eval->static_score;
        if (e >= beta)
            return e;

        //-- Does the current value raise alpha?
        best_score = e;
        if (e > alpha) {
            a = e;
            pv->best_line_length = ply;
        }

        //-- Generate all captures
        generate_captures(board, moves);

        //-- Order the moves
        order_captures(board, moves);

        //-- Play *ALL* captures
        while (make_next_best_move(board, moves, undo)) {

            //-- Increment the "legal_moves_played" counter
            pv->legal_moves_played++;
            pv->current_move = moves->current_move;

			//-- Evaluate the new board position
			evaluate(board, next_pv->eval);

			//-- Search the next ply at reduced depth
			e = -qsearch(board, ply + 1, depth - 1, -b, -a);

			//-- Is a research required?
			if (alpha + 1 != beta && e > a && a + 1 == b)
				e = -qsearch(board, ply + 1, depth - 1, -beta, -a);

            unmake_move(board, undo);

            //-- Is it good enough to cut-off?
            if (e >= beta) {
                return e;
            }

            //-- Is it the best so far?
            if (e > best_score) {
                best_score = e;

                //-- Does it improve upon alpha (i.e. is it part of the PV)?
                if (e > a) {
                    a = e;
                    update_best_line(board, ply);
                }
            }

            // Reset the zero width window
            b = a + 1;

        }

		//-- Reset the move count
		moves->count = 0;

        //-- Now Try the checks!
		generate_quiet_checks(board, moves);

		////-- Maybe if there are many, one will be a checkmate?
		//if (moves->count > 4){

		//	while (simple_make_next_move(board, moves, undo)) {

		//		assert(board->in_check);

		//		//-- Generate moves
		//		struct t_move_list evade_check_moves[1];
		//		generate_evade_check(board, evade_check_moves);

		//		//-- Take the move back
		//		unmake_move(board, undo);

		//		//-- Is it Checkmate?
		//		if (evade_check_moves->count == 0){
		//			pv->best_line_length = ply + 1;
		//			e = +CHECKMATE - ply - 1;
		//			return e;
		//		}
		//	}
		//	//-- Reset the real move count 
		//	moves->imove = moves->count;
		//}
		
        //-- Order the moves
        order_moves(board, moves, ply);

        //-- Play moves
        while (make_next_best_move(board, moves, undo)) {

            //-- Increment the "legal_moves_played" counter
            pv->legal_moves_played++;
            pv->current_move = moves->current_move;

            //-- Evaluate the new board position
            evaluate(board, next_pv->eval);

            //-- Search the next ply at reduced depth
            e = -qsearch_plus(board, ply + 1, depth - 1, -b, -a);

            //-- Is a research required?
            if (alpha + 1 != beta && e > a && a + 1 == b)
                e = -qsearch_plus(board, ply + 1, depth - 1, -beta, -a);

            unmake_move(board, undo);

            //-- Is it good enough to cut-off?
            if (e >= beta) {
                poke(board->hash, e, ply, depth, HASH_LOWER, pv->current_move);
                update_killers(pv, 0);
                return e;
            }

            //-- Is it the best so far?
            if (e > best_score) {
                best_score = e;

                //-- Does it improve upon alpha (i.e. is it part of the PV)?
                if (e > a) {
                    a = e;
                    update_best_line(board, ply);
                }
            }

            // Reset the zero width window
            b = a + 1;

        }
    }

    //-- Update Hash
    if (best_score > alpha)
        poke(board->hash, best_score, ply, depth, HASH_EXACT, pv->best_line[ply]);

    // Return Best Score found
    return best_score;
}
Esempio n. 10
0
DWORD san2move(struct board_t *brd,char san[128])
{
    short c,d,idx,to,from,pcs,file,row,found,cap;
    short mvalid[MAXMOVES];
    char buf[128];
    char *str;
    DWORD promotion,mvs[MAXMOVES];
    
    to=from=file=row=-1;
    cap=FALSE;
    pcs=PAWN;
    promotion=0;

    for(c=0;c<=127;c++)
	buf[c]=san[c];
    
    buf[127]='\0';
    str=buf;
    
    /*
	primo passaggio:
	
	cerchiamo di individuare subito gli arrocchi
    */

    if(strncmp(buf,"O-O",strlen("O-O"))==0)
    {
	pcs=KING;
	from=((brd->color==WHITE)?(E1):(E8));
	to=((brd->color==WHITE)?(G1):(G8));
	
	goto third;
    }
    
    if(strncmp(buf,"O-O-O",strlen("O-O-O"))==0)
    {
	pcs=KING;
	from=((brd->color==WHITE)?(E1):(E8));
	to=((brd->color==WHITE)?(C1):(C8));
    
	goto third;
    }
    
    /*
	secondo passaggio:
	
	togliamo i caratteri inutili "x+#" e 
	leggiamo la posizione SAN "normale"
    */

    for(c=0;c<strlen(buf);c++)
    {	
	if((buf[c]=='+')||(buf[c]=='#')||(buf[c]=='x'))
	{
	    if(buf[c]=='x')
		cap=TRUE;
	
	    for(d=c;d<strlen(buf);d++)
		buf[d]=buf[d+1];
	}

	if((buf[c]=='=')&&(strlen(buf)==(c+2)))
	{
	    promotion=promflags(buf[c+1]);
	    buf[c]='\0';
	}
    }

    if(strspn(buf,"123456789NBRQKabcdefgh")!=strlen(buf))
	return 0;

    if((c=inarray(*san,"PNBRQK"))!=-1)
    {
	if(c==PAWN)
	    return 0;

	pcs=c;
	*str++;
    }

    if((strlen(str)>=5)||(strlen(str)<=1))
	return 0;
    
    if(strlen(str)==4)
    {
	if((from=findcoord(str))==-1)
	    return 0;

	if((to=findcoord(str+2))==-1)
	    return 0;
    }
    
    if(strlen(str)==3)
    {	
	row=inarray(*str,"12345678");
	file=inarray(*str,"abcdefgh");

	if((to=findcoord(str+1))==-1)
	    return 0;
    }

    if(strlen(str)==2)
    {
	if((to=findcoord(str))==-1)
	    return 0;    
    }
    
    third:
        
    /*
	terzo passaggio:
	
	generiamo tutte le mosse possibili ed escludiamo
	tutte quelle che non combaciano con i dati in
	nostro possesso
    */
    
    idx=0;
    
    if(cap==TRUE)
	generate_captures(brd,mvs,&idx);
    else
	generate_moves(brd,mvs,&idx);
    
    for(c=0;c<idx;c++)
    {
	makemove(brd,mvs[c]);
	
	mvalid[c]=FALSE;
	
	if(is_in_check(brd,brd->color^1)==FALSE)
	{
	    mvalid[c]=TRUE;
	
	    if(((mvs[c]>>6)&0x3F)!=to)
		mvalid[c]=FALSE;
	    else if(((mvs[c]>>12)&0x7)!=pcs)
		mvalid[c]=FALSE;
	    else if((from!=-1)&&((mvs[c]&0x3F)!=from))