刺身の上にたんぽぽ乗せる日記

プログラミングしたり、自販機の下に落ちてる小銭を集めたりしてます

Pyppeteerをdocker環境とmacで動かす

Google Cloud Buildでbazel testで動かしてたpyppeteerが動くようになるまでのメモ。

  • TL;DR
    • Docker環境ではダウンロード済みのchromiumã‚’executablePathで指定
    • pyppeteer==0.0.25
    • websockets==6.0.0
    • pyee==6.0.0


ブラウザからの反応がなくなるタイプの問題はpyppeteerのlogLevelをDEBUGにすると見つけやすい。

import logging
browser = await launch(logLevel=logging.DEBUG, args=["--no-sandbox"])

File "/builder/home/.cache/bazel/_bazel_root/eab0d61a99b6696edb3d2aff87b585e8/execroot/__main__/bazel-out/k8-fastbuild/bin/django/testutil/test_puppeteer.runfiles/pypi__pyppeteer_0_2_5/pyppeteer/launcher.py", line 226, in get_ws_endpoint
raise BrowserError('Browser closed unexpectedly:\n')
pyppeteer.errors.BrowserError: Browser closed unexpectedly:

stackoverflow.com

Docker内で走らせたときにこのエラーが出るという報告が多数出ていた。pyppeteerが勝手にダウンロードするchromiumでは動かず、自分で予めダウンロードしたchromiumでないと動かない。executablePathでchromiumのpathを渡すことで直る*1。Chromiumのバージョンは、87.0.4280.141で確認。

websockets.exceptions.ConnectionClosed WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason

github.com

このエラーは単純なページの表示では起きないらしいが、少し複雑なページのテストを行うと出るらしい。websockets==6.0.0にダウングレード*2すると直る。

TypeError: create_connection() got an unexpected keyword argument 'ping_interval'

pyppeteer0.2.2~0.2.5(最新)はwebsockets==6.0.0にない引数を使うためpyppeteer==0.0.25までダウングレードする必要がある。この段階でdockerでpyppeteerは動くようになったが、macでまだ動かなかった。

RuntimeWarning: coroutine 'Browser._targetInfoChanged' was never awaited f(*args, **kwargs)

github.com

pyee==6.0でdocker/macの両環境で動くようになった。

*1:Macでは問題なかった

*2:最新版は8.0.0

ダンジョンメーカー シナリオモード 攻略メモ

結構大変だったので書いておく。

ED分岐や即死回避の選択肢はwikiを参照。

wikiwiki.jp

重要ポイント

モンスター
  • スライムとゾンビ以外は侵略時に自己回復が追いつかないため役に立たない
  • 魔物買うときも品揃えの強化の条件は購入数・購入価格ではなく、買った日数なので、スライムとゾンビだけ買えばいい。
  • スキルは変更できないので、購入時にいらないスキルがついてるモンスターは買わない
  • 研究所と抽出の効率化のためにもいらないモンスターはなるべく買わない
  • 王城用の呪いのオーラ持ちと侵略された王城/影の境界用の黒き守護の紋章持ちを探す。
    • 訓練済み★5 LV999再生する鋼スライムでも王城攻略は無理だったので呪いのオーラは最優先したい
    • 訓練済み★5 LV600くらいで、呪いのオーラ・石の皮のスライムでソロで倒せた
  • 呪いのオーラ持ちが見つからなかったので、騎士と巫女で代用も試したけど、耐久力が足りずに王城は耐えられなかった
侵略
  • 侵略失敗してリザルト画面でモンスター死んだらホームに戻って再開。左下の撤退で誰も死なずに退却できる。
  • 雑魚を送り込んでも相手のバフの餌食になるので、侵略は少数精鋭で。継承したモンスターだけを送る
  • 特に王城・影の境界などは専用の対策スキルモンスターソロで送り込む
  • 勝ったら破壊。堕落勇士は侵略で使い物にならないので、略奪は必要なし。破壊すると、防衛の時間が伸びるため、引き継ぎモンスターが十分強くて、LV上げが必要ない場合は撤退すると周回が速くなる
防衛
  • 施設は利用金額に応じて充実していく。トゲや祭壇2とか買っていばらのやぶ・抽出・研究所を出していく
  • 自ダンジョンは入り口に研究所、その上か下に抽出 - ★は5まで、訓練は1回なので、研究所を入口に置く
  • 勇士を倒したモンスターに経験値が入るので、勇士を倒してしまうダメージ罠は置かない
  • 研究所は強化一回すると効率が倍になる。訓練はそんなポイントいらないので、強化しなくても良さそう
  • いばらのやぶ置いて権能2オートしてればまず負けない。いばらが置けるまでは権能2撃つ前にモンスターがやられることがあるので、少し入り口から離す
  • 少数精鋭の部隊を作りたいので、魔王部屋前に任意の戦闘部屋、その前にいばらの二部屋でモンスターを強くしていく
周回
  • 40日経過ゲームオーバー → 巫女 → 秘書 → ルナ → (巫女2 → ルナ2 →) 王女
    • 選択肢はwiki参照
    • 巫女とルナ2回目は継承枠増えるだけなので、なくても大丈夫
  • ルカ解禁されたらLVは上げておく

Google App Engine + Djangoの地雷

基本的には https://cloud.google.com/python/django/appengine にそって行けばいいんだけど、地雷を一杯踏んだので書いておく。

  • App Engineの場所はアメリカにしろ。AsiaはSQLとApp Engine一緒に置けない。
  • 書かれてないけど、SQLのDB作成時に、場所はApp Engine準拠にしておくと多分いい?
  • python manage.py migrateする前にpython manage.py makemigrationsしたほうが良さそう
  • ローカルサーバーで動かす時はpython manage.py runserverではなく、dev_appserver.pyを使わないとgae関連のapiが使えない
  • 大きめのファイルのアップロードをdjangoで受ける際は自作のupload handlerを描かないといけない(http://stackoverflow.com/questions/3586134/how-to-avoid-notimplementederror-only-tempfile-temporaryfile-is-available-for-u)
    • 1.9の実装はNamedTemporaryFile使ってるだけなので、そこを変えたコードをコピペで作ったら動いた

Poker AI用GTOメモ

Poker's 1%: The One Big Secret That Keeps Elite Players On Top

Poker's 1%: The One Big Secret That Keeps Elite Players On Top

これに書いてあったやつのメモ書き。

全体のバランス

ベット・コールする度に、綺麗に一定割合でハンドが絞られていく。
スターティングハンドが広すぎると、レンジが弱すぎるので、タイトにいかなくてはいけない。

call

全てのストリートでcall頻度は7割くらい欲しい。
3割以上foldしてると、ポット打ち続けるだけで利益出る
callするコンボは上位7割

7割欲しい、というのは、恐らく相手のハンドコンボと自分のハンドコンボのエクイティが概ね変わらないという前提で正しいだけなので、ハンドコンボのエクイティが大きく異る場合*1はもっとfoldすべき。

bet

betはvalue:bluff比率が2:4、2:2、2:1と打つ度にbluffを減らす。
callされた = 上位7割なので、ブラフコンボを減らさないと危険。
打つ度にハンドを強くpolarizeさせていく。

  • 例:turnではOESDとかはbetではなくcheck。ガットはbetでpolarize
  • 例:riverはツーペア・オーバーペアとかとミスドローでbetして、マージナルなメイドハンドはcheck(ブラフキャッチ?)に回す

turnがbrickの時は変化が少ないので、betting frequencyを減らしてもいい。

bet戦略 → call戦略

betした後、ハンドがcheck側のcomboの場合、call戦略に移る。後でまたイニシアチブは奪い直してbet戦略に戻ってもいい?

バレルする時、バリューのコンボはそのまま、ブラフのコンボを半分にしてvalue:bluff比を調整する。bet-betとbet-checkのラインを比べると後者が弱すぎて、7割コールできる強さにならないけど、相手のcallしてくるcomboと同じ強さのcomboでチェックできないので、ごく少数のbluff catcherでチェックしていい。floatは多分十分なバレル頻度があればpunishできる。

*1:bet-checkラインなど

pypy virtualenv設定メモ

  • sudo apt-get install pypy virtualenv

$ virtualenv test -p `which pypy`
$ source test/bin/activate
$ pip install ...

サーバがまた起動しなくなってた


Gave up waiting for root device. Common problems:

  • Boot args (cat /proc/cmdline)
  • Check rootdelay= (did the system wait long enough?)
  • Check root= (did the system wait for the right device?)
  • Missing modules (cat /proc/modules; ls /dev)

ALERT! /dev/disk/by-uuid/34e5c1 ... does not exist.

こういうやつでてた。

大体の場合はディスクデバイスが起動準備間に合ってない場合に起きるエラーで、すぐexitすれば、大体ディスクが立ち上がってるから、そのまま起動できる。回避するにはrootdelay=をすごく大きい数字にすればいいらしいけど、自分の場合、

(initramfs) blkid

これやっても何のディスクも表示されないから、そもそもディスクが認識されていない。ディスクがマウントされてない以上、busyboxのツール以外何もできないので、死ぬかと思ったけど、幸いcloudcoreのVPSは、OSインストールの際、任意のISOが選べる。「OSのインストール」って書いてあるからISOで上書きするのかとおもいきや、単純に任意のISOからブートできる、というだけだったので、レスキューディスクが使える。debianの最小CDhttps://www.debian.org/CD/netinst/を使ってrescueで立ち上げたら、無事ディスクは生きてたので、まずバックアップをとった。

とりあえずgrub・initramfsの問題かと思って両方共書き直ししてみてもだめだったので、カーネル入れなおししてみた。

http://forums.debian.net/viewtopic.php?t=84834

# apt-get purge linux-image* && apt-get update && apt-get install linux-image-686

とあるけど、自分の場合はlinux-imageの最新版まだ入れてない状態だったので、そっち選んでインストール後、再起動で無事サーバが復活した。死ぬかと思った・・・。