2019年12月30日月曜日

Seleniumで2048を解いてみた


背景

Seleniumはブラウザの操作をプログラムで組み立てられるフレームワークです。
Webアプリケーションのテストなどに利用されます。

ここ数ヶ月自分がやりこんでいる2048というゲームをSeleniumを使って解くプログラムを作ってみました。
実行時の様子はこちらです。



備忘録を兼ねて取り組んだ内容を共有します。

使ったもの

前回の記事(UbuntuでSelenium Serverを通して作ったFirefoxのセッションを使いまわす方法)で構築した、Selenium ServerとPython3でSeleniumが動く環境を利用しました。

実行方法

プログラムをダウンロードして、Selenium Serverと共に実行すれば動かせます。
背景で紹介した動画で実行している操作を共有します。

プログラムをgitを利用してクローン(ダウンロード)
動画ではこれは既に行っている状態になっています。
mkdir ~/gitprojects
cd ~/gitprojects
git clone https://github.com/asukiaaa/selenium-play-2048.git
git checkout 2019.12.30

Pythonのプログラム実行前に、ダウンロードしたSelenium Serverを実行しておきます。
java -jar selenium-server-standalone-3.141.59.jar

Selenium Serverを実行しているのとは別のターミナルで実行します。
cd ~/gitprojects/selenium-play-2048
session_id=`python3 src/startSession.py`
python3 src/solve2048.py $session_id

60%くらいの確率で2048を達成します。

工夫した点

駒の操作後に0.1待機

駒を読み取る際に、操作直後に読み取ると操作前のボードを読み取ってしまいます。
そのため、0.1秒待機してから読み取っています。

該当するコードはこちらです。
https://github.com/asukiaaa/selenium-play-2048/blob/2019.12.30/src/utils.py#L191-L202

操作時は新しい駒だけを読み取る

ボード上の駒を全部読み取ると0.2秒くらいかかりますが、操作した直後に現れるtile-newというクラスが付いた駒だけを読み取ることで、全体読み取りに対して約16倍の高速化を行なえています。
一手操作後のボードの状況は計算できるため、計算後のボードに新しい駒を追加することで次のボードを作成しています。

該当するコードはこちらです。
https://github.com/asukiaaa/selenium-play-2048/blob/2019.12.30/src/utils.py#L255-L264
https://github.com/asukiaaa/selenium-play-2048/blob/2019.12.30/src/utils.py#L165-L173

3手先の予測

最初は操作したほうが良いと思う法則をifで連ねていましたが、条件分岐の関数が長くなって全体の把握が難しくなり、条件の新規追加追加が難しくなりました。
そのため、有用そうな3手先の予測から最も良さそうなものを採用する形式にしました。

該当するコードはこちらです。
https://github.com/asukiaaa/selenium-play-2048/blob/2019.12.30/src/utils.py#L13-L30
https://github.com/asukiaaa/selenium-play-2048/blob/2019.12.30/src/utils.py#L165-L173

まとめ

SeleniumをPythonを通して利用して2048を達成できました。

0 件のコメント :