2020年1月28日火曜日

ドラクエ8のカジノビンゴを完全自動化しました

久しぶりに電子工作しました
iOS のスイッチコントロールが便利だという話です

環境

  • macOS 10.15.2
  • Arduino IDE 1.8.10
  • Arduino Pro mini (5V, 16Mhz)
  • サーボモータ SG90

成果物


Arduino Pro mini + サーボモータ (SG90) を使って先端につけたスタイラスペンを使って自動で画面にタップする感じです
回路などポイントは後述しています

これと iOS のスイッチコントロールを組み合わせることで永遠にビンゴし続けます
ちなみに土台はダンボールを使って簡単に作っています

背景

スイッチコントロールという iOS の機能を知ったがスイッチコントロールだけだと自動化できなかったので定期的にタップしてくれるロボットを作成した感じです
あとは久しぶりに電子工作したかった感じです

回路

fritzing で書いたブレッドボード回路は以下の通りです
スライドスイッチを入れていますがなくても OK です
サーボモータに VCC (5V) と GND を接続しあとは制御するようのピンに接続しているだけです

実写は以下の通りです
緑色のひょろひょろと出ているジャンパー線は GND から出ておりスタイラスペンにつながっています (これポイント)
電源は面倒なので FTDI のシリアルケーブルでそのまま Mac の USB ポートから供給しています
もちろん 5V 電源であればアダプタでも電池でもリチウムイオンでも何でも OK です

ブレッドボード上の回路部分だけアップ
ノイズ除去用に VCC と GND のすぐそばに並列でセラミックコンデンサを接続しています

スケッチ

大したスケッチではないですが一応紹介します
9 番ピンでモータの制御をしています

#include <Servo.h>

Servo myservo;
int led = 9;

void setup() {
  myservo.attach(led);
}

void loop() {
  myservo.write(90);
  delay(10000);
  myservo.write(180);
  delay(500);
}

タッチペン

先程紹介したひょろひょろの接続先です
スタイラスペンは人間の GND とスマホの電極を使って静電気を発生させタップしています
なので人間の手と同じ原理にするために GND をスタイラスペンの先端に接続する必要があります
この手法はタップをロボット化している方のほとんどが実践している手法のようです

またスタイラスペンは先っちょだけ外せるやつがたまたま手元にあったのでそれを使っています
固定は面倒だったので瞬間接着剤を使いました


あとはサーボモータの位置もポイントです
タップする際にふわっとしたタッチだと反応してくれません
結構しっかりタッチしないと反応してくれなかったので写真を見るとわかりますが調整してかなりスマホに近い位置にサーボモータを固定するようにしました
また画面の端っこすぎても反応してくれませんでした
なのでなるべくサーボモータをダンボールから前に突き出すことで画面の真ん中辺りをタップするようにしています

スイッチコントロールとは

iOS12 から使える機能なのですが特定のタップ、スワイプなどをレシピとして管理してワンタップするだけでそのレシピを実行してくれる機能です
https://support.apple.com/ja-jp/guide/iphone/iph400b2f114/ios

これを使うことでビンゴのスタートボタンを一定のタイミングで押すレシピを事前に作成しておき、あとは画面のどこをタップしてもいいようにサーボモータを制御しています

スイッチコントロールと組み合わせるメリットはロボット側が画面のどこをタップしても良いという点です
例えばロボットに「初めにここをタップして次にここをタップして」みたいな感じで全部やらせることもできるのですがそれだと回路も複雑になるしロボットのアームとして制御するサーボモータの数も膨大になってしまうので大変です
なのでスイッチコントロールと組み合わせることで簡単に複雑な画面タップを実現することができるのです

ただスイッチコントロールにもデメリットはあり「5 タップ、10 秒」までしかやってくれません
なので 10 とか 20 ある操作をスイッチコントロールにやらせることはできません

応用したい

今回作ったのは単純に自動タップマシンなので他にも何か使えないかなと思っています
スマホだけじゃなくて実は物理的なスイッチを押したりできるようになると更に便利かなと思っています
あとはモータの始動をスライドスイッチだけじゃなくてスマホからも制御できるようにするとか、、さすがにやりすぎかな

サーボモータ自体かなり簡単に制御できるアクチュエータなので 2, 3 個であれば複数組み合わせても良いかなと思っています
ただサーボモータを固定するのが大変で今回は手元にあった適当なダンボールを使いましたが本当であればプラスチックや木材、ステンレスなどでしっかり固定するべきかなと思っています
そうなってくると今度は単純な工作技術が必要になってくるのでそれはそれで大変になってくるかなと思います

今後

ちゃんとユニバーサル基板にはんだ付けしようかなと思います
あとは土台作りをちゃんとしてみたいです
というかこうなってくると電子工作というよりかは土台作成がしっかりしてこないとダメだなと思いました
実はロボティクスの世界はフレームとかそういうのを作成するほうが大変なんじゃないかな

2020年1月18日土曜日

スマホ版クロノトリガープレイメモ

年末年始にセールをしていので購入してプレイしてみました
感想とか攻略ネタの備忘録です

価格

2019/01/04 610 円でセール中に購入

Good

  • オート戦闘は便利 (さすがに倍速戦闘はない、またデフォルトをオート戦闘にすることもできなさそう)
  • コマンドの記憶も便利
    • レベル上げなどをタップだけで可能
  • アプリが強制キルされた場合は自動セーブで再開から開始可能
  • 装備画面やアイテム画面の操作はスマホに最適化されていると感じた
    • ただ 2 回タップで決定など実感慣れないと操作しにくい部分もあった
  • 強くてニューゲームもちゃんとある
    • エンディング終了後にセーブできるので途中でアプリを終了しないほうが良いと思われる
  • アニメーションが入る箇所がある
    • エイラの登場シーンなど

Bad

  • 倍速戦闘がほしかった (戦闘のメッセージと速度は変えられる)
    • イベントのスキップもない
    • アニメーションの Skip はある
  • ソフトウェアコントローラの操作性が微妙なところがある
    • 慣れるまでには時間がかかりそう
    • 宝箱が取りづらい、階段の登りづらい、穴に落ちてはいけないところが辛い
  • メニューで指定したキャラの技がいきなり使えない
    • マールで回復させたいのに「技」を選択してマールにしてからじゃないとオーラが使えないという感じ
    • 装備も同様で「装備」を選択してから装備させたいキャラに移動しなければいけない
  • ランドスケープでしかできないので faceID で解除する際に一度縦にしないといけない
    • またスマホを支えるための小指が痛くなる
    • また間違ってスクリーンショットを撮影してしまうことが多々あった

追加コンテンツ

SFC 版にない追加シナリオがあります
基本的には DS 版と同じようです

  • 竜の聖域
    • 1 週目から行ける追加コンテンツ
    • サブクエを進めていく感じ、クリアすると報酬がもらえる
    • 行ったり来たりを繰り返す感じので一回クリアすれば OK という感じ
    • エレメンタルガードも 1 つで十分
  • 次元のゆがみ
    • 1 度クリアしてから行ける追加コンテンツ
    • 宝箱に強力な武器があるのでそれだけ忘れないように
  • 時の闇
    • 次元のゆがみをクリアしてから行ける追加コンテンツ
    • 夢喰いを倒して終わり、夢幻を入手できる
    • 一応これがラスボス

以下夢喰いを倒したときのステータスです
ピンチになったらラストエリクサーを使っておけばまず負けないと思います

1 週目で最後まで行きましたが道中レベル上げなどしなくても勝手にこれくらいの強さにはなるようです
だいたい 20 時間前後でクリアできそうです

攻略メモ

  • かりの森ではコマンド固定にしてクロノの回転斬りをタップで連発していれば OK
    • ヌーはできれば程度で OK
  • 魔法 or 全体攻撃が有効
    • 魔法しか効かない敵や物理しか効かない敵がいるため
    • シルバー or ゴールドピアスがあればさらにサクサク進める
    • 戦闘の効率という意味では序盤に「バーサクリング」をかなり使った
    • 後半はヘイストメットでゴリゴリいける
  • 封印の宝箱を開ける順番に注意
    • 中世調べる -> 現世あける -> 中世あける
    • プレート 4 つと北の廃墟
  • 忘れちゃいけないいろじかけ
    • ドクロイ (古代) -> レインボーメット
    • ドクロイ青 (古代) -> マーメイドメット
    • プチラヴォスR (口) ヘイストメット
    • プチラヴォスR (殻) プロテクトメット
    • プチアーリマン ゴールドピアス
    • ジール (左手) プリズムドレス
    • ジール (右手) プリズムメット
  • ラヴォスは右が本体
  • 2 週目以降の目的
    • 各種カプセル回収
    • プリズムドレスとプリズムメットとにじのめがね
    • 月光の鎧
    • ヘイストメットとプロテクトメット
    • 天使のティアラ
  • おすすめ装備 (男子) 追加コンテンツクリア前
    • それぞれの最強武器+「ヘイストメット」+「ノヴァアーマー」
    • それぞれの最強武器+「プリズムメット」+「月光の鎧」
  • おすすめ装備 (男子) 追加コンテンツクリア後
    • それぞれの最強武器+「マスタークラウン」+「ロイヤルプレート」
  • おすすめ装備 (女子)
    • それぞれの最強武器+「プリズムメット」+「プリズムドレス」
  • おすすめアクセサリ
    • 「虹のメガネ」「激怒の腕輪」「ゴールドピアス」
    • あとは各キャラ専用のアクセサリー「ブレイブソウル」「英雄のバッジ」
  • レベル上げはジェノサイドドームのベルトコンベアー or 次元のゆがみ (古代) の青い敵2体
    • クロノ or 魔法のサンダガ連打で OK
    • 1200 以上ダメージを与えれば OK
    • ダメージが届かない場合は虹のメガネを装着する、ダメージが足りる場合はゴールドピアスで MP の消費を抑える
    • バリア/プロテクトボールが入手できるので金策にもなる
    • ただジェノサイドドームはロボ固定になるのでロボがレベル MAX になりそうになったら次元のゆがみを使う
    • ブリザビーストx2 は 4000 以上のダメージが出せれば一撃で倒せる
    • 虹のピアス+フレア or シャイニング辺りでないと厳しい

まとめ

神ゲーではあるのでスマホ版でもストレスなくプレイできると思います
あとはレベル 99 にしたりステータスをカプセルでカンストさせる感じかなと思います

2020年1月5日日曜日

リーダブルコード備忘録

リーダブルコードを読んだので所感などを備忘録として残しておきます
翻訳版は Kindle 用の電子書籍がないようです

最初に

サンプルコードがいろいろ出るが JavaScript や Python など比較的高級言語で記載されているので読みやすい
C++ なども一部ある
そしてそれらが実際にリファクタリングされるプロセスが記載されているのでプロセスを理解することが重要だと感じた

過去に達人プログラマーを読んだがそれと同じようなことを言及している部分は多く存在したと思う

大事そうなことメモ

  • 変数名はわかりやすく、スコープに応じて決める
  • コードだけ見てわかる場合はコメントは不要、最初はコメントを書くことを意識すると良い
  • ヨーダコード -> if 分の左辺に定数を記載して比較と代入演算子の記述バグを発見する方法
  • 気になったことをコメントに書いても OK、バグになりそうな箇所や計算量に課題がある箇所など
  • 関数名はそれを見ただけで何ができるのかわかるような名前が望ましい
  • 関数名はユーザが暗黙的に想定している命名規則を使う場合にそれに応じた計算量や値の取得ができるようにしなければならない
    • 例えば GetHoge はフィールドである hoge を返すだけの関数であったり size 関数は配列やハッシュの長さを返すだけの処理にする
    • DeleteHoge のような関数の名前で実は削除はしていないで空の値を設定するだけみたいな実装はよくない
  • 言語のコーディング規約がある場合はそれを使う、チーム内で決めても OK、とにかく一貫した書式を使うこと
  • 比較する場合は左辺に変化しずらい比較対象の値を設定し右辺にインクリメントしたりするような値を設定する
  • 否定の否定は使わない (if (!disable) 的な)
  • ド・モルガンの法則を覚えて比較式を簡単に変換できるようにしておく
  • guard 記法を積極的に使う
  • Don’t repeat yourself (DRY) の原則はリーダブルコードにも何回か出てきた
  • 汎用コード (util/) となる部分を素早く見つけすぐに切り出せるようにする
  • 長いタスクを短いタスクを列挙し関数やクラスなどに分割する
  • テストが見やすいコードは読みやすいコード
  • できる限り言語の標準パッケージを使う
  • まずはやってみる、試してみる、そしないと何も始まらない

これらを踏まえて疑問に思ったことや所感的なことを以下に記載します

golang や Swift はリーダブルコードで指摘されていることを言語レベルで吸収してくれる言語なのかもしれない

特にスタイルに関してだが、例えば「段落を使ったり複数行に分けて書く」とかは go fmt で自動でやってくれるのでコーディングしている側はそこまで気にしなくて済む
大文字小文字でスコープの範囲を指定できるのでその点も見た目だけで判断できる
ただ golang にはラベルを使った goto があり本書では goto を嫌っていたのですべてが理想な言語というわけでは当然ないと思う

Swift も同じような印象で例えば if let などは使用する変数のスコープを最小限にするための機能でそういった場合は自然に変数名が短くなると思う
Optional/Unwrap 型も見ただけで NULL の可能性が判断できる

コーディング規約などは IDE などでも統一できると思う

インデントや行間、1 行の最大文字数などは IDE を使って統一することもできると思った

IDE が嫌な場合は rubocop などのコード解析ツールを使っても良いと思う

やりすぎはダメというがやりすぎかどうかの判断が難しい

おそらく経験しかないと思う
あとは好みだろうか

テストについてもやりすぎは良くないと指摘している
個人的にはテストは嫌いなのでやりすぎるということはないと思う

リファクタリングやテストを優先してコードが増えないようにしたい

基本的にはリーダブルコードはコード量を減らすパターンが多いが状況によってはコード量が多くなるケースもあると思う
特にテストのためにリファクタリングしたりモックなどのコードが増える場合もあるので気をつけないとダメだと思う

使われていない通っていないロジックを評価する仕組みを入れておきたい

不要なコードがある場合は実装しない/削除したほうが良いと本書にもあるがそれを判断するための仕組みを入れておいたほうが良いと思う
基本的にはログで良いと思う
プロファイリングというかバグトレースなどのツールでも良いと思う

削除する基準はわからないが 1 年以上使われていないロジックなどは一生使われないイメージがある
でも初めから実装しないという手段を取れるのであればそれが一番だと思う

最終的には「好み」だと思う

変数の名前は関数の名前は特にそうだと思う
もちろん本書で指摘されているケースと全く同じケースだった場合には気付けると思うがそうでない場合がほとんどで、そういったケースはもうコーディングしている本人やレビュワーの好みに完全に左右されると思う
do-while は極力使わないという記載もあったが正直これも好みなので使っても全然良いと思う

リファクタリングやテストと同じできりがないとことだと思うのである一定のレベルでリーダブル化することやめないとダメだと思う

最後に

これを読んで実際にリーダブルなコードにリファクタリングしなければいけないケースに遭遇したときにすぐに実践できるレベルになっていなければダメだと思う
ただ、本書を読んですぐにそういう風な人になるということはなくやはり経験を積まないとダメだと思う
本書のパターンを記憶しておくのも有効な手段だとは思うがそれよりも実際の経験を積むほうが体にリーダブルなコードを書くクセがつくので良いと思う

2 回目以降に同じように読み直すのも良いがリファクタリングのサンプルコードだけを見直したり好きな章や気になる章を読み直すだけでも良いと思う