羽生さんが駒を一度も後退させずに勝った対局

はじめに

先日、第2回電王戦の第1局を見に、ニコファーレに行ってきました。

そのとき、聞き手の矢内さんが「羽生さんが駒を一度も後退させずに勝った対局ある」というお話をされていて、 会場は90へぇくらいの雰囲気になっていました。

ただ、具体的にどの対局という話はなく、矢内さんも「間違ってたらごめんね☆」という感じだったので、 実際に調べてみました。

使ったもの

2ちゃんねる棋譜

Blunder.Converter

Python 2.6.8 (Cygwin)

方法

駒が後退したかどうかを判定するのにはCSA形式が都合がよさそうだったので、 Blunder.Converterを使用して、2ちゃんねる棋譜のKI2形式をCSA形式に変換しました。

その後、最近勉強中のPython棋譜を抽出するコードを書きました。

コード

#!/usr/bin/python
# coding: UTF-8

import os
CSA_DIR = './2chkifu.csa/'

for csaFile in os.listdir(CSA_DIR):

    # ファイルの読み込み
    csaStr = open(CSA_DIR + csaFile).read()

    # 羽生さんの棋譜か
    if 'N+羽生' in csaStr:
        habuMove =  1   # 羽生さんが先手
    elif 'N-羽生' in csaStr:
        habuMove = -1   # 羽生さんが後手
    else:
        continue

    # 羽生さんの勝ちか
    csaLines = csaStr.split('\n')
    if '%TORYO' not in csaLines:
        continue
    toryoIndex = csaLines.index('%TORYO')
    preToryo = csaLines[toryoIndex - 1][0]
    if (habuMove == 1 and preToryo == '-') or (habuMove == -1 and preToryo == '+'):
        continue   # 羽生さんの負け

    # 駒が後退していないか
    if '+' in csaLines:
        startIndex = csaLines.index('+')
    else:
        continue
    startIndex = startIndex + 1 + (1 - habuMove) / 2
    backFlag = 0
    for n in xrange(startIndex, toryoIndex, 2):
        if csaLines[n][2] != '0' and int(csaLines[n][2]) * habuMove < int(csaLines[n][4])* habuMove:
            backFlag = 1   # 駒が後退した
            break

    # 結果の表示
    if backFlag == 0:
        print csaFile

出力結果

00311.csa
00685.csa
01600.csa
06521.csa
07639.csa
35267.csa
45018.csa

結果を詳しく

まとめ

見つかっても1局くらいなのかなと思っていたのですが、意外と多かったです。 結果を見てそりゃそうかと思ったのは、比較的短手数の対局が多かったことです。

追記 (2013-04-10)

駒落ち(CSA形式で手番が'-')の棋譜の処理が間違っていたので、その棋譜は無視するようにコードを修正しました。 結果は変わりません。