Skip to content

Commit

Permalink
- CAPTURES_PRO_PLUSの指し手生成バグってる問題。
Browse files Browse the repository at this point in the history
	これ、歩の不成の場合、駒を捕獲する指し手しか生成してはならない。
	歩の成りの場合、駒を捕獲しなくともOK。この条件を守る指し手生成、難しい。
	→ この実装、やめる。

	// ↓廃止

	// note : 
CAPTURES_PRO_PLUSとNON_CAPTURES_PRO_MINUSとの生成される指し手の集合も被覆していない。
	// → 被覆させないことで、二段階に指し手生成を分解することが出来る。

	CAPTURES_PRO_PLUS_ALL,      // CAPTURES_PRO_PLUS + 
歩の不成で捕獲する指し手なども含む(捕獲しないなら含まない)
	NON_CAPTURES_PRO_MINUS_ALL, // NON_CAPTURES_PRO_MINUS + 歩の不成なども含む

- Unittestに指し手生成の歩の不成のテスト追加。
  • Loading branch information
yaneurao committed Jan 23, 2022
1 parent 1049d7e commit ca89b8b
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 18 deletions.
23 changes: 14 additions & 9 deletions source/movegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,15 @@ template <MOVE_GEN_TYPE GenType, Color Us, bool All> struct GeneratePieceMoves<G
// ただしAll(全合法手を生成するとき)だけは不成も生成
// また、移動先の升が1段目は、成れないのでその指し手生成は除外
if (All && rank_of(to) != T_RANK1)
{
// CAPTURE_PRO_PLUSに対しては、捕獲できないなら、不成の歩の指し手を生成してはならない。
// toに自駒がないことはすでに保証されている。(移動できるので)
//if (GenType == CAPTURES_PRO_PLUS && !pos.piece_on(to))
// continue;
// → CAPTURE_PRO_PLUS_ALLは実装ややこしいから廃止する。

mlist++->move = make_move(from, to, Us, PAWN);
}
}
else
mlist++->move = make_move(from, to , Us, PAWN);
Expand Down Expand Up @@ -901,8 +909,8 @@ ExtMove* generateMoves(const Position& pos, ExtMove* mlist, Square recapSq)
// 歩の不成などを含め、すべての指し手を生成するのか。
// GenTypeの末尾に"ALL"とついているものがその対象。
const bool All = (GenType == EVASIONS_ALL) || (GenType == CHECKS_ALL) || (GenType == LEGAL_ALL)
|| (GenType == NON_EVASIONS_ALL) || (GenType == RECAPTURES_ALL) || (GenType == QUIET_CHECKS_ALL)
|| (GenType == CAPTURES_PRO_PLUS_ALL) || (GenType == NON_CAPTURES_PRO_MINUS_ALL);
|| (GenType == NON_EVASIONS_ALL) || (GenType == RECAPTURES_ALL) || (GenType == QUIET_CHECKS_ALL);
//|| (GenType == CAPTURES_PRO_PLUS_ALL) || (GenType == NON_CAPTURES_PRO_MINUS_ALL);

if (GenType == LEGAL || GenType == LEGAL_ALL)
{
Expand Down Expand Up @@ -951,8 +959,8 @@ ExtMove* generateMoves(const Position& pos, ExtMove* mlist, Square recapSq)
GenType == NON_EVASIONS_ALL ? NON_EVASIONS :
GenType == RECAPTURES_ALL ? RECAPTURES :
GenType == EVASIONS_ALL ? EVASIONS :
GenType == CAPTURES_PRO_PLUS_ALL ? CAPTURES_PRO_PLUS :
GenType == NON_CAPTURES_PRO_MINUS_ALL ? NON_CAPTURES_PRO_MINUS :
//GenType == CAPTURES_PRO_PLUS_ALL ? CAPTURES_PRO_PLUS :
//GenType == NON_CAPTURES_PRO_MINUS_ALL ? NON_CAPTURES_PRO_MINUS :
GenType; // さもなくば元のまま。
return generateMoves<GenType2, All>(pos, mlist, recapSq);
}
Expand All @@ -971,11 +979,8 @@ ExtMove* generateMoves(const Position& pos, ExtMove* mlist)
template ExtMove* generateMoves<NON_CAPTURES >(const Position& pos, ExtMove* mlist);
template ExtMove* generateMoves<CAPTURES >(const Position& pos, ExtMove* mlist);

template ExtMove* generateMoves<NON_CAPTURES_PRO_MINUS >(const Position& pos, ExtMove* mlist);
template ExtMove* generateMoves<NON_CAPTURES_PRO_MINUS_ALL>(const Position& pos, ExtMove* mlist);

template ExtMove* generateMoves<CAPTURES_PRO_PLUS >(const Position& pos, ExtMove* mlist);
template ExtMove* generateMoves<CAPTURES_PRO_PLUS_ALL >(const Position& pos, ExtMove* mlist);
template ExtMove* generateMoves<NON_CAPTURES_PRO_MINUS>(const Position& pos, ExtMove* mlist);
template ExtMove* generateMoves<CAPTURES_PRO_PLUS >(const Position& pos, ExtMove* mlist);

template ExtMove* generateMoves<EVASIONS >(const Position& pos, ExtMove* mlist);
template ExtMove* generateMoves<EVASIONS_ALL >(const Position& pos, ExtMove* mlist);
Expand Down
13 changes: 8 additions & 5 deletions source/movepick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ MovePicker::MovePicker(const Position& p, Move ttm, Value th , const CapturePiec
// ProbCutにおいて、SEEが与えられたthresholdの値以上の指し手のみ生成する。
// (置換表の指しても、この条件を満たさなければならない)
// 置換表の指し手がないなら、次のstageから開始する。
stage = PROBCUT_TT + !(ttm && pos.capture(ttm)
&& pos.pseudo_legal(ttm)
&& pos.see_ge(ttm, threshold));
stage = PROBCUT_TT + !(ttm && pos.capture_or_pawn_promotion(ttm)
&& pos.pseudo_legal(ttm)
&& pos.see_ge(ttm, threshold));

}

Expand Down Expand Up @@ -295,7 +295,9 @@ Move MovePicker::next_move(bool skipQuiets) {
case QCAPTURE_INIT:
cur = endBadCaptures = moves;

endMoves = Search::Limits.generate_all_legal_moves ? generateMoves<CAPTURES_PRO_PLUS_ALL>(pos, cur) : generateMoves<CAPTURES_PRO_PLUS>(pos, cur);
//endMoves = Search::Limits.generate_all_legal_moves ? generateMoves<CAPTURES_PRO_PLUS_ALL>(pos, cur) : generateMoves<CAPTURES_PRO_PLUS>(pos, cur);
// → Probcutとかでしか使わないから、CAPTURES_PRO_PLUS_ALLは廃止する。
endMoves = generateMoves<CAPTURES_PRO_PLUS>(pos, cur);

// 駒を捕獲する指し手に対してオーダリングのためのスコアをつける
score<CAPTURES>();
Expand Down Expand Up @@ -356,7 +358,8 @@ Move MovePicker::next_move(bool skipQuiets) {
cur = (ExtMove*)Math::align((size_t)cur, 32);
#endif

endMoves = Search::Limits.generate_all_legal_moves ? generateMoves<NON_CAPTURES_PRO_MINUS_ALL>(pos, cur) : generateMoves<NON_CAPTURES_PRO_MINUS>(pos, cur);
//endMoves = Search::Limits.generate_all_legal_moves ? generateMoves<NON_CAPTURES_PRO_MINUS_ALL>(pos, cur) : generateMoves<NON_CAPTURES_PRO_MINUS>(pos, cur);
endMoves = generateMoves<NON_CAPTURES_PRO_MINUS>(pos, cur);

// 駒を捕獲しない指し手に対してオーダリングのためのスコアをつける
score<QUIETS>();
Expand Down
1 change: 1 addition & 0 deletions source/movepick.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class MovePicker

// 通常探索(search)のProbCutの処理から呼び出されるの専用。
// threshold_ = 直前に取られた駒の価値。これ以下の捕獲の指し手は生成しない。
// capture_or_pawn_promotion()に該当する指し手しか返さない。
MovePicker(const Position& pos_, Move ttMove_, Value threshold_ ,
const CapturePieceToHistory* cph);

Expand Down
56 changes: 56 additions & 0 deletions source/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,9 @@ void Position::UnitTest(Test::UnitTester& tester)
Position pos;
StateInfo si;

// 任意局面での初期化。
auto pos_init = [&](const std::string& sfen_) { pos.set(sfen_, &si, Threads.main()); };

// 平手初期化
auto hirate_init = [&] { pos.set_hirate(&si, Threads.main()); };
// 2枚落ち初期化
Expand Down Expand Up @@ -2488,6 +2491,59 @@ void Position::UnitTest(Test::UnitTester& tester)
}
}

{
// 指し手生成のテスト
auto section2 = tester.section("GenMove");

{
// 23歩不成ができ、かつ、23歩不成では駒の捕獲にはならない局面。
pos_init("lnsgk1snl/1r4g2/p1ppppb1p/6pP1/7R1/2P6/P2PPPP1P/1SG6/LN2KGSNL b BP2p 21");
Move move1 = make_move(SQ_24, SQ_23,B_PAWN);
Move move2 = make_move_promote(SQ_24, SQ_23,B_PAWN);

ExtMove move_buf[MAX_MOVES] , *move_last;
// move_bufからmove_lastのなかにmoveがあるかを探す。あればtrueを返す。
auto find_move = [&](Move m) {
for (ExtMove* em = &move_buf[0]; em != move_last; ++em)
if (em->move == m)
return true;
return false;
};

bool all = true;

move_last = generateMoves<NON_CAPTURES>(pos, move_buf);
all &= !find_move(move1);
all &= find_move(move2);

move_last = generateMoves<CAPTURES>(pos, move_buf);
all &= !find_move(move1);
all &= !find_move(move2);

move_last = generateMoves<NON_EVASIONS>(pos, move_buf);
all &= !find_move(move1);
all &= find_move(move2);

move_last = generateMoves<NON_EVASIONS_ALL>(pos, move_buf);
all &= find_move(move1);
all &= find_move(move2);

move_last = generateMoves<CAPTURES>(pos, move_buf);
all &= !find_move(move1);
all &= !find_move(move2);

move_last = generateMoves<CAPTURES_PRO_PLUS>(pos, move_buf);
all &= !find_move(move1);
all &= find_move(move2);

move_last = generateMoves<NON_CAPTURES_PRO_MINUS>(pos, move_buf);
all &= !find_move(move1);
all &= !find_move(move2);

tester.test("pawn's unpromoted move", all);
}
}


#if 0
// ランダムプレイヤーでの対局
Expand Down
4 changes: 0 additions & 4 deletions source/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -887,11 +887,7 @@ enum MOVE_GEN_TYPE
// 本ソースコードでは、NON_CAPTURESとCAPTURESは使わず、CAPTURES_PRO_PLUSとNON_CAPTURES_PRO_MINUSを使う。

// note : NON_CAPTURESとCAPTURESとの生成される指し手の集合は被覆していない。
// note : CAPTURES_PRO_PLUSとNON_CAPTURES_PRO_MINUSとの生成される指し手の集合も被覆していない。
// → 被覆させないことで、二段階に指し手生成を分解することが出来る。

CAPTURES_PRO_PLUS_ALL, // CAPTURES_PRO_PLUS + 歩の不成なども含む
NON_CAPTURES_PRO_MINUS_ALL, // NON_CAPTURES_PRO_MINUS + 歩の不成なども含む

EVASIONS, // 王手の回避(指し手生成元で王手されている局面であることがわかっているときはこちらを呼び出す)
EVASIONS_ALL, // EVASIONS + 歩の不成なども含む。
Expand Down

0 comments on commit ca89b8b

Please sign in to comment.