King Exitの攻略でも書いてみる


 たまには攻略も書いてみよう。雑にパパッと。
 攻略も感想も書かなくなったらネタ無いもんな。

 ニューゲームから通しプレイで、隠し通路や良アイテムや実績を全て羅列するスタイルで書くけど、まず見落とさないようなのとか、取らなくてもさほど問題無いようなのとかはバッサリ省略。
 魔の欠片も見付けやすいから省略しちゃったけど、書いても良かったかもなー。まーいいや。
 バージョンは1.15か1.16。書いてる途中でバージョン変わったけど、影響は多分無さそう。
(追記:1.17-1.18も大きな影響は無し/細かい影響で気付いた点は文中に追記)

 普通に歩いててエンカウントした雑魚は全て倒す、という程度の育成が前提。稼ぎはしない程度で。検証プレイではほぼ最短経路で移動したので、普通にプレイするなら育成の問題は全く無い筈。
 魔の欠片を誰に使うかはお好みで。検証プレイでは未使用。
 MPは雑に使いまくっても多分平気。MP再生装備やレベルアップの全快でほぼ足りる。

 序章で四人パーティになった後は、敗北BAD ENDを回収可能になるが、後で全てのBAD ENDを回収出来る部屋があるので、無理に回収する必要はさほど無い。
 とはいえ、個人的には普通に回収したい派なので、回収のタイミングも一応書く。

 弱点や耐性については、抜けやミスが普通にありまくる筈。
 スリップやパニックは、通るボスは多いんだけど、今日の俺はゴリ押し派所属なので耐性は調べてない。
Continue reading


フォルダ作成や名前の変更がクソ遅い問題に引っ掛かった


 Windows10で起きたけど、多分これWindows7とかでも起きる気がする。

 いつ頃からか忘れたが、Explorerでフォルダ作って名前入力してEnter押したとこで何十秒か固まる、という現象が多発していたのだ。リネームなどでも毎回固まるし。極端に重い、って感じの固まり方。
 んで、Explorerに何か変なのが取り憑いたんかなー、とか思ってたんだけど、コマンドプロンプトからrenしても全く同じ固まり方なんで、FSの方がヤバかったりしないかな、とさすがに不安になって、似た症状の報告が無いか真面目に探してみた。

 結論から言えば、多分Windows Searchのインデックスが巨大になると起きる、っぽい。言い換えれば、特定フォルダ以下にファイルが大量にあると起きる、と。
 コントロールパネルの「インデックスのオプション」を開いたら、インデックスが百万個以上作られてたんで、問題が起きてるフォルダを「含まれる場所」の一覧から外してみて、念の為「詳細設定→再構築」をやってみた。2000個以下までインデックスが減ったので、フォルダ操作をしてみる。軽い。めでたい。

 まあ、バカみたいに大量のファイルを生成するお仕事とかの人じゃなきゃ引っ掛からないのかもしれないけどさ。
 ファイルが大量にありすぎてバックアップソフトが固まったこともあったし、まー色々起きるもんだなーと。でもOS標準機能はちゃんとスケールして欲しいです正直。

追記(2020/1/5):
 ファイルの移動や削除などが99%で終わらなくなる奴は、適当にエクスプローラー開いて、表示→オプション→プライバシー/エクスプローラーの履歴を消去する/消去、で直った。何だかなー。


Tree of Savior OBTをやってみた


 がっつり10日間ほどプレイしたので、久々に感想を。
 モンクに転職して少し遊んだとこでアンインストールしたので、その辺りまでの話。

 プレイしながら「RO2に求められてたのはこういうのなんだろなー」って何回も思った。2Dっぽい絵が好きな人には合うんじゃなかろか。
 ゲーム性は量産型なので、プレイ開始前から飽きてるといういつもの現象が起きたけど、一時期のように次から次へとイナゴごっこしてた訳でもないので、割と長時間飽きずに行けた。具体的には一週間飽きなかった。その後は惰性で三日ほど遊んで終わり。

 「ステ振りとスキル振りとクラスチェンジ分岐」という俺の苦手な離脱ポイントてんこ盛りの仕様なので、とりあえず海外情報サイト(Tree of Savior Fan Base)Public Buildsを眺めることに。
 いつもの習性でヒーラー路線を目指したんだけど、もうMMOとかイナゴする機会もなかなか無いだろうから、やったことの無かった殴りヒーラーに行ってみた。クレリック系二番人気のモンクビルドである。

 結論から言えば、何か失敗だった気がする。うむ。まーいいや。早く離脱した方がいいんだ。
 どうせひねくれるなら、ちょっと気になってたオラクルでも目指せば良かった気もする。

 ゲーム的に快適だなーと思ったのは、クエ報酬が経験値でなく「使うと経験値の入るアイテム」を貰える点で、適度に貯めれば適正レベルをひたすら維持し続けられる。
 あと、量産型MMOだと「初期だけクエ連発で死ぬほどホイホイ上がって、いきなりクエが尽きて急にマゾい作業に」が定番だったけど、ToSはとりあえず相当長い間はクエが続く。尽きた後もそこまでマゾい作業ではない、らしいけど。

 ただ、クエ自体が作業寄りの要素ではあるので。
 やっぱオフゲと比べると、作業じゃない部分の比率が低いな、とは思う。序盤のプレイで既にそんな感じ。
 あとボス戦も割と作業だったけど、それは序盤だからだろう。さすがに。

 俺の苦手なデイリーなんたら系は、ToSにもある。これがあると離脱が早まるので助かる。
 六年続けたマビをやめた理由でも、デイリーはかなりの比重を占めてたしなー。
 そういえばPSO2もだ。クロト銀行でやめたんだ。
 デイリー系は、プレイ時間が減った時に、一気に飽きを加速する。デイリーしかやってねー、でも行かないとまずすぎー、リアルきついけどデイリー消化しないとー、みたいな感じ。
 むしろ廃プレイしてる時の方が気にならないんだよな、デイリーがクソでも。

 で、恒例だけど、そろそろやめた理由を書いておく。
 たかだか10日間くらいのプレイだが、何しろ恒例なので。

 まず、プリーストC2辺りが非常に楽しかった、というのが伏線となる。カフリサン一式を買って、ブレッシングLv3に強化Maxでサクラメント付けて、バババッバババッと物凄い勢いで敵が吹っ飛んでった。
 それが次第に、ものすげー何発も殴らないと敵が倒せなくなり、良さげな装備はアホみたいな値段になり、「ここを耐えてモンクになったら、きっとあれ以上に暴れられる世界になる」って思ってたんだけどさ。

 ならんわな。

 とどめは、そこそこいい感じだけどちょっと飽きてたプリ服と比べて、モンク服はあんまり好みじゃなかったことで。
 過去に経験したクラスの服にはいつでも変えられるんだけど、この先ずっとプリ服ってのもなー、と。

 まー、クラスチェンジとか相当でかい離脱チャンスですよね。逃さず離脱出来ました。めでたくクリアです。
 ということで、ToS終了。食った食った。

 次はどうすっかなー。
 DMMイナゴも飽きてきて、事前ガチャも回してたのにほぼプレイせず終わりとか多くなってきたし、事前ガチャ自体を回さなくなってきたし。
 FF11、マビノギ、アイギスに続く「一年半飽きなかったゲーム」はいつ来るかなー。


ソシャゲ系にありがちな経験値計算を自作電卓に組み込んでみた


 こんなん書いてもなー、って思わなくもないが、どうでもいい狭いネタなんか過去に山のように書いてるしな。
 つーことで、自作電卓の話。

 元々、CUIな電卓の自作は好きで、DOS向けに小さいのをアセンブラで書いたりしたこともあった。
 小さいの、と言っても、実行ファイルのサイズが小さいって話で、アセンブラだからソースは無駄にでかい。内部はbigint/rationalな処理で、循環小数は循環節付きで出力するみたいな無駄に頑張った仕様だった。
 Wolfram Alphaとかがある今時なら、こんなもん作ろうとも思わなかっただろうけどさ。

 あの頃の俺はなー、ソースの可読性とか投げ捨てるもの以前で、「見易いソース」って感覚が皆無だった(←今でも怪しい)。そもそもアセンブラで何から何まで全部書いちまおうとか考えた時点で、悪い意味のバカであるな。だがそもそも当時の俺はC言語すら知らねえのだ(笑)。
 なお、TASMのIDEALモードとかいう、もう心底アレなソースだった。いや面白い仕様だったし好きだけど。でもなー。
 しかも、何も考えずに全ての箇所を最適化した。何でもないところでもcall+retをjmpに変えたり、sbbで分岐減らしたり、フラグレジスタ読んで論理演算でどーにかとか、再帰的なマクロでテーブル作って除算を高速にとかやってたような。しかもバカだから曲芸でもコメント書かねえ。
 このように典型的なクソコードであり、完成したからまだいいけど、本気で何やってるか分からんソースになったし、あの経験が特に役に立つことも無かった気はする。
 けど、ほら、アレだ、「昔オフゲで死ぬほどチートやって飽きたからもうオンラインゲームとかでわざわざチートしたいとか思わんし」って現象があるけど、同様に「昔アセンブラで死ぬほどパズルみたいなコード書いて飽きたからもう要らん最適化したいとか思わんし」みたいなのもあるかもしれん。どうだろう。

 何かどんどん狭い話をしてる気が。

 話を戻して。

 Pythonを触るようになって少し経った頃、evalでクソ簡単な電卓作れるよなー、と思った。
 いやまーPerlも入れてたから、ワンライナーで済む話ではあったのだが、そこはそれ。何か作りたくなったのだ。

from __future__ import division, print_function
import sys
expr = ' '.join(sys.argv[1:]) or 'None'
print(expr, '=', eval(expr))

こんな程度だし。

 で、普段から使うようになって、千年戦争アイギスの経験値の計算とかもやってたんだけど。
 ソシャゲ的な奴って、「育成目標は経験値2400、主要狩場で拾えるカードから得られる経験値は225と255、あと手持ちで素材にしたいカードは経験値40が2枚、70が1枚、140が3枚」みたいな状況が良くあるじゃん。
 それを、

>e game.xp(2400, 225, 255, (40,2), (70,1), (140,3))

とかで自動的に計算してくれる機能が欲しいな、と。
 面倒だからやらずにいたけど、アイギスのデイリー復刻実装でこういう計算の需要が俺的に多発したんで、試しに拡張してみた。

from __future__ import division, print_function
import sys
import collections


def clamp(v, min_v, max_v):
    return min(max_v, max(min_v, v))


class game(object):
    @staticmethod
    def xp(target, *exp_and_limits):
        RESULT_HEAD_LEN_MIN = 15
        RESULT_HEAD_LEN_MAX = 50
        RESULT_TAIL_LEN_MIN = 5
        RESULT_TAIL_LEN_MAX = 30

        exp_lims = [
            x if isinstance(x, collections.Iterable)
                else (x, float('inf'))
            for x in exp_and_limits]

        # return [[num, ...], ...]
        def inner_func(target_rest, exp_lims_rest):
            exp_unit, num_limit = exp_lims_rest[0]
            max_num = -(-target_rest // exp_unit)
              # just round up
            max_num = clamp(max_num, 0, num_limit)
            if len(exp_lims_rest) == 1:
                return [[max_num]]

            result = []
            inner_exp_lims = exp_lims_rest[1:]
            for num in range(0, max_num + 1):
                exp_product = exp_unit * num
                inner_target = target_rest - exp_product
                inner_result = inner_func(
                    inner_target, inner_exp_lims)
                for row in inner_result:
                    result.append([num] + row)
            return result

        raw_result = inner_func(target, exp_lims)
        result = []
        for row in raw_result:
            exp_total = sum(
                exp * num
                for (exp, limit), num
                in zip(exp_lims, row))
            excess = exp_total - target
            if excess < 0:
                continue
            result.append((excess, row))
        result.sort(
            key=lambda x: [-x[0], x[1:]], reverse=True)

        head_len = clamp(
            len([
                1 for row in result
                if row[0] == result[0][0]]),
            RESULT_HEAD_LEN_MIN, RESULT_HEAD_LEN_MAX)
        tail_len = clamp(
            len([
                1 for row in result
                if row[0] == result[-1][0]]),
            RESULT_TAIL_LEN_MIN, RESULT_TAIL_LEN_MAX)
        if len(result) > head_len + tail_len + 1:
            result[head_len:-tail_len] = [
                '{} sets omitted'.format(
                    len(result) - head_len - tail_len)]
        return result


expr = ' '.join(sys.argv[1:]) or 'None'
print(expr, '=', eval(expr))

こんな感じで。
 元ソースから他の俺向け機能を削除しまくってから貼ったんで、ちゃんと動くかは知らないけど、試しにさっきのコマンドを走らせてみたら、

>e game.xp(2400, 225, 255, (40,2), (70,1), (140,3))
game.xp(2400, 225, 255, (40,2), (70,1), (140,3)) = [(0, [10, 0, 2, 1, 0]), (0, [7, 1, 2, 1, 3]), (0, [5, 5, 0, 0, 0]), (0, [2, 6, 0, 0, 3]), (0, [1, 7, 1, 1, 2]), (0, [0, 8, 2, 0, 2]), (5, [8, 1, 0, 1, 2]), (5, [7, 2, 1, 0, 2]), (5, [6, 3, 2, 1, 1]), (5, [1, 8, 0, 0, 1]), (5, [0, 9, 1, 1, 0]), (10, [7, 3, 0, 1, 0]), (10, [6, 4, 1, 0, 0]), (10, [4, 4, 0, 1, 3]), (10, [3, 5, 1, 0, 3]), '109 sets omitted', (135, [4, 5, 2, 0, 2]), (150, [0, 10, 0, 0, 0]), (165, [8, 3, 0, 0, 0]), (195, [7, 4, 0, 0, 0]), (225, [6, 5, 0, 0, 0])]

って感じになったので、多分動く気はする。怪しいが。
 なお、出力の意味は、最初の等号の右の

(0, [10, 0, 2, 1, 0])

だけ説明すりゃ分かるかなーと。この場合は「超過0、225*10 + 255*0 + 40*2 + 70*1 + 140*0」ってことで。左の項目が多い方から順にソートされてるから、優先的に使いたい素材を左に指定すると便利とかそんな感じ。
 あと、項目数が10個くらいになるとメモリ使い切る勢いになってくるし、何千通りも最適解が表示されてもまともに見る気にもならないんで、大人しく7個くらいまでにしておいた方が。

 相変わらずの説明する気ねーだろ的記事であるが、まー、分かるべ。行ける行ける。
 あと、Python2.7.x用のつもりだけど、Python3.xでも動いてるようには見える。知らんけど。
 ついでにWindowsの場合、cmd.exeへのショートカットをデスクトップに置いてプロパティ開いてショートカットキーを設定しておけば更に楽に。

 たまにこういう小さいソースコード貼っただけみたいな記事を書くけど、需要無さそうだよなー本気で。ハハハ。
 まーでも、ちょっとコード書ける人なら「そーかーevalで手軽に自作電卓とか便利そうだなー」と思うかもしれないなー、というのもある。ワンライナーと違って、自分用の関数とか定数とか作れるのはかなり嬉しい。
 俺は当時最適だと思ったPythonで書いたけど、Node.jsが登場して一荒れして落ち着いて風格が出てきた今となっては、そっちで書いた方が良い気がしなくもない。電卓としてはPythonの除算演算子(新仕様)は便利だけど。いちいちintとかfloatとか考えなくて済むからなー。

 なお、これで色々な経験値素材の組み合わせを計算させてみたけど、素材を何種類か持ってれば、無駄の無い組み合わせは大抵はゴロゴロ出てくるっぽい。
 だが、そこまでして無駄をなくす意味は多分無い。


ネットワークドライブのファイルを開く時の警告を消してみた


 Windowsのファイル共有とかNASとかで、ネットワーク上のフォルダで主に作業してる人、いますよね。つーか俺もな。
 で、ファイル開く時にいちいち、

開いているファイル – セキュリティの警告
このファイルの作成者を確認できません。このファイルを開きますか?

とか、

開いているファイル – セキュリティの警告
このファイルの作成者を確認できません。このファイルを実行しますか?

とか言われること無いですかね。俺はある。あった。

このファイルはローカル ネットワークの外部の場所にあります。認識できない場所のファイルは、PC に悪影響を与える可能性があります。この場所が信頼できる場合のみ、このファイルを開いてください。

とか下の方に出てて、うるせーバカ、と思いつつも、まあ悪気は無いんだろうと思って、大人しく「開く」とか押してたさ。毎日毎日。

 でも、思うんだけど。
 これ狼少年と同じで、危なくないと分かってるのに毎回「危ないぞー」って言われてると、それはそれで何も感じなくなって危ないんだよな。
 などと、もっともらしい理由を付けてみたけど、単に面倒になった。

 ということで、止め方を調べたところ、コントロールパネル→インターネットオプション、から行くらしい。これ基本的にIEの設定が入ってるとこだよな。変なとこにまとめるなー。ExplorerとInternet Explorerを一体化しようとしてた頃の名残だろか。
 で、セキュリティタブを開いて、と。
 ここから先は、時代によって違うっぽい。最近の環境だと多分、上に並んでるアイコンの「ローカル イントラネット」を押してから、右の方の「サイト」を押す、だと思う。
 もう少し古いと「信頼済みサイト」を押してから「サイト」、かも。

 で、ローカルイントラネットのダイアログが開いたら、詳細設定ボタンを押して、「このWebサイトをゾーンに追加する」のところにフォルダーのパスを入れて追加押すだけ。「このゾーンのサイトにはすべてサーバーの確認 (https:) を必要とする」にチェックが入ってたら切るべきかも。
 フォルダーのパスと言われても意味分からんわ、って場合は、試しに検索してみたら色々なとこで親切に解説されてるようなのでそちらにお任せしたい。

 つーことで、警告無しで開くようになったついでに、ゴミ箱も使えねーかなー、と思ったので調べてみたら英語情報があって、Windows7でもそのまま行けた。基本的には適当なGUID作ってレジストリちょいと弄るだけ。
 日本語情報もあるんじゃねーかなーと思って、Explorer\BitBucket\KnownFolderとかで日本語サイトを検索したら一箇所あった。そっち見た方が楽かも。