예제 #1
0
int Kyokumen::MakeLegalMoves(Teban teban, Te *teBuf, int *pin)
{
	int pbuf[16*11];
	int teNum = 0;
	if (pin == nullptr) {
		MakePinInf(pbuf);
		pin = pbuf;
	}
	if (teban == SELF && m_ControlE[m_KingS] != 0) {
		return AntiCheck(teban, teBuf, pin, m_ControlE[m_KingS]);
	}
	if (teban == ENEMY && m_ControlS[m_KingE] != 0) {
		return AntiCheck(teban, teBuf, pin, m_ControlS[m_KingE]);
	}
	
	int suji, dan;
	int sujiMax, danMax;
	int StartDan, EndDan;
	
	sujiMax = GetSuji();
	danMax = GetDan();
	
	// 盤上の駒を動かす.
	for (suji=1; suji <= sujiMax; suji++) {
		for (dan=1; dan <= danMax; dan++) {
			KomaPos pos = SUJIDAN2KOMAPOS(suji, dan);
			if ((m_Ban[pos] & teban) != 0) {
				AddMoves(teban, teNum, teBuf, pos, pin[pos]);
			}
		}
	}
	// 歩を打つ.
	if (m_Hand[teban|FU] > 0) {
		for (suji=1; suji <= sujiMax; suji++) {
			// 二歩チェック.
			int nifu = 0;
			for (dan=1; dan <= danMax; dan++) {
				KomaPos pos = SUJIDAN2KOMAPOS(suji, dan);
				if (m_Ban[pos]== (teban|FU)) {
					nifu = true;
					break;
				}
			}
			if (nifu) continue;
			// (先手なら2段目より下に、後手なら8段目より上に打つ).
			if (teban == SELF) {
				StartDan = 2;
				EndDan = danMax;
			} else {
				StartDan = 1;
				EndDan = danMax-1;
			}
			for (dan=StartDan; dan<=EndDan; dan++) {
				// 打ち歩詰めもチェック.
				KomaPos pos = SUJIDAN2KOMAPOS(suji, dan);
				if (m_Ban[pos] == EMPTY && !Utifudume(teban, pos, pin)) {
					teBuf[teNum++] = Te(0, pos, teban|FU, EMPTY);
				}
			}
		}
	}
	// 香を打つ.
	if (m_Hand[teban|KY] > 0) {
		for (suji=1; suji <= sujiMax; suji++) {
			// (先手なら2段目より下に、後手なら8段目より上に打つ).
			if (teban == SELF) {
				StartDan = 2;
				EndDan = danMax;
			} else {
				StartDan = 1;
				EndDan = danMax-1;
			}
			for (dan=StartDan; dan <= EndDan; dan++) {
				KomaPos pos = SUJIDAN2KOMAPOS(suji, dan);
				if (m_Ban[pos] == EMPTY) {
					teBuf[teNum++] = Te(0, pos, teban|KY, EMPTY);
				}
			}
		}
	}
	// 桂を打つ.
	if (m_Hand[teban|KE] > 0) {
		// (先手なら3段目より下に、後手なら7段目より上に打つ).
		for(suji=1; suji <= sujiMax; suji++) {
			if (teban == SELF) {
				StartDan = 3;
				EndDan = danMax;
			} else {
				StartDan = 1;
				EndDan = danMax-2;
			}
			for (dan=StartDan; dan <= EndDan; dan++) {
				KomaPos pos = SUJIDAN2KOMAPOS(suji, dan);
				if (m_Ban[pos] == EMPTY) {
					teBuf[teNum++] = Te(0, pos, teban|KE, EMPTY);
				}
			}
		}
	}
	// 銀〜飛車は、どこにでも打てる.
	for (int koma=GI; koma <= HI; koma++) {
		if (m_Hand[teban|koma] > 0) {
			for (suji=1; suji <= sujiMax; suji++) {
				for (dan=1; dan <= danMax; dan++) {
					KomaPos pos = SUJIDAN2KOMAPOS(suji, dan);
					if (m_Ban[pos] == EMPTY) {
						teBuf[teNum++] = Te(0, pos, teban|koma, EMPTY);
					}
				}
			}
		}
	}
	
	return teNum;
}
예제 #2
0
int CNegaScout_TT_HH::NegaScout(int depth, int alpha, int beta){
	int count,i;
	int type;
	int a,b,t;
	int side;
	int score;
	
	i = IsGameOver(m_cur_position, depth);
	if (i != 0)
		return i;
	
	side = 1-(m_max_depth-depth)%2;
	
	score = m_tt->LookupHashTable(alpha, beta, depth, side);
	if (score != INVALID_SCORE && depth != m_max_depth){
		/*if (depth == m_max_depth){
			ChessMove move = new ChessMove();
			move.Move = m_tt.LookupBestMove(side);
			m_best_move = move;
		}*/
		return score;
	}
	
	if (depth <= 0)	
	{
		score = m_evaluator->Evaluate(m_cur_position, side == 0, depth);
		m_tt->EnterHashTable(EXACT, score, depth, side);
		return score;
	}
	
	//m_nMovecount = 0;
	count = m_move_generator->CreatePossibleMove(m_cur_position, m_moves, depth, side);
	AddMoves(count, depth);
	
	for (i = 0; i < count; ++i) 
	{
		m_move_list[depth][i].m_score = m_hh->GetHistoryScore(m_move_list[depth][i]);
	}
	m_hh->MergeSort(m_move_list[depth], count, false);
	
	int bestmove = -1;
	
    a = alpha;
    b = beta;
    int eval_is_exact = 0;
    for (i = 0; i < count; ++i){
		m_tt->HashMakeMove(m_move_list[depth][i], m_cur_position);
		type = MakeMove(m_move_list[depth][i]);

		t = -NegaScout(depth-1 , -b, -a);

		if (t > a && t < beta && i > 0){
			a = -NegaScout (depth-1, -beta, -t);     /* re-search */
			eval_is_exact = 1; 
			if(depth == m_max_depth){
				m_best_move = m_move_list[depth][i];
				//m_tt.EnterHashBestMove(m_best_move.Move, side);
			}
			bestmove = i; 
		}
		
		m_tt->HashUnmakeMove(m_move_list[depth][i], type, m_cur_position); 
		UnmakeMove(m_move_list[depth][i],type); 
		if (a < t){
			eval_is_exact = 1;
			a = t;
			if(depth == m_max_depth) {
				m_best_move = m_move_list[depth][i];
				//m_tt.EnterHashBestMove(m_best_move.Move, side);
			}
		}
		if (a >= beta) 
		{
			m_tt->EnterHashTable(LOWER_BOUND, a, depth, side);
			m_hh->EnterHistoryScore(m_move_list[depth][i], depth);
			return a;
		}
		b = a + 1;                      /* set new null window */
	}
	if (bestmove != -1)
		m_hh->EnterHistoryScore(m_move_list[depth][bestmove], depth);
	if (eval_is_exact != 0) 
		m_tt->EnterHashTable(EXACT, a, depth, side);
	else 
		m_tt->EnterHashTable(UPPER_BOUND, a, depth, side);
	return a;
}