Numpy Style の docstring

リファクタリングしたり、他の人に移譲する時にドキュメントがあったほうが良いよなと思い、Numpy Styleのdocstringを調べた。


numpydoc.readthedocs.io

記述例

def add(a: float, b: float=0.0) -> float:
    """
    Add two floats.

    Parameters
    ----------
    a : float
        Description of parameter `a`.
    b : float, default 0.0
        Description of parameter `b`.

    Returns
    -------
    float
        The sum of two floats.

    Yields
    ------
    Type
        Description of generated value.

    Receives
    --------
    Type
        Explaination of parameters passed to a generator's .send() method.

    Raises
    ------
    Exception
        Description of errors.

    See Also
    --------
        Related functions witch users may not be aware of, etc...

    Notes
    -----
        Additional information.

    Examples
    --------
    >>> add(3.0, 4.0)
    7.0

    >>> add(1.0)
    1.0
    """

    return a + b



class MyClass:
    """
    MyClass

    Attributes
    ----------
    id : int
        Identfier.
    value : float
        Value.
    name : str
        Name.

    Methods
    -------
    get_id()
        Return its id.
    set_value(value)
        Set value
    """
    def __init__(self, id: int, value: float, name: str) -> None:
        self.id: int = id
        self.value: float = value
        self.name: str = name

    def get_id(self) -> int:
        """
        Return its id.

        Returns
        -------
        int
            id
        
        Examples
        --------
        >>> A = MyClass(2, 3.0, 'name')
        >>> A.get_id()
        2
        """
        return self.id

    
    def set_value(self, value: float) -> None:
        """
        Set value.

        Parameters
        ----------
        value : float
            an float value to set.
        
        Examples
        --------
        >>> A = MyClass(0, 0.0, 'name')
        >>> A.value
        0.0
        >>> A.set_value(3.0)
        >>> A.value
        3.0
        """
        self.value = value

    
if __name__ == '__main__':
    import doctest
    doctest.testmod()

Sections

アンダーラインハイフンでセクションを区切る。
Short Summary
一行の簡単な説明。
Parameters
パラメータ名 : 型(, default デフォルト値)
パラメータの説明。
Returns

戻り値の説明。
Raises
Raiseしうる例外の説明。
See Also
ユーザーが知覚して無さそうな関連した関数とかの情報。
Notes
補足説明。
Examples
実行例。

所感

VSCodeとかだとホバーした時にドキュメントが表示されて便利。
確かdocstringからドキュメントを生成するツールもあったはず。

ただ明らかに1ファイルの文字数は増えていて、逆に読みにくくならないか心配。

Dockerfile

将来的にOSが変わったりしてライブラリで詰まったりしたら嫌だなぁ、と思い開発環境をDockerで整えることにした。

Docker

コンテナ作るやつ。カーネルはホストOSのものを使うからゲストOSが要らなくて計量らしい。

ライブラリ隔離だけならvenvだけでも良いんだけど、MacとかLinuxに変わった時に入らないライブラリがあると面倒だから、初めからコンテナで開発環境を隔離することにした。

Dockerfile

コンテナの原型となる「イメージ」の設計図。
(https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html, accessed on 2021/04/15)

FROM python:3.9.4-buster

WORKDIR /opt/app

COPY requirements.txt /opt/app
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
FROM イメージのベースを指定
LABEL イメージに付けるラベルの指定
RUN イメージの最上位のレイヤーで実行されるコマンドを設定
CMD コンテナ実行時のデフォルト処理を設定
EXPOSE コンテナがリッスンするポートを設定
ENV 環境変数の設定
COPY ローカルファイルをコンテナにコピー
ENTRYPOINT コンテナ起動時の処理
VOLUME イメージ内にデータを永続的に保持する際に使用する データベース、ストレージ、設定用ストレージetc...
USER 非ルートユーザへ変更
WORKDIR ワークディレクトリを設定 コマンドを実行する場所

VSCodeとの連携

Remote - Container

コンテナ内でVSCodeを使っているかのようにできる。
marketplace.visualstudio.com


実際にアプリケーションとしてデプロイする時はマルチステージビルドしてイメージを計量にしたり、実行ユーザーを変更したり、環境変数を整えたりしてから使う。

ハタ人間パーティー

100階攻略したことを踏まえて、構成してみたかったパーティーについて。

パーティ構成

逆手パ

第一スキル 第二スキル 第三スキル 第四スキル 隊列
主人公 指揮 回収 暗視 警戒 後衛
夏奈 根性 回避 逆手 前衛
白瀬 暗視 回避 曲撃ち 逆手 前衛
るりか 冷静 治療 応援 逆手 後衛

ハンドガン使い3人の逆手パーティー
るりかの応援によって火力を底上げする。
スキルの自由枠が一つあるので例えば《回収》が付けば素材回収パーティーになる。

速射パ

第一スキル 第二スキル 第三スキル 第四スキル 隊列
主人公 指揮 回収 暗視 警戒 後衛
リコ 頑丈 反撃 前衛
委員長 根性 解析 射撃 速射 後衛
エリ 警戒 逃げ足 治療 速射 後衛

リコを盾に委員長とエリで後ろから狙撃するパーティー
速射パで避けられない相手からの一撃をリコの「頑丈」「反撃」で捌いていく。
エリを逆手役にしたらイマイチだったため狙撃手として起用。
火力が欲しければリコも狙い撃ちすればよい。

逆手パ

第一スキル 第二スキル 第三スキル 第四スキル 隊列
主人公 指揮 回収 暗視 警戒 後衛
平山 逆手 応援 体捌き 後衛
大神 根性 底力 体捌き 逆手 前衛
ユイ 回避 急所狙い 逆手 前衛

刀剣急所狙い逆手パーティー
「急所狙い」+「逆手」がどれくらい強力かはよく知らない。
平山の無駄使い?

パーティに必要なスキル

2章を攻略する上で重要となる点がいくつかある。

第一に戦力だ。生半可な火力で挑めばため技を食らって全滅である。また、レベルによって押し切るという戦法も90階から敵のレベルが100を超えることから難しいと思われる。そこで必要なのが火力を保証するスキルと武器を大量生産しやすくする《回収》である。これらのスキルのサポートによって、2章攻略の難易度を下げるのが重要だ。

第二に安定性だ。深層に向かうにつれ、戦闘を回避できるならば回避したい敵が出てくる。そんなときに逃走不可能では全滅は避けられない。したがって、《暗視》スキルは必須とする。また、全滅の原因として多いのは先制からの恐怖やため技だ。これらのリスクを軽減するために《警戒》組み込む必要がある。

第三に周回性だ。深層を目指すには素材集めやレベル上げで数多くダンジョンを潜る必要がある。周回のストレス軽減が重要で、そこで必要となるのが《暗視》《回収》ということになる。

以上より、パーティに必須となるスキルは

  • 火力スキル
  • 《回収》
  • 《暗視》
  • 《警戒》

ということになる。

火力パーティ

火力スキルとして代表的なのが《速射》と《逆手》である。

一部の人は全て《速射》で十分と考えているが、それでは味気ないし、速射パーティー自体にも欠点がある。

一つ目の欠点は運用開始時期の遅さである。1ターン狙い撃ちとして運用するには《速射》レベル5以上、素早さ14~程度のステータスが必要だ。主人公/平山は別として、普通にダンジョンを潜りながらこれを達成するのは早くて70階、遅ければ80階に到達する頃だろう。《速射》が重要となるのは80階以降とは言え、それまでの階層は《速射》無しで攻略する必要があるため、レベル上げや素材集めがやや面倒くさい。

もう一つの欠点は戦闘時間の長さである。1ターン狙い撃ちしても相手の攻撃を受けることは避けられない。また、仕留め損ねるともっと時間がかかり周回する上で面倒くさいことになる。特に深層でもよく遭遇する雑魚集団(ゴキブリやUFO)には手間取り、オートにしても時間がかかるのだ。

速射パは深層攻略には有効だが、ダンジョン周回という点では不利なことを押さえておきたい。そして、レベル上げや素材集めにはダンジョン周回が不可欠なのだ。


一方で、逆手パはスキルレベル1でも武器さえあれば機能するため40階程度から導入することができる。素早さと手数を重視するため雑魚戦でも強く、敵の行動を待たずして戦闘を終えることができる。これは周回する上で非常に有用だ。

逆に、逆手パの欠点は素早さと攻撃力(力or器用さ)を重視するがゆえに、防御力と恐怖耐性を放棄するので先制や恐怖で全滅する危険性が潜んでいることだ。


したがって、速射パと逆手パを混合したパーティー構築が望ましいと考えられる。

主人公のスキル

主人公のスキルは3つとも自由、かつ全てのパーティに主人公が含まれることから、その3つを選別することが重要であることは言うまでもない。

どのパーティーでも使用するという点から、『パーティに必要なスキル』で考察したスキルの中から選ぶのが最適だろう。

主人公に《速射》は必要か?

主人公に火力スキルを付けるとしたら《速射》だろう。
《逆手》も魅力的だが、速射パで主人公の《逆手》が死ぬことを考えるとやはり《速射》だと思う。
主人公は《DQT2000》を常備すると思うのでその点も噛み合っている。

しかし、主人公は素早さが命という点から見れば《速射》するよりハンドガンや刀剣の方が向いていると思われる。

主人公をパーティ内に最速して、速射×2 + 主人公2発 + 壁1発の攻撃で戦闘終了するならば主人公に《速射》は必要ない。

逆手パという観点から見ても、逆手6発 + 主人公1発 o r逆手12発 + 主人公1発で戦闘は終了するためわざわざ狙い撃ちする必要がない。

主人公を火力として捉える必要があるのは単騎や2人でダンジョンを攻略するような特殊なプレイだけで、それを目的としない今回の理論では主人公の《速射》は必要ないと考えている。

主人公に素早さは必要か?

主人公に素早さが必要なのは溜め技に対してパーティ全員が防御できるようにするためである。
防御すれば全滅は避けられるかもしれない(仲間が死なないとは言ってない)が、溜め技の前に倒すために速射パや逆手パを組むのだから、結局主人公の素早さは最速である必要はない。

どうしても避けられない溜め技として先制からの溜めが挙げられるが、この場合主人公がパーティー内最遅でも一応全員防御はできる。
実際には《煙幕》を使っての逃走が最善手なため2章では《煙幕》を2つ常備しよう。

主人公の恐怖耐性

主人公の火力に拘らないで《DQT2000》に《バカ》を付けて常備させれば十分だと思う。

雑談

意外にアクセス数があって、未だに需要があるのかと驚くパワポケ11裏サクセス。

購入して10年くらいでようやく「あれ」を撃破したが、落とした衝撃でカセットが抜けて全滅したり、全滅した一軍を救助しにいった二軍が全滅したり、子供の頃の私にはひどいゲームだった。
しかも全滅したのは手間暇かけてスキル粘りした一軍で、何度1章からやりなおしたことか。

このゲームの攻略法を上げるとすれば、

  • 一軍ではなく二軍でダンジョン攻略
  • 60~80階が正念場で手間暇をかけてその階層で装備を整える

といったところか。

念のため三軍も育成していたけれど、途中で面倒になって3軍はLv70くらいで止まっている。
まあ大体60階くらいで欲張って深く潜った時に全滅するので、100階は遠いけど50~60階でしっかり装備を整えてから60~65階に臨むべき。
「あれ」は委員長の《キュウビ》狙い撃ちや逆手《ドラゴイーター》計4発で7~8割削れるので大したことはなかった。

また興味が湧いたら一章からやり直そうかな。


闇の誘惑解除記念


まだまだ戦えると思う(誰もが扱えるとは言ってない)。


FAQ(?)

構築編

《サンダー・ドラゴン》入れないの?

入れたのも組んでるけど皆も組んでいるのでわざわざ公にする必要がない。

《混沌領域》入れないの?

入れたのも組んである。《サンダー・ドラゴン》も入れて、《ツイン・ツイスター》《禁じられた一滴》で捲る感じのやつ。
アーティファクト-ロンギヌス》で悶えるからあんまり使わない。こちらも《アーティファクト-ロンギヌス》直撃しうるけど、動画のように《PSYフレームギア・γ》意識させて《強欲で貪欲な壺》《闇の誘惑》使っちゃえばこっちのもの。

《激流葬》って強いの?

気持ちよかった。

《屋敷わらし》3積み?

《鉄獣の抗戦》で一手負けするから。

《成金ゴブリン》使ったらワンキルできなくない?

できない。使わなかった時だけ《水晶機巧-ハリファイバー》+《雷龍融合》でワンキルしにいく。

《クリッター》?

nnt339es.hatenablog.com

基本先手取るときだけしか入れないけど、【シャドール】相手には先でも後でも入れる。

プレイ編

勝ち方がわかりません。

相手のリソース削ったり、裏目を回避しながら戦闘アドでアド差広げたり、相手の妨害数見極めてワンキルしたり。

リソースを削るという点では、《エフェクト・ヴェーラー》《灰流うらら》《増殖するG》《ハーピィの羽根箒》当たりの使い方が重要。
上手く誤魔化せば、《雷電龍》握っている状況からトップで《孤高除獣》《雷劫龍》が捲れて、《灰流うらら》貫通、《無限泡影》貫通、《増殖するG》無傷みたいな感じで勝ちが近づく。

相手のデッキに詳しくないと勝てないので一人回しして、どうぞ。

ドロソをたくさん引きました。何から使えば良いですか?

決めたら対戦相手に《灰流うらら》等で狙い撃ちされるので、予測した相手の反応と実際の相手の反応を比較しながら使う。

当たり前だけど、デッキに何が残っているか考えながら使う。

  • 「このデッキ相手には《超雷龍》を置く必要がないし、《雷龍融合》はもう手札にあるから《強欲で貪欲な壺》で手を広げよう」
  • 「《孤高除獣》と《闇の誘惑》があるけど、《闇の誘惑》から使ったら《灰流うらら》使ってくれるかもな、《PSYフレームギア・γ》を意識してくれるかもな、逆にドローしたカードが《PSYフレームギア・γ》で《雷獣龍》効果に対する《灰流うらら》《増殖するG》をケアできるかもな。《PSYフレームギア・γ》にビビッて《アーティファクト-ロンギヌス》を先投げしてない可能性があるから《孤高除獣》から召喚だな。」
  • 「《雷電龍》《雷源龍》で2枚圧縮しながら《超雷龍》出してドローだな。今は後続がないけどトップから後続が続くのは《雷劫龍》雷鳥龍》《雷龍融合》《孤高除獣》の8枚は残っているな。」
  • 「《ハーピィの羽根箒》を持っているけど《灰流うらら》されると、羽根したターンを何もできずに渡しちゃうな。先に《闇の誘惑》で《灰流うらら》チェックしよう。」

あまり自分のデッキの中身は考えていなかった。

サイドチェンジがわかりません。

構築が「メインギミック+引くカード+引きたいカード」なので迷うことはないと思います。
《エフェクト・ヴェーラー》を全抜きすると《神聖魔皇后セレーネ》が死にます。

《PSYフレームロード・Λ》の交換候補は《トポロジック・ゼロヴォロス》《召命の神弓アポロウーサ》《トロイメア・ケルベロス》《ユニオン・キャリアー》

ハタ人間二章武器・アクセサリ攻略

パワポケ11裏サクセス怪奇ハタ人間2章を攻略する上で合成すべき武器・アクセサリをまとめる。

基本的に挙げたもの以外を作る必要はなく、同じものを作り続けて良い性能のものを引いた方が良い。

1~20階

武器

爆弾教本
1章最強武器は二章序盤も健在。

バグ技を駆使しつつ、2軍の育成・素材集めに励もう。

アクセサリ

ゴキユニ
1章最強コスパを誇る防具。

20~40階

武器

20~40階を攻略する上で壁となるのが、《パワードスーツ》《パワーポッド》系の敵である。無属性ではなかなかダメージを与えられない。したがって、【】・【】の武器が優先される。

スタングローブ【
2章開始時に作れるようになる【】属性のグローブ。

グローブキャラに持たせておくと機械系の敵をボコボコにできる。
この階層で確定で【】が付く武器はこれかキャノンの《サンダーキャノン》のみ。
単体攻撃武器はこれだけで、パーティーに一人いると戦車・砲台シルエットに強気で挑める。

グローブは計算式が弱いが、この階層では《ギャスビゴー星人》など属性が付いているだけで有利になる敵が多いため、【】要員として有用である。

ビームナイフ【
1章から作れる【】属性の刀剣。

合成素材が、

  • 《鋼》×1
  • 《ガラスの欠片》×2
  • 《白い石》×1

と軽いため、1章の宇宙人の基地でスキルレベル上げをしていれば早い段階で量産することができる。

刀剣の次の作成すべき武器は50階で解放される《雷神刀》である。
50階到達時では《雷神刀》を量産するには素材が重いため、50~55階で使用することも見据えて性能を粘っておこう。

レイガン【
1章から作れる【】属性のハンドガン。

30階到達時点で《フレアブラスター》《レーザーライフル》《エイミング》といった強力な武器が作れるようになるが、いずれも《幻の合金》を必要とし、その時点で量産することはできない。

たとえライフル・キャノンキャラであっても、この階層では【】属性のついた《レイガン》を粘って攻略したほうが良いと思われる。それほどこの階層では属性が強い。

合成素材は、

  • 《鋼》×2
  • 《ガラスの欠片》×2
  • 《白い石》×1

と軽め。《白い石》の数と相談しながら《バカ》等を粘ろう。

アクセサリ

鋼のプロテクター
1章終盤で用いたものが一つあれば良い。

迷彩服
素早さを重視するパーティーで、プロテクターを付けたくないならアリだろう。

《丈夫な布》は残しておきたいので、付加価値を粘る必要はない。

白石の指輪
後衛はこれを二つ付けてUFO対策を行おう。

素早さや器用さの補正+3を狙いつつ、《連打》や《バカ》等が付いたら前衛に回してやれば良い。

40~60階

まだ敵はそれほど強くない階層だが、油断すれば《パワーポット》《宇宙ビースト》《ドラゴポット》といった敵にやられてしまう。

40~50階では《鋼》集め、50~60階で《ふしぎな機械》集めに徹底して着実に装備を整えていくのが重要だ。

武器

この階層をグローブで抜けるのは難しい。50階に到達すれば《ヘビーナックル》を合成できるようになるが、素材が重く性能を粘れないためやはり厳しい。可能であれば刀剣に持ち替えて攻略することをおすすめする。

雷神刀【
50階到達で合成可能になる【】属性の刀剣。

素の性能が高いため、大幅なマイナスが付かなければそれだけで刀剣キャラは安泰である。

【構える】など付けば最高だが、素早さや力補正が付いても《逆手》との併用で80階まで通用する。

《玉鋼》《堅い木》は全てここにつぎ込むつもりで節約しておこう。

フレアブラスター【
30階到達時に合成可能となる【】属性のハンドガン。

作成可能になる時期に比べて、性能が著しく高い。《レイガン》では厳しくなる40階後半ではこちらに持ち替えるようにしたい。

《幻の合金》はここにつぎ込んで、器用さ・素早さ補正を狙おう。たまたま【ねらう】が付いても、それはそれで有用だ。

レーザーライフル【
2章開始時に合成可能となる【】属性のライフル。

ライフルキャラや主人公/平山に持たせて【】属性をカバーしよう。

【ねらう】が付いて、かつスキル粘りをしていればレベル50当たりで主人公/平山の《速射》がLv5になって1ターン狙い撃ちが可能となるため、50階以降に出現する単体大型に対して強く出られる。

《レイガン》《ビームナイフ》の火力不足が気になってきたらこの【】属性武器をパーティーに導入しよう。

アクセサリ

防刃ベスト
30階到達時に作れるようになる胴防具。

防御力は心許ないが、特殊効果の【負傷】無効がミソで、これを付けているかいないかで《宇宙ビースト》戦の安定感が異なる。

《宇宙ビースト》を楽に倒せるようになれば、《魔獣ジャケット》に繋がるので50階到達前までに前衛用のものを粘っておきたい。

  • 《丈夫な布》×6
  • 《鉄》×4

だけで合成できるので、低階層の内に《丈夫な布》をたくさん合成しておくと良い。

魔獣ジャケット
50階到達時に合成できるようになる胴防具。

この階層での量産は厳しいが、60階を目指す上で前衛の防御力としていくつか作っておきたい。

ジャングルブーツ
《丈夫な布》×4で合成できる脚防具。

素で素早さが上がることから力・器用さの補正を粘ることで逆手パーティーの性能向上に貢献する。

防御力も6と指輪より高いため、属性耐性を付けにくいこの階層では重宝する。

60~80階

60階からは《宇宙ドラゴン》《宇宙クリオネ》といった単体大型の敵が追加される。

さらに70階からは《ダークビースト》《ドラコポットMk2》《宇宙戦車》といった進化種が登場するため、慎重にレベル上げを行う必要がある。

武器

属性武器は依然有効だが敵によって有効な属性がばらけるため、パーティー全体として隙のないような武器選び・合成が望まれる。

ドラゴン系に対する【】、《ダークビースト》《宇宙ガンナー》に有効な【】を上手く混ぜ合わせて選びたい。

ヘビーナックル
50階到達時に合成できるようになる【ためる】確定のグローブ。

《幻の合金》を敵がドロップするようになるため、素材に余裕が出てきたら【】属性を粘ってグローブキャラに持たせたい。

ライトサーベル【
70階到達時に合成できるようになる【】属性の刀剣。

この階層では粘った《雷神刀》がまだ有効であるため合成を急ぐ必要はないが、刀剣キャラでパーティーを固めている場合や逆手パーティーの場合属性を散らすために合成した方が良い。

性能の良いものができた場合、《宇宙ウィルム》用に終盤まで使うことができる。

レイブラスター【
50階到達時に合成できるようになる【】属性のハンドガン。

合成素材が、

  • 《ふしぎな機械》×2
  • 《プリズム》×1
  • 《白い石》×1

と、とにかく軽い。50~60階で集めた《ふしぎな機械》を投入して、逆手用の高補正武器や【ねらう】付きを狙おう。

《フレアブラスター》と上手くパーティー内で混ぜることで、隙のないハンドガンパーティーが出来上がる。

アクセサリ

この階層から防御力よりも属性耐性が重要になってくる。レベルの上がってきた回避・頑丈を生かすためにも壁役もしっかりと属性耐性を整えた方が良い。

赤光の指輪
耐火を25%上昇させるために用いる。

《竜麟の指輪》のほうが高補正が付くが、この階層では《竜のウロコ》は《ドラゴイーター》用にとっておきたい。

機械の指輪
耐電・耐光を25%上昇させるのに用いる。

《ふしぎな機械》はこの階層を抜ける頃には山ほど集まって性能を粘れるので、60階未満では合成は程々にして残りの《ふしぎな機械》は武器に回そう。

80~100階

90階からは敵のレベルが100を超えるため、装備やスキルがより重要になる。80階で解放される最強装備群はあれば良いというほどで、100階攻略の観点で言えばそれほど重要ではない。80階まででどれだけ優秀な装備を作れるかが攻略のカギである。

武器

ドラゴンハート
《ドラゴコア》を必要とするグローブ。

ドラゴン狩りのついでに落ちた《ドラゴコア》の使い道。

コスモミキサー
【貫通】付き無属性3回攻撃の刀剣。

3回攻撃ということでクリティカルを狙うのに適するが、90階以降の敵に対して思ったより火力が伸びない。

属性があれば爆発が防げたのに、と思うこともあるので《ライトサーベル》をひたすら粘るのもアリ。

ドラゴイーター【
【負傷】付き【】属性のハンドガン。

ハンドガン使いはこれさえあれば良い、というほど強い。

たとえ【】属性が効かない敵であってもゴリゴリ削ることができるため、《竜のウロコ》と《宇宙鉄》はどんどんつぎ込むべき。

キュウビ【
60階の時点で合成できるようになる【】属性のライフル。

【ねらう】が付くのが前提だが、「あれ」はこれ一丁で事足りる。

ライフル使い(ほぼ委員長のみ)ならば普段から持たせても火力的に問題ない。

フレイムキッス・フォトンスパイク・サンダーボルト
属性【貫通】キャノン。

【ねらう】が付くのが前提だが、それさえ粘れば属性と【貫通】が保証される。

そもそもキャノン使えるのが主人公、平山、堤ぐらいしかおらず、主人公が使うにしても狙い撃ちしない限り火力は出ないため無理して作る必要はない。主人公、平山に関しては【ねらう】付き《ドラゴイーター》でも問題ない。

アクセサリ

逆鱗スーツ
逆鱗の指輪
虹色の指輪



TCGエージェント第4モデル

TCG学習モデルと問題点 - Just a Note for Hobby

単純なモデルを構成して、再探索を試みる。

モデル4

更新式

 Q \leftarrow Reward + \gamma \times Q

Reward:自分のアド - 相手のアド
 \gamma:割引率

Qネットワークの出力層の活性化関数をLinearにしたため、報酬と割引価値が釣り合ったところで収束するはず。

手法

  • DDQN(2回毎に更新)
  • Experience Replay (バッファサイズは500)(バッファサイズを半分にして学習させても大きな違いは見られなかった)

結果

1000episode学習させたエージェントをEvaluateしたところ、勝率60%で収束。

補足: Evaluate方法

前提として、どのモデルも同じ対戦相手で学習を行うとする。
学習を行った対戦相手に学習タスクなしで100マッチ行い、その勝率で比較する。

考察

モデル1に見られたようなデッキ切れで敗北というのは見られなかった。
以前は報酬を手札、フィールド、ライフ、デッキ枚数の変化量から算出していたが、今回のモデルではフィールドとライフの変化量から算出したため、よりライフを取るアクションが高く評価されたのと考えられる。


一方で、強力なモンスター1体だけを成立させた後、ただ攻撃することによって勝利を得ていた。そのモンスターが処理された場合、以降何もせずに敗北していた。

#ToDo
敗北するのは、より良いアクションを探索しないからであり、Q値を行動選択の確率として解釈するか、ε-greedy手法を取り入れる必要がある。

学習過程を分析すると、300回ほどで勝率60%の能力に達しており、このモデルではそれ以上の能力が得られないことを示唆している。

横軸はマッチ数、縦軸は勝利数を示し、グラフの傾きは勝率を表す。

CythonのPickle化

ポインタをもつクラスをPickle化しようとしたらエラーを吐いたので、その対処法のメモ。

__getstate__メソッドの実装

ポインタにしているオブジェクトを復元できるだけの情報を一旦Pythonオブジェクトのメンバにして、__dict__stateとして返す。

__setstate__メソッドの実装

__getstate__で吐き出した情報からポインタオブジェクトを再作成。

実装例

cdef class SomeClass:
    cdef CppClass* cpp
    def __init__(self, id: int) -> None: # イニシャライザ
         self.cpp = new CppClass(id)


    def __dealloc__(self) -> None: # new したメモリの解放
        del self.cpp


    def __getstate__(self): # pickle化する時に呼び出される
        self.id = self.cpp.getid() # 復元できるだけの情報を取得
        state = self.__dict__.copy() 
        del self.id # 不要なオブジェクトを削除
        return state


    def __setstate__(self, state): # unpickle化する時に呼び出される
        self.__dict__.update(state)
        self.cpp = new CppClass(self.id) # 再作成。必要があればセッターを使って復元する
        del self.id

その他

より低レベルなPickleの実装として、__reduce__があるけど、おそらく可読性や実装の楽さで__getstate__, __setstate__が勝る。

というより、__reduce__でリビルダーを上手く実装できなかった。

参考資料

pickle --- Python オブジェクトの直列化 — Python 3.9.1 ドキュメントより引用

object.__getstate__()
クラスはそのインスタンスをどう pickle 化するかについてさらに影響を与えることができます; クラスに __getstate__() メソッドが定義されていた場合それが呼ばれ、返り値のオブジェクトはインスタンスの辞書ではなく、インスタンスの内容が pickle 化されたものになります。__getstate__() がないときは通常通りインスタンスの __dict__ が pickle 化されます。

object.__setstate__(state)
非 pickle 化に際して、クラスが __setstate__() を定義している場合、それは非 pickle 化された状態とともに呼び出されます。その場合、状態オブジェクトが辞書でなければならないという要求はありません。そうでなければ、 pickle された状態は辞書で、その要素は新しいインスタンスの辞書に割り当てられます。

__getstate__() および __setstate__() メソッドの使い方に関する詳細な情報については 状態を持つオブジェクトの扱い 節を参照してください。