Пример #1
0
int play(int me, int opponent, int row, int col, bool first_player, move_t **moves) {

  bool can_capture_right, can_capture_left;
  move_t *moves_right, *moves_left;
  int score_right = 0;
  int score_left = 0;

  if (me == BLACK) {
    D printf("BLACK: ");

    can_capture_left = can_capture(me,opponent,row,col,row+1,col+1,row+2,col+2);
    can_capture_right = can_capture(me,opponent,row,col,row+1,col-1,row+2,col-2);
   
    D printf(" From (%d,%d): Right? %s Left? %s\n",row,col,(can_capture_right ? "Yes" : "No"),
	   (can_capture_left ? "Yes" : "No"));

    if (can_capture_left)
      score_left = 1 + test_capture(me,opponent,row,col,row+1,col+1,row+2,col+2,first_player,&moves_left);
    if (can_capture_right)
      score_right = 1 + test_capture(me,opponent,row,col,row+1,col-1,row+2,col-2,first_player,&moves_right);

    moves_left = move_gen(row+2,col+2,moves_left);
    moves_right = move_gen(row+2,col-2,moves_right);

  } else {

    D printf("WHITE: ");

    can_capture_left = can_capture(me,opponent,row,col,row-1,col-1,row-2,col-2);
    can_capture_right = can_capture(me,opponent,row,col,row-1,col+1,row-2,col+2);

    if (can_capture_left)
      score_left = 1 + test_capture(me,opponent,row,col,row-1,col-1,row-2,col-2,first_player,&moves_left);
    if (can_capture_right)
      score_right = 1 + test_capture(me,opponent,row,col,row-1,col+1,row-2,col+2,first_player,&moves_right);
    
    moves_left = move_gen(row-2,col-2,moves_left);
    moves_right = move_gen(row-2,col+2,moves_right);
  }

  if ((!can_capture_right) && (!can_capture_left) && first_player) {
    move_t *temp_moves;
    *moves = NULL;
    D printf(" returning 0 (no captures available)\n");
    return - find_best_move(opponent,me,false,&temp_moves); 
  }  else {
    if ((can_capture_left && (!can_capture_right)) ||
	(can_capture_left && can_capture_right && (score_left > score_right))) {
      *moves = moves_left;
      D printf(" returning %d (score_left)\n",score_left);
      return score_left;
    } else {
      *moves = moves_right;
      D printf(" returning %d (score_right)\n",score_right);
      return score_right;
    }
  }
}
Пример #2
0
void test_divide(int depth)
{
  int i,move_count;
  move_t ms[MOVE_STACK];
  uint64 nodes;
  uint64 total_nodes;
  int legal_moves;
  #ifdef EVASIONS
  char strbuff[256];
  move_t ms_test[MOVE_STACK];
  #endif
  
  if(!depth) return;
  nodes = 0;
  total_nodes = 0;
  legal_moves = 0;
  
  pht_init();
  depth -= 1;
  timer_start();
    
  #ifdef EVASIONS
  if(is_in_check(board->side))
  { move_count = move_gen_evasions(&ms[0]);
    if(move_count != move_gen_legal(&ms_test[0]))
    { board_to_fen(&strbuff[0]);
      printf("error: \n %s \n",strbuff);
    }
  }
  else
  { move_count = move_gen(&ms[0]);
  }
  #else
  move_count = move_gen(&ms[0]);
  #endif
    
  for(i = 0; i < move_count; i++)
  { if(!move_make(ms[i])) continue;
    nodes = perft(depth);
    print_move(ms[i].p);
    legal_moves++;
    printf("%I64u",nodes);
    printf("\n");
    move_undo();
    total_nodes += nodes;
  }
  printf("\nNodes: %I64u",total_nodes);
  printf("\nMoves: %d",legal_moves);
  printf("\n\n");
  timer_stop();
  pht_free();
}
Пример #3
0
int find_best_move(int me, int opponent, bool first_player, move_t **moves) {
  int best_score, best_row, best_col;
  move_t *best_moves;
  bool first = true;
  for (int row=0; row<8; row++) 
    for (int col=0; col<8; col++) 
      if (board[row][col] == me) {
       	int score;
	move_t *move_list;
	D printf("Looking for the best moves starting from (%d,%d)\n",row,col);
	score = play(me,opponent,row,col,first_player,&move_list);
	D printf("The score from (%d,%d) was %d\n",row,col,score);
	if ((score > best_score) || first) {
	  D printf("This is the new best score.\n");
	  best_score = score;
	  best_row = row;
	  best_col = col;
	  best_moves = move_list;
	  first = false;
	}
      }
  D printf("Making the final move_gen()\n");
  *moves = move_gen(best_row,best_col,best_moves);
  return best_score;
}
Пример #4
0
void test_pawn_divide(int depth)
{
  int i,move_count;
  move_t ms[MOVE_STACK];
  uint64 nodes = 0;
  uint64 total_nodes = 0;
  int legal_moves = 0;
  
  if(!depth) return;
  pawnhits = 0;
  pawncollisions = 0;
  pht_init();
  depth -= 1;
  timer_start();
  move_count = move_gen(&ms[0]);
  for(i = 0; i < move_count; i++)
  {
    if(!move_make(ms[i])) continue;
    nodes = perft(depth);
    print_move(ms[i].p);
    legal_moves++;
    printf("%I64u",nodes);
    printf("\n");
    move_undo();
    total_nodes += nodes;
  }
  printf("\nNodes: %I64u",total_nodes);
  printf("\nMoves: %d",legal_moves);
  printf("\nPawnHits: %d",pawnhits);
  printf("\nPawnCollisions: %d",pawncollisions);
  printf("\n\n");
  timer_stop();
  pht_free();
}
Пример #5
0
// Nega-max演算法(recursive)
// board: 盤面資訊(0~59), 表示法如下(X:邊界, 0:棋盤格子):
// XXXXXX
// X0000X
// X0000X
// X0000X
// X0000X
// X0000X
// X0000X
// X0000X
// X0000X
// XXXXXX
//
// piece_num: 記錄各兵種之存活棋子數
// dark_num: 記錄可翻棋子數
// red_num, black_num: 紅黑存活棋子數
// turn: 輪走方
// depth: 目前深度
// max_depth: 最大深度
int search(int board[BOARD_SIZE], int piece_num[PIECE_TYPE], int dark_num, int red_num, int black_num, int turn, int depth, int max_depth, clock_t t)
{
	int s[MAX_MOVE], d[MAX_MOVE], cap_s[MAX_MOVE], cap_d[MAX_MOVE];
	int i, m, n;
	int curr_score, score, value;
	int src, dest, cap;
	int factor;

	// factor: 將分數轉換為相對於自己的分數
	factor = (turn == RED) ? 1 : -1;
	// 終止條件
	if(red_num == 0)
		return -(MAX_SCORE-depth-1) * factor;
	if(black_num == 0)
		return (MAX_SCORE-depth-1) * factor;
	if(depth == max_depth)
		return factor * eval(piece_num);

	src = 0;
	dest = 0;
	score = -MAX_SCORE;
	if(clock() > t)
		return score;
	// 產生走法
	move_gen(board, turn, s, d, &n, cap_s, cap_d, &m);
//	if(depth == 1)
//		printf("%d %d\n", n, m);
	// 對吃子步進行搜尋
	for(i = 0; i < m; i++){
		cap = move(board, piece_num, &red_num, &black_num, cap_s[i], cap_d[i]);
		value = -search(board, piece_num, dark_num, red_num, black_num, !turn, depth + 1, max_depth, t);
		if(value >= score){
			score = value;
			src = cap_s[i];
			dest = cap_d[i];
		}
		unmove(board, piece_num, &red_num, &black_num, cap_s[i], cap_d[i], cap);
//		if(depth == 1)
//			printf("%d %d %d\n", value, cap_s[i], cap_d[i]);
	}
	// 對走子步進行搜尋
	for(i = 0; i < n; i++){
		cap = move(board, piece_num, &red_num, &black_num, s[i], d[i]);
		value = -search(board, piece_num, dark_num, red_num, black_num, !turn, depth + 1, max_depth, t);
		if(value >= score){
			score = value;
			src = s[i];
			dest = d[i];
		}
		unmove(board, piece_num, &red_num, &black_num, s[i], d[i], cap);
//		if(depth == 1)
//			printf("%d %d %d\n", value, s[i], d[i]);
	}
	// 計算當前盤面之審局分數
	curr_score = eval(piece_num) * factor;
	// 判斷是否執行null move
	if(dark_num > 0 && score <= curr_score){
		value = -search(board, piece_num, dark_num, red_num, black_num, !turn, depth + 1, max_depth, t);
		if(value >= score){
			score = value;
			src = 0;
			dest = 0;
		}
//		if(depth == 1)
//			printf("%d 0 0\n", value);
	}
	if(depth == 1){
		best_src = src;
		best_dest = dest;
	}
	return score;
}
Пример #6
0
uint64 perft(int depth)
{ 
  int i,move_count;
  move_t ms[MOVE_STACK];
  uint64 nodes;
  uint64 val;
  #ifdef EVASIONS
  char strbuff[256];
  move_t ms_test[MOVE_STACK];
  #endif
  #ifdef BITS
  bitboard_t bb;
  #endif
  
  if(depth == 0) return 1;
  if((val = probe_hash(depth)) != 0) 
    return val;

  nodes = 0;
  val = 0;
    
  #ifdef BITS
  bb = 0;
  for(i = PLS(WP); i <= H8; i = PLN(i))
    bitset(&bb, rsz[i]);
  if(bb != board->bb_pawns[W])
    printf("pawn_error\n");
  bb = 0;
  for(i = PLS(BP); i <= H8; i = PLN(i))
    bitset(&bb, rsz[i]);
  if(bb != board->bb_pawns[B])
    printf("pawn_error\n");
  #endif
  
  #ifdef EVASIONS
  if(is_in_check(board->side))
  { move_count = move_gen_evasions(&ms[0]);
    if(move_count != move_gen_legal(&ms_test[0]))
    { board_to_fen(&strbuff[0]);
      printf("error: \n %s \n",strbuff);
    }
  }
  else
  { move_count = move_gen(&ms[0]);
  }
  #else
  move_count = move_gen(&ms[0]);
  #endif
    
  for(i = 0; i < move_count; i++)
  { if(!move_make(ms[i])) continue;
    if(depth == 1)
      nodes++;
    else
      nodes += perft(depth - 1);

    move_undo();
  }
  record_hash(depth,nodes);
  return (nodes);
}