bioshogi 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +8 -8
  3. data/README.org +1 -1
  4. data/bin/bioshogi +1 -1
  5. data/lib/bioshogi/ai/brain.rb +35 -11
  6. data/lib/bioshogi/ai/diver/base.rb +1 -1
  7. data/lib/bioshogi/ai/diver/nega_alpha_diver.rb +1 -1
  8. data/lib/bioshogi/ai/diver/nega_alpha_mate_diver.rb +1 -1
  9. data/lib/bioshogi/ai/diver/nega_max_diver.rb +1 -1
  10. data/lib/bioshogi/ai/diver/nega_scout_diver.rb +1 -1
  11. data/lib/bioshogi/ai/evaluator/attack_weight_table.rb +1 -1
  12. data/lib/bioshogi/ai/evaluator/base.rb +1 -1
  13. data/lib/bioshogi/ai/evaluator/level0.rb +1 -1
  14. data/lib/bioshogi/ai/evaluator/level1.rb +1 -1
  15. data/lib/bioshogi/ai/evaluator/level2.rb +1 -1
  16. data/lib/bioshogi/ai/evaluator/level3.rb +1 -1
  17. data/lib/bioshogi/ai/evaluator/level4.rb +1 -1
  18. data/lib/bioshogi/ai/evaluator/opening_basic_table.rb +1 -1
  19. data/lib/bioshogi/ai/player_brain_mod.rb +1 -1
  20. data/lib/bioshogi/ai/versus.rb +91 -0
  21. data/lib/bioshogi/ai.rb +1 -1
  22. data/lib/bioshogi/assets/kifu_formats/sample.csa +132 -0
  23. data/lib/bioshogi/assets/kifu_formats/sample.ki2 +29 -0
  24. data/lib/bioshogi/assets/kifu_formats/sample.kif +123 -0
  25. data/lib/bioshogi/assets/kifu_formats/sample.sfen +1 -0
  26. data/lib/bioshogi/cli/input_checker.rb +21 -0
  27. data/lib/bioshogi/cli/piece.rb +15 -8
  28. data/lib/bioshogi/cli.rb +6 -92
  29. data/lib/bioshogi/converter.rb +56 -0
  30. data/lib/bioshogi/extreme_validator.rb +1 -1
  31. data/lib/bioshogi/formatter/animation/demo_builder.rb +1 -1
  32. data/lib/bioshogi/input_parser.rb +7 -0
  33. data/lib/bioshogi/player.rb +1 -1
  34. data/lib/bioshogi/version.rb +1 -1
  35. data/lib/bioshogi.rb +48 -33
  36. metadata +10 -6
  37. data/lib/bioshogi/cli/convert.rb +0 -34
  38. data/lib/bioshogi/cli/input_parser.rb +0 -23
  39. data/lib/bioshogi/cli/versus.rb +0 -160
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ae27d982817c1182a4701c34f9e61e2c1c6c8c4b21090cf6e013537f44d50b6
4
- data.tar.gz: 812dd8c24a9988b8c41aa6cfb49a4f158d0dc147d1481e36da04eacafe3b9066
3
+ metadata.gz: '09cedd64dd22183ebc509b5c6671db22760801d56d9446faee819c601c6d35a0'
4
+ data.tar.gz: b3f33ec180576fca527b880755aa44561170fcd5553b130a434dd352882bca6b
5
5
  SHA512:
6
- metadata.gz: 863a38da8084b2d42c6b3e63388ca46afd007dcea8bdd0caa3f4f6198c00b87bd5d886cea895a0e02b4a6537099343444cad9fadfd5d33e34eb015d3654565bc
7
- data.tar.gz: 81fe9ef05826cc1dc1cb372399c894b3c68b61de4dfe034a16071a348f95db9d2156d21fcbd1bf5831b59f0a41a8f67bda32b0e7aee0d832562e0c653558ced2
6
+ metadata.gz: 959b4cb436c7369bd26783507242c969f19a24630b5ddc577bd056bf73c9d9c6a5354cb4daa911753cfbc26567479ca842b603a55b3021911d4c80636ccd0b0e
7
+ data.tar.gz: c2a9c1154346a9ddcb57be4888b8ddb749ac0afe062ea56c65932947c76d9e68fd9f71f569432d72a2219fa7bd4149668814318abf3ed9c6214b4b137b639cfb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bioshogi (0.0.3)
4
+ bioshogi (0.0.4)
5
5
  actionview
6
6
  activesupport (>= 7.1.0)
7
7
  color
@@ -18,13 +18,13 @@ PATH
18
18
  GEM
19
19
  remote: https://rubygems.org/
20
20
  specs:
21
- actionview (7.1.1)
22
- activesupport (= 7.1.1)
21
+ actionview (7.1.2)
22
+ activesupport (= 7.1.2)
23
23
  builder (~> 3.1)
24
24
  erubi (~> 1.11)
25
25
  rails-dom-testing (~> 2.2)
26
26
  rails-html-sanitizer (~> 1.6)
27
- activesupport (7.1.1)
27
+ activesupport (7.1.2)
28
28
  base64
29
29
  bigdecimal
30
30
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -34,7 +34,7 @@ GEM
34
34
  minitest (>= 5.1)
35
35
  mutex_m
36
36
  tzinfo (~> 2.0)
37
- base64 (0.1.1)
37
+ base64 (0.2.0)
38
38
  bigdecimal (3.1.4)
39
39
  builder (3.2.4)
40
40
  byebug (11.1.3)
@@ -45,7 +45,7 @@ GEM
45
45
  crass (1.0.6)
46
46
  diff-lcs (1.5.0)
47
47
  docile (1.4.0)
48
- drb (2.1.1)
48
+ drb (2.2.0)
49
49
  ruby2_keywords
50
50
  erubi (1.12.0)
51
51
  faraday (2.7.11)
@@ -63,7 +63,7 @@ GEM
63
63
  method_source (1.0.0)
64
64
  mini_portile2 (2.8.5)
65
65
  minitest (5.20.0)
66
- mutex_m (0.1.2)
66
+ mutex_m (0.2.0)
67
67
  nokogiri (1.15.4)
68
68
  mini_portile2 (~> 2.8.2)
69
69
  racc (~> 1.4)
@@ -132,4 +132,4 @@ DEPENDENCIES
132
132
  test-unit
133
133
 
134
134
  BUNDLED WITH
135
- 2.4.21
135
+ 2.4.22
data/README.org CHANGED
@@ -688,7 +688,7 @@ Web Page:(Web Page)
688
688
  Commands:
689
689
  bioshogi convert # 棋譜フォーマット変換
690
690
  bioshogi help [COMMAND] # Describe available commands or one specific command
691
- bioshogi input_parser # 入力
691
+ bioshogi input_checker # 入力
692
692
  bioshogi piece # 駒一覧
693
693
  bioshogi versus # CPU同士の対戦
694
694
 
data/bin/bioshogi CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "bioshogi/cli"
3
- Bioshogi::Cli.start
3
+ Bioshogi::CLI.start
@@ -4,7 +4,7 @@
4
4
  require "timeout"
5
5
 
6
6
  module Bioshogi
7
- module Ai
7
+ module AI
8
8
  # 指定の Diver を使って簡単に反復探索するためのクラス
9
9
  class Brain
10
10
  def self.human_format(infos)
@@ -50,13 +50,13 @@ module Bioshogi
50
50
  def iterative_deepening(params = {})
51
51
  # このパラメータはそのまま Diver に渡している
52
52
  params = {
53
- depth_max_range: 1..1, # 1..3 なら時間がある限り1→2→3手と読み進めていく。3手詰限定なら 3..3 とする
54
- time_limit: nil, # nil なら時間制限なし。時間指定なしなら 深度を を 1..3 のようにする意味はなくて最初から 3..3 とすればよい
55
- mate_mode: false, # 王手になる手と、王手をかわす手だけを生成するか?
53
+ :depth_max_range => 1..1, # 1..3 なら時間がある限り1→2→3手と読み進めていく。3手詰限定なら 3..3 とする
54
+ :time_limit => nil, # nil なら時間制限なし。時間指定なしなら 深度を を 1..3 のようにする意味はなくて最初から 3..3 とすればよい
55
+ :mate_mode => false, # 王手になる手と、王手をかわす手だけを生成するか?
56
56
 
57
57
  # 常に diver_instance に渡すもの
58
- base_player: player, # どちらのプレイヤーから開始したか。詰将棋のときなど先後で指し手の方針を明確に分ける必要があるため。
59
- current_player: player.opponent_player, # Diver#dive の最初の player として使うため
58
+ :base_player => player, # どちらのプレイヤーから開始したか。詰将棋のときなど先後で指し手の方針を明確に分ける必要があるため。
59
+ :current_player => player.opponent_player, # Diver#dive の最初の player として使うため
60
60
  }.merge(params)
61
61
 
62
62
  if params[:time_limit]
@@ -78,6 +78,7 @@ module Bioshogi
78
78
 
79
79
  # ordered_children = children # 前の反復で最善とされた順に並んでいる手
80
80
 
81
+ child_count = 0
81
82
  hands = []
82
83
  provisional_hands = []
83
84
  mate = false
@@ -89,6 +90,7 @@ module Bioshogi
89
90
  mate = false
90
91
  children.each do |hand|
91
92
  logger.debug "#ROOT #{hand}" if logger
93
+ child_count += 1
92
94
 
93
95
  # 即詰があれば探索を速攻打ち切る場合
94
96
  # 無効にしてもいいけど他の探索で時間がかかったら、この深さの探索全体がTLEでキャンセルされる可能性がある
@@ -104,8 +106,15 @@ module Bioshogi
104
106
  hand.sandbox_execute(container) do
105
107
  start_time = Time.now
106
108
  v, pv = diver.dive(hand_route: [hand]) # TLEが発生してするとcatchまで飛ぶ
107
- v = -v # 相手の良い手は自分のマイナス
108
- provisional_hands << {hand: hand, score: v, black_side_score: v * player.location.value_sign, best_pv: pv, eval_times: diver.eval_counter, sec: Time.now - start_time}
109
+ v = -v # 相手の良い手は自分のマイナス
110
+ provisional_hands << {
111
+ :hand => hand,
112
+ :score => v,
113
+ :black_side_score => v * player.location.value_sign,
114
+ :best_pv => pv,
115
+ :eval_times => diver.eval_counter,
116
+ :sec => Time.now - start_time,
117
+ }
109
118
  # 1手詰: (v >= SCORE_MAX - 0) 自分勝ち
110
119
  # 2手詰: (v >= SCORE_MAX - 1) 相手勝ち
111
120
  # 3手詰: (v >= SCORE_MAX - 2) 自分勝ち
@@ -148,7 +157,8 @@ module Bioshogi
148
157
 
149
158
  # 自分の合法手があるのに相手の手を1手も見つけられない状況
150
159
  # TLEが早過ぎる場合に起きる
151
- if !children.empty? && hands.empty?
160
+ # TLEが早過ぎる場合、そもそも childrens.empty? はエラーになる
161
+ if child_count >= 1 && hands.empty?
152
162
  raise BrainProcessingHeavy, "合法手を生成したにもかかわらず、指し手の候補を絞れません。制限時間を増やすか読みの深度を浅くしてください : #{params}"
153
163
  end
154
164
 
@@ -181,7 +191,14 @@ module Bioshogi
181
191
  hand.sandbox_execute(container) do
182
192
  start_time = Time.now
183
193
  v, pv = diver.dive
184
- {hand: hand, score: -v, socre2: -v * player.location.value_sign, best_pv: pv, eval_times: diver.eval_counter, sec: Time.now - start_time}
194
+ {
195
+ :hand => hand,
196
+ :score => -v,
197
+ :socre2 => -v * player.location.value_sign,
198
+ :best_pv => pv,
199
+ :eval_times => diver.eval_counter,
200
+ :sec => Time.now - start_time,
201
+ }
185
202
  end
186
203
  }.sort_by { |e| -e[:score] }
187
204
  end
@@ -193,7 +210,14 @@ module Bioshogi
193
210
  hand.sandbox_execute(container) do
194
211
  start_time = Time.now
195
212
  v = evaluator.score
196
- {hand: hand, score: v, socre2: v * player.location.value_sign, best_pv: [], eval_times: 1, sec: Time.now - start_time}
213
+ {
214
+ :hand => hand,
215
+ :score => v,
216
+ :socre2 => v * player.location.value_sign,
217
+ :best_pv => [],
218
+ :eval_times => 1,
219
+ :sec => Time.now - start_time,
220
+ }
197
221
  end
198
222
  }.sort_by { |e| -e[:score] }
199
223
  end
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  module Diver
4
4
  class Base
5
5
  MATE = "(詰み)"
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  module Diver
4
4
  class NegaAlphaDiver < Base
5
5
  def dive(player: params[:current_player], depth: 0, alpha: -SCORE_MAX, beta: SCORE_MAX, hand_route: [])
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  module Diver
4
4
  # 詰将棋専用
5
5
  # ・評価値の大小は関係なく3つの状態しかない
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  module Diver
4
4
  # コードはわかりやすいが遅い
5
5
  class NegaMaxDiver < Base
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  module Diver
4
4
  # https://ja.wikipedia.org/wiki/Negascout
5
5
  class NegaScoutDiver < Base
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
 
7
7
  # http://www.yss-aya.com/book.html
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
  class Base
7
7
  attr_reader :player
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
  # 評価すること
7
7
  # ・盤上の駒の価値
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
  # 評価すること
7
7
  # ・盤上の駒の価値
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
  class Level2 < Level1
7
7
  private
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
  class Level3 < Base
7
7
  def score_compute_report
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Bioshogi
4
- module Ai
4
+ module AI
5
5
  module Evaluator
6
6
  class Level4 < Level3
7
7
  def score_compute_report
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  module Evaluator
4
4
  OpeningBasicTable = {
5
5
  :advance => {
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  concern :PlayerBrainMod do
4
4
  def evaluator(options = {})
5
5
  (options[:evaluator_class] || Evaluator::Level1).new(self, options)
@@ -0,0 +1,91 @@
1
+ # -*- compile-command: "../../../.bin/bioshogi versus" -*-
2
+
3
+ module Bioshogi
4
+ module AI
5
+ class Versus
6
+ concern :CLI do
7
+ included do
8
+ desc "versus", "CPU同士の対戦"
9
+ option :depth_max, type: :numeric, aliases: "-d", default: 8
10
+ option :times, type: :numeric, aliases: "-n", default: 512
11
+ option :time_limit, type: :numeric, aliases: "-t", default: 5.0
12
+ option :round, type: :numeric, aliases: "-r", default: 1
13
+ option :logging, type: :boolean, aliases: "-l", default: false
14
+ option :log_file, type: :string, default: "brain.log"
15
+ option :black_diver, type: :string, default: "Diver::NegaAlphaDiver"
16
+ option :white_diver, type: :string, default: "Diver::NegaScoutDiver"
17
+ def versus
18
+ Versus.new(options.to_options).call
19
+ end
20
+ end
21
+ end
22
+
23
+ def initialize(options = {})
24
+ @options = {
25
+ :depth_max => 8,
26
+ :times => 512,
27
+ :time_limit => 5.0,
28
+ :round => 1,
29
+ :logging => false,
30
+ :log_file => "brain.log",
31
+ :black_diver => "Diver::NegaAlphaDiver",
32
+ :white_diver => "Diver::NegaScoutDiver",
33
+ }.merge(options)
34
+ end
35
+
36
+ def call
37
+ if @options[:logging]
38
+ log_file = Pathname(@options[:log_file])
39
+ FileUtils.rm_rf(log_file)
40
+ Bioshogi.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(log_file))
41
+ end
42
+
43
+ divers = [
44
+ Bioshogi::AI.const_get(@options[:black_diver]),
45
+ Bioshogi::AI.const_get(@options[:white_diver]),
46
+ ]
47
+ tp divers
48
+ pp @options
49
+ tp @options
50
+
51
+ win_counts = Location.inject({}) { |a, e| a.merge(e.key => 0) }
52
+
53
+ @options[:round].times do |round|
54
+ container = Container::Basic.start
55
+ @options[:times].times do
56
+ current_player = container.current_player
57
+
58
+ deepen_score_list_params = {
59
+ time_limit: @options[:time_limit],
60
+ depth_max_range: 0..@options[:depth_max],
61
+ }
62
+ diver_class = divers[container.turn_info.current_location.code]
63
+ records = current_player.brain(diver_class: diver_class, evaluator_class: AI::Evaluator::Level3).iterative_deepening(deepen_score_list_params)
64
+ record = records.first
65
+ hand = record[:hand]
66
+ container.execute(hand.to_sfen, executor_class: PlayerExecutor::WithoutMonitor)
67
+
68
+ puts "---------------------------------------- [#{container.turn_info.turn_offset}] #{hand} (#{diver_class})"
69
+ # container.players.each { |e| tp e.pressure_report }
70
+
71
+ tp deepen_score_list_params
72
+ tp AI::Brain.human_format(records)
73
+ tp container.players.inject({}) { |a, e| a.merge(e.location => e.pressure_rate) }
74
+ puts container
75
+ puts
76
+ puts "#{hand} #{record[:black_side_score]}"
77
+ puts
78
+ puts container.to_kif_oneline
79
+
80
+ captured_soldier = current_player.executor.captured_soldier
81
+ if captured_soldier && captured_soldier.piece.key == :king
82
+ win_counts[current_player.location.key] += 1
83
+ Pathname("win_counts.txt").write(win_counts.inspect)
84
+ break
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
data/lib/bioshogi/ai.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Bioshogi
2
- module Ai
2
+ module AI
3
3
  SCORE_MAX = 999999 # Float::INFINITY を使うとおかしくなるので注意
4
4
  end
5
5
  end
@@ -0,0 +1,132 @@
1
+ V2.2
2
+ N+加藤桃子 女王
3
+ N-里見香奈 女流王座
4
+ $EVENT:女流王座戦
5
+ $SITE:大阪・芝苑
6
+ $START_TIME:2017/11/11 10:00:00
7
+ $END_TIME:2017/11/11 17:22:00
8
+ $OPENING:ゴキゲン中飛車
9
+ P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
10
+ P2 * -HI * * * * * -KA *
11
+ P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
12
+ P4 * * * * * * * * *
13
+ P5 * * * * * * * * *
14
+ P6 * * * * * * * * *
15
+ P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
16
+ P8 * +KA * * * * * +HI *
17
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
18
+ +
19
+ +2726FU
20
+ -3334FU
21
+ +2625FU
22
+ -2233KA
23
+ +7776FU
24
+ -3142GI
25
+ +3948GI
26
+ -5354FU
27
+ +5968OU
28
+ -5455FU
29
+ +3736FU
30
+ -8252HI
31
+ +4837GI
32
+ -4253GI
33
+ +3746GI
34
+ -5344GI
35
+ +4958KI
36
+ -5162OU
37
+ +6878OU
38
+ -6272OU
39
+ +6766FU
40
+ -7282OU
41
+ +5867KI
42
+ -7172GI
43
+ +8877KA
44
+ -9394FU
45
+ +7888OU
46
+ -9495FU
47
+ +9998KY
48
+ -8384FU
49
+ +8899OU
50
+ -7283GI
51
+ +7988GI
52
+ -6172KI
53
+ +6665FU
54
+ -7374FU
55
+ +6766KI
56
+ -8173KE
57
+ +7786KA
58
+ -5251HI
59
+ +2878HI
60
+ -8485FU
61
+ +8659KA
62
+ -3342KA
63
+ +6979KI
64
+ -2133KE
65
+ +7675FU
66
+ -7475FU
67
+ +6675KI
68
+ -4275KA
69
+ +7875HI
70
+ -0074FU
71
+ +7576HI
72
+ -0075KI
73
+ +7678HI
74
+ -5556FU
75
+ +5756FU
76
+ -7565KI
77
+ +5655FU
78
+ -0056FU
79
+ +5926KA
80
+ -1314FU
81
+ +0062FU
82
+ -4152KI
83
+ +6261TO
84
+ -5161HI
85
+ +5554FU
86
+ -6566KI
87
+ +7868HI
88
+ -6676KI
89
+ +0077FU
90
+ -7675KI
91
+ +6858HI
92
+ -7566KI
93
+ +5868HI
94
+ -6665KI
95
+ +0032KA
96
+ -8586FU
97
+ +8786FU
98
+ -3435FU
99
+ +3223UM
100
+ -6364FU
101
+ +3635FU
102
+ -6121HI
103
+ +2334UM
104
+ -9192KY
105
+ +2648KA
106
+ -2191HI
107
+ +2524FU
108
+ -6575KI
109
+ +3456UM
110
+ -0084FU
111
+ +4875KA
112
+ -7475FU
113
+ +6864HI
114
+ -5263KI
115
+ +6468HI
116
+ -0065KA
117
+ +6865HI
118
+ -7365KE
119
+ +5665UM
120
+ -0059HI
121
+ +0066KE
122
+ -7273KI
123
+ +0052KA
124
+ -6364KI
125
+ +6564UM
126
+ -7364KI
127
+ +0065FU
128
+ -0048KA
129
+ +6564FU
130
+ -4866UM
131
+ +0073KI
132
+ %TORYO
@@ -0,0 +1,29 @@
1
+ 開始日時:2017/11/11 10:00:00
2
+ 終了日時:2017/11/11 17:22:00
3
+ 棋戦:女流王座戦
4
+ 場所:大阪・芝苑
5
+ 手合割:平手
6
+ 先手:加藤桃子 女王
7
+ 後手:里見香奈 女流王座
8
+ 戦型:ゴキゲン中飛車
9
+ 先手の囲い:居飛車穴熊
10
+ 後手の囲い:片美濃囲い, 銀冠
11
+ 先手の戦型:対振り持久戦, 三間飛車
12
+ 先手の手筋:垂れ歩
13
+ 後手の手筋:垂れ歩
14
+ 先手の備考:居飛車, 対振り, 対抗型
15
+ 後手の備考:振り飛車, 対抗型
16
+
17
+ ▲2六歩 △3四歩 ▲2五歩 △3三角 ▲7六歩 △4二銀 ▲4八銀 △5四歩 ▲6八玉 △5五歩
18
+ ▲3六歩 △5二飛 ▲3七銀 △5三銀 ▲4六銀 △4四銀 ▲5八金右 △6二玉 ▲7八玉 △7二玉
19
+ ▲6六歩 △8二玉 ▲6七金 △7二銀 ▲7七角 △9四歩 ▲8八玉 △9五歩 ▲9八香 △8四歩
20
+ ▲9九玉 △8三銀 ▲8八銀 △7二金 ▲6五歩 △7四歩 ▲6六金 △7三桂 ▲8六角 △5一飛
21
+ ▲7八飛 △8五歩 ▲5九角 △4二角 ▲7九金 △3三桂 ▲7五歩 △同 歩 ▲同 金 △同 角
22
+ ▲同 飛 △7四歩 ▲7六飛 △7五金 ▲7八飛 △5六歩 ▲同 歩 △6五金 ▲5五歩 △5六歩
23
+ ▲2六角 △1四歩 ▲6二歩 △5二金 ▲6一歩成 △同 飛 ▲5四歩 △6六金 ▲6八飛 △7六金
24
+ ▲7七歩 △7五金 ▲5八飛 △6六金 ▲6八飛 △6五金 ▲3二角 △8六歩 ▲同 歩 △3五歩
25
+ ▲2三角成 △6四歩 ▲3五歩 △2一飛 ▲3四馬 △9二香 ▲4八角 △9一飛 ▲2四歩 △7五金
26
+ ▲5六馬 △8四歩 ▲7五角 △同 歩 ▲6四飛 △6三金左 ▲6八飛 △6五角 ▲同 飛 △同 桂
27
+ ▲同 馬 △5九飛 ▲6六桂 △7三金上 ▲5二角 △6四金直 ▲同 馬 △同 金 ▲6五歩 △4八角
28
+ ▲6四歩 △6六角成 ▲7三金
29
+ まで113手で先手の勝ち