LoginSignup
0
0

はじめに

Expect の manpage を見ると、Expect ができることの例として以下があります。

ゲーム(例えば rogue)を始める時に、最適なパラメタがもらえなかった場合、最適なパラメタがもらえるまで何度でもリスタートを行ない、その後制御を人間に移す。

昔 JNetHack で遊んでいたとき、主にWizard(魔法使い)を選んでいまして、
初期装備にいい杖やアイテムが出るまでQuit&再実行を繰り返す所謂リセマラを
地道に手動でやっていた事を思い出しました。ヒマ贅沢な時間の使い方だなと。

汝、今こそこれを自動化せよ

なるほど、やってみましょう。

JNetHack のリセマラスクリプト

CentOS7 + nethack-367-src.tgz + jnethack-3.6.7-0.1.diff.gz の tty 環境で実行しました。
ここでは ~/nh/install/games/jnethack にインストールされたものとします。
※デフォルトでのインストール場所は、昔と今では全然違うんですね。

jnh.ex
#!/usr/bin/expect

set timeout 1

# お好みの 職業・種族・性別・属性を設定してください
set JOB    w  ; # 職業(w - 魔法使い)
set RACE   h  ; # 種族(h - 人間)
set GENDER *  ; # 性別(* - ランダム)
set ATTR   n  ; # 属性(n - 中立)

# ---------------------------------------------------------------
# お望みのパラメータ・所持品を CONDITION に記載してください
#
# 強早耐知賢魅のうち、強知賢が11以上を希望する例
# set CONDITION ".*強:1\[1-9\].*知:1\[1-9\].*賢:1\[1-9\].*"
#
# 所持品を正規表現で記載する例 (今回はこれを使う)
set CONDITION ".*(回復|識別)の魔法書.*(変化|無力化)の杖.*魔法のマーカ.*"
#
# 組み合わせる場合は、パラメータ->所持品の順序で記述してください
# set CONDITION ".*賢:1\[1-9\].*魔法のマーカ.*"
# ---------------------------------------------------------------

while { 1 } {
    spawn ~/nh/install/games/jnethack
    expect "ynq"
    send "n"             ; # 職業,種族,性別,属性を自動選択しない
    expect {
        "職業を選んでください" {
            send $JOB    ; exp_continue
        }
        "種族を選んでください" {
            send $RACE   ; exp_continue
        }
        "性別を選んでください" {
            send $GENDER ; exp_continue
        }
        "属性を選んでください" {
            send $ATTR   ; exp_continue
        }
        "これでよい" {
            send "y"     ; exp_continue
        }
        "More" {
            # Space2回押す+所持品を確認する
            send "  i"
            expect {
                -re $CONDITION {
                    interact
                    exit 0
                } default {
                    send "\003 "  ; # Ctrl+c と space 1回
                    expect {
                        "本当にやめる" {
                            send "y" ; exp_continue
                        }
                        "識別しますか" {
                            send "q"
                        }
                     }
                }
            }
        }
    }
    expect eof
    catch wait
}

魔法使いは初期装備で強力な杖や魔法のマーカがもらえる(こともある)と
嬉しいので、このスクリプトでは希望の所持品の条件を正規表現で記載して、
出るまでひたすら spawn を繰り返し、出たら interact する、としました。

他の職業だとどういうのがいいんでしょうね。

所持品ではなく、良パラメータを求める場合は、

set CONDITION ".*強:1\[1-9\].*知:1\[1-9\].*賢:1\[1-9\].*"

のようにすればよいのでしょう。※文法上、[ ] の前にはバックスラッシュが必要です。
当然ですが、絶対出ない値やアイテムを条件にすると、永遠にプレイ開始できません。

それでは、スクリプトを実行しました。

                                                                   武器
                                                                   a - 祝福された+1 六尺棒(手にしている)
                                                                   鎧
                                                                   b - 祝福された+0 魔法を防ぐクローク(身につけている)
                                                                   巻物
                                                                   i - 呪われていない地図の巻物
                                                                   j - 呪われていない解呪の巻物
                                                                   k - 呪われていない罰の巻物
                                                                   魔法書
                                                                   l - 祝福された衝撃の魔法書
                                                                   m - 呪われていない識別の魔法書
                                                                   薬
                                                                   f - 呪われていない超回復の薬
                                                                   g - 呪われていない水
                                           --+----------           h - 呪われていない回復の薬
                                           |.......{....           指輪
                                           |....@......|           d - 呪われていない耐毒の指輪
                                           |....f...$..|           e - 祝福された +1 体力の指輪
                                           -------------           杖
                                                                   c - 変化の杖(0:7)
                                                                   道具
                                                                   n - 魔法のマーカ(0:44)
Megadriver 手品師              強:9 早:16 耐:15 知:18 賢:8 魅:9 中 o - 呪われていない目隠し
地下:1 $:0 体:12(12) 魔:7(7) 鎧:9 経験:1                           (end) 

しばらく待つと、このように所望の品が含まれた初期状態でスタートできました。

末尾の wait はプロセスの終了を待つ処理です。
wait しない場合、以下のようにゾンビプロセス(defunctの行)が残るための対策です。

wait なしの場合の ps auxf 抜粋
megadri+ 25188  0.2  0.0 134200  3120 pts/1    Sl+  21:55   0:00      \_ /usr/bin/expect ./jnh.ex
megadri+ 25190  0.0  0.0      0     0 ?        Zs   21:55   0:00          \_ [jnethack] <defunct>
megadri+ 25195  0.0  0.0      0     0 ?        Zs   21:55   0:00          \_ [jnethack] <defunct>
megadri+ 25205  0.0  0.0      0     0 ?        Zs   21:55   0:00          \_ [jnethack] <defunct>
megadri+ 25209  0.0  0.0      0     0 ?        Zs   21:55   0:00          \_ [jnethack] <defunct>
megadri+ 25213  0.0  0.0      0     0 ?        Zs   21:55   0:00          \_ [jnethack] <defunct>
megadri+ 25217  0.0  0.0      0     0 ?        Zs   21:55   0:00          \_ [jnethack] <defunct>
megadri+ 25221  0.0  0.0  17704  2236 pts/2    Ss+  21:55   0:00          \_ /home/megadriver/nh/install/games/lib/jnethackdir/jnethack

さいごに

  • 久々にプレイしましたが、懐かしさと新鮮さが入り交じっており、JNetHack の面白さは
    昔以上でした。鉄棒(#)ってなんなの?
  • スクリプト作成よりも何倍もの時間を、ついつい始めたプレイに費やしてしまいました
  • 初期装備が多少よくても結局リトライしまくるのですが、初期アイテムが良いゆえに
    止めどきを見失いがちになります(自制心がさがった!)

関連サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0