コード例 #1
0
ファイル: search.c プロジェクト: dylhunn/fianchetto
// Compute the amount of time to spend on the next move
// Some parameters might be -1 if they do not apply
int time_use(board *b, int time_left, int increment, int movestogo) {
	if (time_left <= 0) return 100; // Oops!

	// Algorithm for remaining move estimation based on:
	// http://facta.junis.ni.ac.rs/acar/acar200901/acar2009-07.pdf
	// Slightly more aggresive time managment because of overhead after search

	// Calculate the total value of material
	int mat_value = 0;
	for (int i = 0; i < 8; i++) {
		for (int j = 0; j < 8; j++) {
			if (p_eq(b->b[i][j], no_piece)) continue;
			switch(b->b[i][j].type) {
				case 'P': mat_value += 1; break;
				case 'N': mat_value += 3; break;
				case 'B': mat_value += 3; break;
				case 'R': mat_value += 5; break;
				case 'Q': mat_value += 9; break;
				default: ;
			}
		}
	}
	// Assume the game is 70 moves long, but never use more than 1/10th of the remaining time
	int half_moves_left_guess;
	if (mat_value < 20) half_moves_left_guess = mat_value + 10;
	else if (mat_value <= 60) half_moves_left_guess = (mat_value * 3 + 176) / 8;
	else half_moves_left_guess = (mat_value * 5 - 120) / 4;
	half_moves_left_guess += 6; // Adjustment for search invocation overhead
	int our_moves_left_guess = max(5, (half_moves_left_guess / 2));
	return time_left/our_moves_left_guess;
}
コード例 #2
0
/* Pair : row,column */
int lee_algo(Pair* source, Pair* target){
  int i, j, v1, v2;
  Pair p, v, step[4] = {{1,0},{0,1},{-1,0},{0,-1}};
  /* initialize all cells like unvisited */
  for(i=0; i<sz.r; ++i){
    for(j=0; j<sz.c; ++j){
      W[i][j] = -1;
    }
  }
  q_clear();
  p_set(W,source,0);
  q_push(source);
  while(!q_empty()){
    p = q_pop();
    for(i=0; i<4; ++i){
      v = p_sum(step+i,&p);
      v1 = p_get(Z,&p); 
      v2 = p_get(Z,&v);
      #ifdef DEBUG
      printf("try: %d,%d\n",v.r,v.c);
      #endif
      if(p_in(&v) && p_get(W,&v)==-1 && (v1-v2 <= 3) && (v1-v2 >= -1) && can_go(&v)){
        
        #ifdef DEBUG
        printf("from: %d,%d go: %d,%d\n",p.r,p.c,v.r,v.c);
        #endif
        
        p_set(W,&v,p_get(W,&p)+1);
        q_push(&v);
        if(p_eq(&v,target)) break;
      }
    }
    if(p_eq(&v,target)) break;
  }
  #ifdef DEBUG
  printf("q: %d\n",q_empty());
  #endif
  return p_get(W,target);
}
コード例 #3
0
int hadlock_algo(Pair* source, Pair* target){
  int i, j, v1, v2, res;
  Pair p, v, step[4] = {{1,0},{0,1},{-1,0},{0,-1}};
  /* initialize all cells like unvisited */
  for(i=0; i<sz.r; ++i){
    for(j=0; j<sz.c; ++j){
      W[i][j] = -1;
    }
  }
  q_clear();
  p_set(W,source,0);
  q_push(source);
  while(!q_empty()){
    p = q_pop();
    for(i=0; i<4; ++i){
      v = p_sum(step+i,&p);
      v1 = p_get(Z,&p); 
      v2 = p_get(Z,&v);
      if(p_in(&v) && (p_get(W,&v)==-1 || (p_get(W,&v)>p_get(W,&p))) && (v1-v2 <= 3) && (v1-v2 >= -1) && can_go(&v)){
        if(p_mhtn_norm(&v,target) < p_mhtn_norm(&p,target)){
          p_set(W,&v,p_get(W,&p));
          q_push_back(&v);
        }else{ /* > */
          /*if(!(p_get(W,&v)!=-1 || (p_get(W,&v)==p_get(W,&p)+1))){ */
          p_set(W,&v,p_get(W,&p)+1);
          q_push_front(&v);  
        }
        if(p_eq(&v,target)){
          break;
        }
      }
    }
    if(p_eq(&v,target)) break;
  }
  res = p_get(W,target);
  if(res != -1) res = 2*res+p_mhtn_norm(source,target); 
  return res;
}
コード例 #4
0
int can_go(Pair* p){
  Pair *b = bts;
  Pair s, t, md, mv, mh, next, buf1, buf2, buf3;
  int v, h, ver, hor; /* coordinate steps */
  double val;
  int vis;
  
  while(b != bts+2){
    ln_init(b,p_get(Z,b)+0.5,p,p_get(Z,p)+0.5);
    /* go from the bottom up */
    if(p_get(Z,p) < p_get(Z,b)){
      s = *p;
      t = *b;
    }else{
      s = *b;
      t = *p;
    }
    
    hor = (s.c > t.c) ? -1 : 1;
    ver = (s.r > t.r) ? -1 : 1;
    
    #ifdef DEBUG
    printf("v: %d, h: %d\n",ver,hor);
    #endif
    
    h = (hor>0) ? 0 : 1;
    v = (ver>0) ? 0 : 1;
    
    vis = 1;
    while(!p_eq(&s,&t)){
      md = p_new(ver,hor);
      md = p_sum(&s,&md);
      buf1 = p_new(md.r+v,md.c+h);
      if(ln_rc_val(&buf1)==0){
        val = ln_z_by_r(buf1.r);
        next = md;  
      }else{
        mv = p_new(ver,0);
        mv = p_sum(&s,&mv);
        buf2 = p_new(mv.r+v,mv.c+h);
        if(!ln_rc_on_same_side(&buf1,&buf2)){
          val = ln_z_by_r(buf2.r);
          next = mv;    
        }else{
          mh = p_new(0,hor);
          mh = p_sum(&s,&mh);
          buf3 = p_new(mh.r+v,mh.c+h);
          val = ln_z_by_c(buf3.c);
          next = mh;
        }
      }
      #ifdef DEBUG
      printf("next %d,%d\n",next.r,next.c);
      #endif
      if(p_get(Z,&next) > val){
        
        #ifdef DEBUG
        printf("bad p: %d,%d val: %f\n",next.r,next.c,val);
        #endif
        
        vis = 0;
        break;
      }
      s = next;
    }
    if(vis) break;
    ++b; /* take next bts */
  }
  return vis;
}
コード例 #5
0
ファイル: search.c プロジェクト: dylhunn/fianchetto
void unapply(board *b, move m) {
	// Information
	piece old_piece = p_eq(m.promote_to, no_piece) ? at(b, m.to) : (piece){'P', at(b, m.to).white};

	// If we are unapplying a double pawn push, disable en passant
	if (b->en_passant_pawn_push_col_history[b->last_move_ply] != -1) {
		b->hash ^= zobrist_en_passant_files[b->en_passant_pawn_push_col_history[b->last_move_ply]];
	}

	// Transform board and hash
	b->hash ^= tt_pieceval(b, m.to);
	set(b, m.from, old_piece);
	set(b, m.to, m.captured);
	b->hash ^= tt_pieceval(b, m.from);
	b->hash ^= tt_pieceval(b, m.to);
	b->hash ^= zobrist_black_to_move;
	b->black_to_move = !b->black_to_move;
	b->last_move_ply--;

	// If the previous move was a double pawn push, enable en passant
	if (b->en_passant_pawn_push_col_history[b->last_move_ply] != -1) {
		b->hash ^= zobrist_en_passant_files[b->en_passant_pawn_push_col_history[b->last_move_ply]];
	}

	// If we just unapplied an en passant move, put the pawn back
	if (m.en_passant_capture) {
		uint8_t en_passant_capture_row = old_piece.white ? 4 : 3;
		coord en_pasant_capture_square = (coord){b->en_passant_pawn_push_col_history[b->last_move_ply], en_passant_capture_row};
		piece captured_pawn = (piece) {'P', !old_piece.white};
		set(b, en_pasant_capture_square, captured_pawn);
	}

	if (old_piece.type == 'K') {
		if (old_piece.white) b->white_king = m.from;
		else b->black_king = m.from;
	}
	
	// Manually move rook for castling
	if (m.c != N) { // Manually move rook
		uint8_t rook_to_col = ((m.c == K) ? 7 : 0);
		uint8_t rook_from_col = ((m.c == K) ? 5 : 3);
		b->hash ^= tt_pieceval(b, (coord){rook_from_col, m.from.row});
		b->b[rook_to_col][m.to.row] = (piece){'R', at(b, m.from).white};
		b->b[rook_from_col][m.from.row] = no_piece;
		b->hash ^= tt_pieceval(b, (coord){rook_to_col, m.to.row});
	}

	// Restore castling rights
	if (b->castle_wq_lost_on_ply == b->last_move_ply + 1) {
		b->castle_rights_wq = true;
		b->hash ^= zobrist_castle_wq;
		b->castle_wq_lost_on_ply = -1;
	}
	if (b->castle_wk_lost_on_ply == b->last_move_ply + 1) {
		b->castle_rights_wk = true;
		b->hash ^= zobrist_castle_wk;
		b->castle_wk_lost_on_ply = -1;
	}
	if (b->castle_bq_lost_on_ply == b->last_move_ply + 1) {
		b->castle_rights_bq = true;
		b->hash ^= zobrist_castle_bq;
		b->castle_bq_lost_on_ply = -1;
	}
	if (b->castle_bk_lost_on_ply == b->last_move_ply + 1) {
		b->castle_rights_bk = true;
		b->hash ^= zobrist_castle_bk;
		b->castle_bk_lost_on_ply = -1;
	}
}
コード例 #6
0
ファイル: search.c プロジェクト: dylhunn/fianchetto
void apply(board *b, move m) {
	// Disable the old en passant eligibility for a file
	if (b->en_passant_pawn_push_col_history[b->last_move_ply] != -1) {
		b->hash ^= zobrist_en_passant_files[b->en_passant_pawn_push_col_history[b->last_move_ply]];
	}

	// Information
	piece moved_piece = at(b, m.from);
	piece new_piece = p_eq(m.promote_to, no_piece) ? moved_piece : m.promote_to;

	// If the move we will apply is en passant, remove the captured pawn
	if (m.en_passant_capture) {
		uint8_t en_passant_capture_row = moved_piece.white ? 4 : 3;
		coord en_pasant_capture_square = (coord){b->en_passant_pawn_push_col_history[b->last_move_ply], en_passant_capture_row};
		set(b, en_pasant_capture_square, no_piece);
	}

	// Transform board and hash
	b->hash ^= tt_pieceval(b, m.from);
	b->hash ^= tt_pieceval(b, m.to);
	set(b, m.to, new_piece);
	set(b, m.from, no_piece);
	b->hash ^= tt_pieceval(b, m.to);
	b->hash ^= zobrist_black_to_move;
	b->black_to_move = !b->black_to_move;
	b->last_move_ply++;

	// For en passant
	b->en_passant_pawn_push_col_history[b->last_move_ply] = -1;
	if (at(b, m.to).type == 'P' && abs(m.to.row - m.from.row) == 2) {
		b->en_passant_pawn_push_col_history[b->last_move_ply] = m.to.col;
		// En passant capture now enabled on this file
		b->hash ^= zobrist_en_passant_files[b->en_passant_pawn_push_col_history[b->last_move_ply]];
	}

	// Manually move rook for castling
	if (m.c != N) { // Manually move rook
		uint8_t rook_from_col = ((m.c == K) ? 7 : 0);
		uint8_t rook_to_col = ((m.c == K) ? 5 : 3);
		b->hash ^= tt_pieceval(b, (coord){rook_from_col, m.from.row});
		b->b[rook_to_col][m.to.row] = (piece){'R', at(b, m.to).white}; // !!
		b->b[rook_from_col][m.from.row] = no_piece;
		b->hash ^= tt_pieceval(b, (coord){rook_to_col, m.to.row});
	}

	// King moves always strip castling rights
	if (moved_piece.white && moved_piece.type == 'K') {
		if (b->castle_rights_wk) {
			b->hash ^= zobrist_castle_wk;
			b->castle_wk_lost_on_ply = b->last_move_ply;
			b->castle_rights_wk = false;
		}
		if (b->castle_rights_wq) {
			b->hash ^= zobrist_castle_wq;
			b->castle_wq_lost_on_ply = b->last_move_ply;
			b->castle_rights_wq = false;
		}
	} else if (!moved_piece.white && moved_piece.type == 'K') {
		if (b->castle_rights_bk) {
			b->hash ^= zobrist_castle_bk;
			b->castle_bk_lost_on_ply = b->last_move_ply;
			b->castle_rights_bk = false;
		}
		if (b->castle_rights_bq) {
			b->hash ^= zobrist_castle_bq;
			b->castle_bq_lost_on_ply = b->last_move_ply;
			b->castle_rights_bq = false;
		}
	}

	if (moved_piece.type == 'K') {
		if (moved_piece.white) b->white_king = m.to;
		else b->black_king = m.to;
	}

	// Moves involving rook squares always strip castling rights
	if ((c_eq(m.from, wqr) || c_eq(m.to, wqr)) && b->castle_rights_wq) {
		b->castle_rights_wq = false;
		b->hash ^= zobrist_castle_wq;
		b->castle_wq_lost_on_ply = b->last_move_ply;
	}
	if ((c_eq(m.from, wkr) || c_eq(m.to, wkr)) && b->castle_rights_wk) {
		b->castle_rights_wk = false;
		b->hash ^= zobrist_castle_wk;
		b->castle_wk_lost_on_ply = b->last_move_ply;
	}
	if ((c_eq(m.from, bqr) || c_eq(m.to, bqr)) && b->castle_rights_bq) {
		b->castle_rights_bq = false;
		b->hash ^= zobrist_castle_bq;
		b->castle_bq_lost_on_ply = b->last_move_ply;
	}
	if ((c_eq(m.from, bkr) || c_eq(m.to, bkr)) && b->castle_rights_bk) {
		b->castle_rights_bk = false;
		b->hash ^= zobrist_castle_bk;
		b->castle_bk_lost_on_ply = b->last_move_ply;
	}
}