Skip to content

Commit

Permalink
V7.73r
Browse files Browse the repository at this point in the history
- Position::pinners[]を求める処理、修正。
- Position::pinners()追加。

 やねうらお — 今日 12:00
 遡ってていくと、pinners[c]のcの意味を以下のStockfishのcommitの時点で私が勘違いして取り込んでいた。これにより、SEEの計算が間違うし、いままでずっと間違えていたのだが、しかしpinnerが絡むようなSEEは滅多に出てこないので棋力低下はほぼ見らなかったのだ。

 それでこれを今回正しい感じに修正したから、benchの値が異なるというのが真相のようであった。

 official-stockfish/Stockfish@1f7ff84

 あと、
 //   王 歩 ^飛 ^飛
 //  のようなケースにおいては、この両方の飛車がpinnersとして列挙される。(SEEの処理でこういう列挙がなされて欲しいので)
 pinnersはこういう仕様になっている必要があるようであった。この点、私の理解が足りていなかった。修正した。
  • Loading branch information
yaneurao committed Nov 4, 2023
1 parent ce12114 commit 1fcbef3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 29 deletions.
41 changes: 14 additions & 27 deletions source/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,47 +648,34 @@ void Position::update_slider_blockers(Color c) const
// ゆえに将棋では、この関数は手番を引数に取るべき。(チェスとはこの点において異なる。)

Bitboard snipers =
( (pieces(ROOK_DRAGON) & rookStepEffect(ksq))
| (pieces(BISHOP_HORSE) & bishopStepEffect(ksq))
// 香に関しては攻撃駒が先手なら、玉より下側をサーチして、そこにある先手の香を探す。
| (pieces(LANCE) & lanceStepEffect(c, ksq))

(
(pieces(ROOK_DRAGON ) & rookStepEffect(ksq ))
| (pieces(BISHOP_HORSE) & bishopStepEffect(ksq ))
// 香に関しては先手玉へのsniperなら、玉より上側をサーチして、そこにある後手の香を探す必要がある。
| (pieces(LANCE ) & lanceStepEffect(c, ksq))
) & pieces(~c);

#if 0
// snipersを取り除いた障害物(駒)
Bitboard occupancy = pieces() ^ snipers;

while (snipers)
{
Square sniperSq = snipers.pop();
Bitboard b = between_bb(ksq, sniperSq) & occupancy;
// 1.
// 王 歩 ^角 ^飛
// のようなケースはない(王から見て斜め方向にいる角しか列挙していないのでsnipersのbitboardは王の横方向に角がいることはない。)

if (b && !b.more_than_one())
{
st->blockersForKing[c] |= b;
if (b & pieces(c))
st->pinners[~c] |= sniperSq;
}
}
#endif

// ↑このStockfishの元のコード、snipersを除いた盤上の駒で考えているが、
// ^王 歩 角 飛
// このような状況で飛車に対して角を取り除いてから敵玉への射線を考えるので、
// 歩がslider_blocker扱いになってしまう。つまり、このコードは間違っているのでは?
// 2.
// 王 歩 ^飛 ^飛
// のようなケースにおいては、この両方の飛車がpinnersとして列挙されて欲しい。(SEEの処理でこういう列挙がなされて欲しいので)

while (snipers)
{
Square sniperSq = snipers.pop();
Bitboard b = between_bb(ksq, sniperSq) & pieces() /* occupancy */;
Bitboard b = between_bb(ksq, sniperSq) & occupancy;

// snipperと玉との間にある駒が1個であるなら。
if (b && !b.more_than_one())
{
st->blockersForKing[c] |= b;
if (b & pieces(~c))
// sniperと玉に挟まれた駒が玉と同じ色の駒であるなら、pinnerに追加。
if (b & pieces(c))
st->pinners[~c] |= sniperSq;
}
}
Expand Down Expand Up @@ -2006,7 +1993,7 @@ bool Position::see_ge(Move m, Value threshold) const

// pinnersが元の升にいる限りにおいては、pinされた駒から王以外への移動は許さない。

if (!(st->pinners[~stm] & occupied))
if (!(pinners(~stm) & occupied))
stmAttackers &= ~st->blockersForKing[stm];

// 手番側のtoに利いている駒がもうないなら、手番側の負けである。
Expand Down
12 changes: 10 additions & 2 deletions source/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,12 @@ struct StateInfo {
// color = 相手側 なら 両王手の候補となる駒。

// 自玉に対して(敵駒によって)pinされている駒
// blockersForKing[c]は、c側の玉に対するpin駒
// blockersForKing[c]は、c側の玉に対するpin駒。すなわちc側,~c側、どちらの駒をも含む。
Bitboard blockersForKing[COLOR_NB];

// 自玉に対してpinしている(可能性のある)敵の大駒。
// 自玉に対して上下左右方向にある敵の飛車、斜め十字方向にある敵の角、玉の前方向にある敵の香、…
// ※ pinners[BLACK]は、BLACKの王に対して(pin駒が移動した時に)王手になる駒だから、WHITE側の駒。
Bitboard pinners[COLOR_NB];

// 自駒の駒種Xによって敵玉が王手となる升のbitboard
Expand Down Expand Up @@ -400,7 +401,9 @@ class Position
Bitboard check_squares(PieceType pt) const { ASSERT_LV3(pt!= NO_PIECE_TYPE && pt < PIECE_TYPE_NB); return st->checkSquares[pt]; }

// c側の玉に対してpinしている駒
//Bitboard pinners(Color c) const;
// ※ pinされているではなく、pinしているということに注意。
//  すなわち、pinされている駒が移動した時に、この大駒によって王が素抜きにあう。
Bitboard pinners(Color c) const { return st->pinners[c]; }

// c側の玉に対して、指し手mが空き王手となるのか。
bool is_discovery_check_on_king(Color c, Move m) const { return st->blockersForKing[c] & from_sq(m); }
Expand Down Expand Up @@ -446,6 +449,11 @@ class Position
// update_slider_blockers()はst->blockersForKing[c]およびst->pinners[~c]を計算します。
// これらはそれぞれ、色cの王が王手状態になるのを防ぐ駒と、色cの駒を王にピン留めする手番~cの
// スライダー駒を格納しています。
// ※ 「ピン留め」とは、移動させた時に開き王手となること。
//
// 注意)
// 王 歩 ^飛 ^飛
// のようなケースにおいては、この両方の飛車がpinnersとして列挙される。(SEEの処理でこういう列挙がなされて欲しいので)

void update_slider_blockers(Color c) const;

Expand Down

0 comments on commit 1fcbef3

Please sign in to comment.