sakurapyon’s blog

sakurapyon’s blog

必至をかけられた場合、どうしたらいいのだろうか?

sakurapyonは、自分が負け(必至)だと認識したら、念のためもうちょっと時間をかけて反復深化するようにしているんだけど、大抵の場合は苦し紛れの思い出王手が長手順になるだけで、あまり意味がない。これはこれで見苦しいのでなんとかしたいんだけど、相手が勝ちを読みきってないのに自分だけ勝手に負けを認識して駒を只捨てして本当に負けになってしまう場合が問題。

以前は、相手だけが負けを悟ってるときに運良くこちらの勝ちになることがあった(水平線効果で勝つ)んだけど、それの逆の場合である。そこまで成長した、という嬉しさはあるけどなんとかしたい。

ウソ必至をかけて相手を惑わすことができればいいんだけど、どうしたらいいんだろうか? (特に人間相手なら有効な気がする)。

昔のsakurapyonと探索速度を比較してみた

送りバントが成功できるまで見守るブログさんの勝手ルールで一人指し手生成祭をやってみたらゆっくりゆうちゃんだったの局面を実行してみた。

後手の持駒:なし
9 8 7 6 5 4 3 2 1

                                                        • +
v香v桂v銀v金v玉v金v銀v桂v香
・v飛 ・ ・ ・ ・ ・v角 ・
v歩 ・v歩v歩v歩v歩 ・v歩v歩
・v歩 ・ ・ ・ ・v歩 ・ ・
・ ・ ・ ・ ・ ・ ・ ・ ・
・ ・ 歩 ・ ・ ・ ・ 歩 ・
歩 歩 ・ 歩 歩 歩 歩 ・ 歩
・ 角 ・ ・ ・ ・ ・ 飛 ・
香 桂 銀 金 玉 金 銀 桂 香
                                                        • +

先手の持駒:なし
手数=4 ▽3四歩 まで

sakurapyon-41、探索深さ14手(延長探索は18手まで行ってます)での測定結果。

9/11: 0( 0): 8002 ▲68玉(59) △88角成(22)▲88銀(79)△65角打▲36角打 △62玉(51)▲75歩(76)△74歩(73)▲74歩(75)
探索中: depthMax/iter/max=14/9/11, time=0.195秒, 10357 nodes, 53009.520 nps, 97845 leaves, 9.4 l/n (2.79^9=10357), quiescount=221350, moves=106623 (mpn=10.29)
10/11: 0( 0): 13183 ▲68玉(59) △88角成(22)▲88銀(79)△65角打▲36角打 △62玉(51)▲75歩(76)△35歩(34)▲45角(36)△47角成(65)
探索中: depthMax/iter/max=14/10/11, time=0.370秒, 19444 nodes, 52528.920 nps, 166730 leaves, 8.6 l/n (2.68^10=19444), quiescount=389540, moves=183121 (mpn=9.42)
11/12: 0( 0): 24240 ▲68玉(59) △88角成(22)▲88銀(79)△65角打▲36角打 △62玉(51)▲75歩(76)△35歩(34)▲45角(36)△47角成(65) ▲23角成(45)
探索中: depthMax/iter/max=14/11/12, time=0.565秒, 32672 nodes, 57787.172 nps, 260964 leaves, 8.0 l/n (2.57^11=32672), quiescount=608276, moves=288790 (mpn=8.84)
12/14: 0( 0): 50757 ▲68玉(59) △88角成(22)▲88銀(79)△65角打▲36角打 △62玉(51)▲75歩(76)△35歩(34)▲45角(36)△47角成(65) ▲23角成(45)△51金(41)
探索中: depthMax/iter/max=14/12/15, time=1.478秒, 112249 nodes, 75924.101 nps, 873505 leaves, 7.8 l/n (2.64^12=112249), quiescount=1993618, moves=968532 (mpn=8.63)
13/17: 0( 0): 218395 ▲68玉(59) △42玉(51)▲78玉(68)△88角成(22)▲88銀(79) △32玉(42)▲79玉(78)△94角打▲77角打△22銀(31) ▲78飛(28)△35歩(34)▲68角(77)△14歩(13)
探索中: depthMax/iter/max=14/13/17, time=3.065秒, 247182 nodes, 80648.366 nps, 1875746 leaves, 7.6 l/n (2.60^13=247182), quiescount=4370864, moves=2085288 (mpn=8.44)
14/18: 0( 0): 290156 ▲68玉(59) △42玉(51)▲78玉(68)△88角成(22)▲88銀(79) △32玉(42)▲79玉(78)△94角打▲77角打△22銀(31) ▲78飛(28)△35歩(34)▲68角(77)△14歩(13)▲77銀(88)
探索中: depthMax/iter/max=14/14/18, time=4.785秒, 414826 nodes, 86698.888 nps, 3119370 leaves, 7.5 l/n (2.52^14=414826), quiescount=7272120, moves=3473294 (mpn=8.37)

「評価関数の呼び出し回数」ってことは、葉局面の数で数えていいのかな。それだと 3119370局面 なので 652k局面/sec という計算になる。 昔のsakurapyon-05は反復9回で11秒(秒未満不明),899094局面だから 約80k局面/sec。1桁近く早くなってるんだな…(枝刈りによって葉の展開数は変わってくるので、数値がでかければ速いわけじゃないとは思いますが)
静止探索も入れるともっと増えますが、このへんはどう計算したらいいんだろ。

20( 0):▲78金(69)△88角成(22)▲88銀(79)△65角打▲56角打 △56角(65)▲56歩(57)△32金(41)▲77銀(88)
depthMax=9(10), time=11 sec
bestVal:20 (20),te:▲78金(69)△88角成(22)▲88銀(79)△65角打▲56角打 △56角(65)▲56歩(57)△32金(41)▲77銀(88)
leafcount:899094, nodecount=198110, nullcount:7468, nullcount2=930, futilitycount=28873,
手数: 5 思考時間: 11秒 総思考時間:先手 0:13 後手 0:02

反復9回時点で比較すると、sakurapyon-05->41は 読んでいる局面数が1桁減ってる。昔は10秒で9手しか読めなかったのに今は14手以上読んでるので、たぶん速度向上分で2手ぐらい+探索効率改善で2手ぐらい深く読めるようになってるのだと思う。

レーティングは1300→1900なので、1手でR150ぐらい? ということは、もう0.5手ぐらい深く読めるとR2000台が見えてきそうだ。もう0.5手…ってどうすればいいんだろ……

今使ってる手法

  • 基本的な構造はれさぴょん
    • Te は64bit変数 (32bitに押し込む手もありそうではある)
    • Kyokumenは ほぼ同じ
    • KyokumenKomagumiはKKPに合わせて書き直し
    • Hashも64bit+64bitに変更
    • 静止探索用手生成など追加
  • 通常探索
    • Aspiration Search
    • PVS
    • null move pruning (PV以外)
    • 再帰的反復深化
    • futility pruning (PV以外)
    • history reduction
      • 評価値が悪い局面は強めにreduction
    • 王手されている、詰めろがかかってる、2連続の取り返し、合法手が1手だけのときは延長
    • distance pruning
    • 簡易1手詰
  • オーダリング
    • ハッシュ1手、カウンター1手
      • ハッシュとカウンターは王手回避の場合も優先
    • 取る手・成る手のうち駒損しない手をMVVLVA順
      • 取り返しは少し優先
    • キラー2手、前回反復深化の最善手1手、カウンター1手
    • 取る手・成る手の残り
      • 取り返しは少し優先
    • 移動手・打つ手をヒストリー順
      • Historyはβカット時にdepth*depthを足しこむ
  • 静止探索(6段)
    • delta pruning
    • 王手延長
    • パスあり
    • 簡易1手詰
    • 生成する手
      • 浅いところ: 取る手・成る手・カウンター手・金銀を敵玉の周りに打つ手
      • 深いところ: 取る手・成る手、ただし中段(4-6段目)の歩を取る手は読まない・カウンター手
      • 王手されてたら王手回避手を生成
    • オーダリングはMVV/LVA
  • 局面評価
    • bonanza 6.0のfv.binからKKPだけ使っている
    • 手でドーピング
  • ハッシュ
    • クリアしない*1
      • 古いハッシュの値は使わないが、手は使う
  • 詰み探索
    • やってない
  • 水平線対策
    • SHEK
  • その他
    • C++ template
      • 指し手生成など、先手番後手番の場合分けが多く使われている関数は効果大*2
    • g++ pgo
  • やめた
    • razoring
    • static null move pruning
    • hash probe cut
    • mate killer