gym-super-mario-brosで途中から再開する方法

mario_backup_reset.gif

日曜日の勉強会の仲間が「マリオAIチャレンジ」をやっているのを見ていて、楽しそうだったので最近触っています。

karaage.hatenadiary.jp

まだ学習をさせるところまでは行けていなくて、マリオに行動を配列で指示したり、gifなどの画像に出力させるところをいじくっているところです。

ところで、途中まで進んだマリオを、そこから再開できる方法があるか考えていました。それができれば計算が早くなるという想定です。最初はdeepcopyでできるのではないかと考えたのですが、やってみるとうまくいきませんでした。おそらくNES emulator (=nes_env.pyの_LIBオブジェクト)がpythonのdeepcopyでは適切にコピーされないのだと思います。

不慣れなPythonなのですが、コードをがんばって追いかけると、nes_env.py_backupメソッドresetメソッドを呼べば良さそうなことまでわかりました。backupメソッドを呼ぶとその箇所が保存されて、その後のresetメソッドではそこに戻ることができるようです。 しかし、resetメソッドはSuperMarioBrosEnvから呼べるのですが、backupメソッドは外部に公開されていないメソッドなので、使えないようなのです。困った。

いろいろ調べたところ、envオブジェクトはWrapperクラスのサブクラスの複数回の委譲を繰り返してSuperMarioBrosEnv(そしてNESEnv)に到達するようで、このWrapperクラスにbackupメソッドを追加すれば良さそうだということに気がつきました。

Pythonのクラスにメソッドを後から追加する方法を調べて、手探りで書いてみました。

# Wrapperクラスにbackupメソッドを追加
def backup(self):
  if hasattr(self.env, "_backup"):
    self.env._backup() # gym_super_mario_bros.smb_env.SuperMarioBrosEnv#backup
  else:
    self.env.backup() # 委譲

Wrapper.backup = backup

(↑2023/01/08 22:55修正)

backupメソッドを持つオブジェクトが見つかるまで委譲先を探して、backupメソッドを持つオブジェクト(SuperMarioBrosEnvクラスのオブジェクト)が見つかったらそれを実行します。 やってみると、うまくいくようです。やった!

ちなみに、Wrapperクラスは委譲の仕組みが入っているので、resetメソッドは何もしなくても委譲されてSuperMarioBrosEnvクラスのresetメソッドが呼ばれます。SuperMarioBrosEnvクラスの_backupメソッドが委譲されていなかったのは、 _ で始まるメソッド名だからです。 (2023/01/08 22:55追記)

Google Colaboratoryも、最小限のコードでの再現環境として作っておきました。 colab.research.google.com

わかりにくいかもしれませんが、最初はクリボーにぶつかってやられているけど、ちょっと戻ってジャンプで回避しています。

Maker Faire Tokyo 2022 にベランダラボで出展しました

前回の続きです。出展してきました。

akiyah.hatenablog.com

 

9月2日(金)は会社を休んで作品を半分運んで、9月3日(土)に残りの半分の作品を運んで、そのままイベントに入りました。

9月4日(日)は、家族(奥さんとむすめ2人)も来て、手伝ってくれました。

 

今回は、牛乳パックフエを展示・販売したのですが、多くの子供たちに触ってもらえてとても嬉しかったです。押したら音が出るという単純さがよかったのかなと思いました。

 

下のむすめ(小学1年生)がPOPみたいなものをたくさん作ってくれました。お客さんにテンセグリティの作り方の説明もしてくれました。本当の(?)お店屋さんをするのが楽しかったみたいですね。

("2しゅるい"というのは、牛乳パックフエにはまっすぐねじるタイプの2種類の折り方があるという意味です)

 

まえこっかくのSUZUKIさんが見に来てくれたのはとても嬉しかったです。紙パックフエの前に円筒ねじり折りに興味を持ったのはまえこっかくのSUZUKIさんが何年か前のMakerFaireで発表されていた人工筋肉でした。今回も、まっすぐよりねじるタイプの方が伸縮がいいという助言をその場で教えてもらって、参考になりました。

その後、紙パックの研究を始めたようで、フットワークが軽いですね!

 

ところで、ベランダラボはD-02-01だったのですが、お隣のD-02-02twitterでよく拝見していた藤田伸さんで、とてもハイクオリティなテンセグリティを展示されていました!販売していたテンセグリティキットも完売されていましたよ。

 

牛乳パックフエは20個くらい販売することができました。作ったものの2/3くらいですかね。牛乳パックフエは、もうちょっと成長させて新しい形に挑戦していきたいです。 いずれ牛乳パックフエの知名度が上がって、小学校の夏休みの工作に使われたりしたら嬉しいなぁ。

Maker Faire Tokyo 2022 にベランダラボで出展します(牛乳パックフエとテンセグリティ)

2022年9月3日(土)、4日(日)のMaker Faire Tokyo 2022にベランダラボで出展します。

 

makezine.jp

 

 

いつものテンセグリティに加えて、今回から作成した牛乳パックフエを展示します。

牛乳パックが伸び縮みして、音を出すことができます。よく見ると2種類ありますよ。

今回は販売ができるようなので、たくさん作ってみました。

 

 

伸縮する牛乳パックの展開図2(ねじるタイプ)

続きです。

伸縮する牛乳パック2

↑ねじるタイプの作り方のメモとして、展開図を書いておきます。

 

伸縮する牛乳パックの展開図2

牛乳パック伸縮2 – GeoGebra

 

赤い線が山折りで、青い線が谷折りです。

牛乳パックの幅は7cmなのですが、それの2倍の長さを5で割って、7*2/5=2.8cmが横の線の間隔になります。これはややこしい計算をして求めたのですが、ここではその計算は省略します(牛乳パックの元々の折り線を生かしてねじるのにはそれなりの制約があるのです)。

点線に沿って牛乳パックにカッターで切れ込みを入れるのですが、その目印をつけるのは結構苦労するかも、、、。まあ、そこまではなんとかして、注ぎ口側から折っていって作ります。

ねじれがあるので少し形が面白くて、そこが気に入っています。伸縮させると45度くらい回転するのも少し気持ちいいですね。

伸縮する牛乳パックの展開図1

伸縮する牛乳パック1

↑これの作り方のメモとして、展開図を書いておきます。

伸縮する牛乳パックの展開図1

牛乳パック伸縮1 – GeoGebra

 

赤い線が山折りで、青い線が谷折りです。横の線の間隔は調整可能ですが2cmにしています。一番上と一番下だけ半分の間隔で、1cmです。

この赤い線と青い線にカッターで切れ込みを入れて、その切れ込みに沿って注ぎ口側から折っていって作ります。

作りとしてはシンプルだし、出来上がりのバランスも良いので、気に入っています。

無限三目並べの必勝法

無限三目並べと言うゲームがあります。三目並べ(マルバツゲーム)に似たルールで、自分のコマの4つ目を打つ時に自分の一番古いコマが消えるというゲームです。

このゲームのQ学習をJavaScriptで作っていました。Q学習した結果を対戦相手として遊べるようにしているので、やってみてください。だんだん強くなるようにしています。

https://akiyah.github.io/3x3/public/?type=ThreeState

(最初は弱いですが、ある程度経つと強くなってきます。)

 

この実装を応用して、無限三目並べの必勝法を計算させて記述しました。(Q学習があんまりうまくいかなくて、原因を探すためにも必勝法を知りたかったのです)(必勝法を探すロジックは、全盤面のパターンを内部的に持ち、どちらかの勝利が確定している盤面から、打つ手を逆に辿って計算しています)

無限三目並べの必勝法

 

先手必勝です。先手の最初の手は上、下、右、左のどれかで、それ以外では必勝ではありません。対称性を除いて、必勝法の画像では「上」を選択しています。

後手の最初の手は対称性を除けば5通りあります。結果的には、どのパターンでも先手が勝てます。後手が最も長く生き残るのは、左下か右下を選択したときで、先手が勝つまで13手かかります。

決着がつく最後の盤面は、どれも似ていますね。後手の一番古いコマが消えたところに先手が打って勝利ですね。

 

必勝法を見つけたのはいいですが、覚えるのはちょっと大変ですね。一本道のところもあるのですが、正しく選択しないと負けてしまう箇所もあります。

 

3x3のマス目を使った対戦ゲームはまだ他にもありそうなので、今後は別のルールでQ学習と必勝法探しを続けていきたいです。

LLNYでYouTube英語動画の日英字幕を同時に見られる!

YouTubeの英語動画を見るときに、YouTubeの機能で自動生成の英語字幕をつけることはできるし、さらに自動翻訳した日本語の字幕をつけることもできます。でも、どちらかを選ぶことになるので、日本語と英語の字幕を同時に見ることはできません。

それができるようになるのが、LLNY(Language Learning with Netflix & YouTube)というChrome拡張機能です。

chrome.google.com

f:id:Akiyah:20211107015952p:plain

LLYN

英単語にマウスを合わせると日本語の意味を表示してくれるし、クリックすると発音してくれます。マウスオーバー中は動画を止めてくれるのも便利です。

 

実は以前はLanguage Learning with Youtube BETAというものを使っていたのですが、YouTubeの仕様変更の影響か、使えなくなっちゃっていたのですよね。ほぼ同じ機能(そしてほぼ同じ名前)のLanguage Learning with Netflix & YouTubeを最近見つけたので、こっちに乗り換えました。とても便利なので助かっています。