ポケモンのタイプ相性チェッカー作った

急にポケモンの話をします。最近、熱心にポケモンの対戦動画を見ていて、自分でも昨年11月に発売されたポケモン ウルトラサンムーンで対戦用ポケモンの厳選環境を作ってしまった。

ポケモンは対戦においてはタイプがとても大事なのだけど、タイプ同士の強弱関係を覚えるのが意外と大変。タイプは18種類ありすべての組み合わせに相性が設定されている(公式のタイプ相性表)。タイプ相性には方向があり、対象性はあったりなかったりするので、基本的には全組み合わせ覚えるしかない。また、2つのタイプをもつポケモンもいるので、複数のタイプ相性関係をかけ合わせて考える必要もある。

たぶん全部覚える必要はなくて、頻出の組み合わせを覚えば、なんとかなると思うのだけど、慣れるまでは大変。タイプ相性表を印刷なりして都度確認しつつ覚えていくのが良さそうだったけど、ちょうど良さそうな課題だったので自分でタイプチェッカーを作って見ることにした。

できたもの

こういう感じのWebアプリケーションを作った。

f:id:hakobe932:20180108120310p:plain:w320
選択したタイプでぼうぎょするか、こうげきするかを選んでおき、上部のボタンを押してタイプを選択する。そうすると下の方に、タイプ相性の計算結果が一覧になって表示される。

スクリーンショットの例では、ゴーストとフェアリーの2つのタイプを持ったポケモン(=ミミッキュ) に対して、どんなタイプのわざが効果があるのかがあるのかがわかるようになっている。ミミッキュはこうかはばつぐんになる技のタイプが少なくて優秀ですね、という感じ。

https://douzemille.net/poketype/ にデプロイしてあるのでどうぞご利用ください。

実装

ポケモンタイプ相性チェッカーのコアドメインはタイプ相性関係である。そこで、まず、その部分を抽象化したnpmモジュールを実装した。

github.com

ここは一番大事なので、Flowで型アノテーションをほどこしてある。全組み合わせのテストはできそうにもないので、代表的な部分だけテストも書いてある。実装で一番大変だったというかだるかったのはこのへん

このモジュールを使うと特定のタイプを持ったポケモンに対して、特定のタイプの技のこうげきを行ったときの効果を得ることができる。だいたい以下のようなイメージ。

import poketype from 'pokemon-type'

const { ほのお, くさ } = poketype.Types

const フシギダネ = poketype.createPokemon(くさ)
const ひのこ = ほのお
const effectiveness = poketype.calcEffectiveness(ひのこ, フシギダネ)

console.log(effectiveness.message) // 'こうかは ばつぐんだ!'

まだ、npm publish してないけどそのうちしたい。インターフェースに日本語使っているのだけはやめたほうが良いかもと思っている。すでに、flow gen-flow-filesすると日本語の型定義の部分が8進数のunicode表記に変換された結果、use strictされたJSの処理系で評価できなくなるという問題に遭遇している。

そして、このpokemon-typesモジュールを利用して、今回のWebアプリケーションを実装した。

github.com

このWebアプリケーションはフロントエンドだけで完結していて、ペラ1のHTMLとJavaScriptで構成されている。見よう見まねで現代的な感じのするReactアプリとして実装した。状態の管理にはRedux、コードのbundleを作るのには、webpackを使っている。

コアの部分はちゃんと実装できているという前提でこちらのコードはわりと殴り書きしている。実装がすべてindex.jsに書かれていたりしてひどいがまぁ動く。デザインセンスはないものの18種類の色のボタンを並べるとカラフルで華やかにはなった。

感想

できたものは、まぁ普通に便利という感じになった。UIの操作感のこなれなさはあるものの、とっさにぱぱっとタイプ相性を調べられる。

ただ、対戦相手のポケモンが登場したときに、そもそもそのポケモンのタイプを覚えていないことが多く、結局ググって調べることも多い。また、ポケモンにはタイプ以外にもいろんなパラメータがあるので、タイプ相性だけ知っていてもどうしようもなく総合的な情報がどうしても必要になる。そこまでくるとデータベースサイトを運用するみたいな世界になってくるが、そういうサイトはすでに存在するので自分でやるメリットはそんなになさそう。

まぁタイプ相性表を実装するのは世の中に何人もいなくて良いはずなので、公開しておくと誰かにとっては便利になるかもしれない。

自分のプロダクトでフロントエンドのJavaScriptを書くのはひさびさだったので、技術的な感想も羅列しておく

  • VSCode でFlowのコードは書けるけど、VSCode自体はTypeScript推しなので時々TypeScriptっぽい型の解釈をしはじめたりする。設定でjavascript.validate.enableをfalseにしておくと良い
  • eslint --fix + prettier で完全なる心の安心が得られる
  • 日本語の識別子使うとテンションは上がるけど、動かないツールに遭遇する心配は増える(そして実際遭遇した)
  • webpackは普通に良くできていてコレでいいじゃんという感じ。gulpよりも実際のユースケースに合わせてもうちょっとモデリングされている
  • SASSでMap型の値をループするのは便利。ポケモンのタイプの数だけCSS書かずに済んだ
  • eslintとbabelとflowとwebpackの設定をすべてやらないと開発が開始できないのは大変。一つのプロジェクトで設定を作ったらその後は使いまわせるので楽。ポケモンの厳選と同じやな!
    • create-react-app には途中で気づいた

追記 (2017-01-09)

motemenさんによる先行研究があった

motemen.hatenablog.com

タイプ相性表を入力しているひとがここにもいた。その部分だけでも拝借すれば良かった...!

micro:bitを買うてきた

あけましておめでとうございます。今年もよろしくお願いします!

それはさておき、micro:bitを購入してしまったので、年末年始のひまつぶしによかろうと、雑なプログラムを幾つか作ってみた。

micro:bit is 何

micro:bitはイギリスのBBCが作っている教育用のマイコンボード。イギリスでは子どもたちに無料で配っているらしい。25個のLEDと2つの入力用ボタン、温度センサーやジャイロセンサー、BLEの通信コンポーネントなどが一つのボードにパッケージングされていて、部品を組み立てたり配線しなくてもいろんなことができる。ともかくオフィシャルサイトの紹介 を見るとわかりやすい。ボードの見た目がかわいい。

開発は本格的なプログラミング言語も使えるが、Web上で動作するScratchみたいなブロックスタイルの開発環境も良くできている(なんかMicrosoftが作ってるみたい)。

サイコロ

ボード自体を振ると加速度センサが反応するので、それをトリガーにサイコロを振ってくれるプログラム。ちょっとしたエフェクトが表示されたあと、1~6の数字がランダムで1つ出力される。

firmwareのコードは以下のような感じで素朴。ご覧のとおり開発環境にはシミュレータもついてたりして試行錯誤しやすい。

Twitterの特定キーワードを監視してLEDで通知してくれるくん

Twitterのfiltered realtime apiを使うと適当なキーワードを含むツイートをストリームで受け取ることができる。これを使って、Twitter上で特定のキーワードをつぶやいている人がいることを検知し、それに合わせて micro:bitのLEDを点滅させることで、すぐさま話題に気づけるというプログラム。

キーワードに反応したら以下のような感じで光る。

micro:bit には無線LANインターフェースとかはついていないので直接インターネットに接続することはできない。一方、Bluetooth LEのインターフェースはあるので、他のコンピュータと通信することはできる。今回は母艦のMacでTwitterのストリームを見ておいてイベントが起こったら、BLEでLEDを光らせる命令をmicro:bitに送るようにした。

micro:bit側で動作させるfirmwareのコードはめちゃくちゃしょぼくて、以下のとおり。コードには現れていないが、右上の歯車からたどり着ける"プロジェクトの設定"で、"No Pairing Required: Anyone can connect via Bluetooth." しておくと良い。

母艦のMac側のコードはNode.jsで実装する。BLEでmicro:bitを接続するための便利なnpmモジュールがあるのでそれを使うと良い。

github.com

罠があって、このモジュールが依存しているnobleというモジュールが Mac OS High Sierraでは使えない。ありがたいことに、パッチを書いてくれている人がいるので、それを使おう。

とにかくnode-bbc-microbitを使うといい感じに、micro:bitと通信できるようになる。今回の仕組みを実現するために自分で書いたソースコードは以下のリポジトリにあるので見てくれ!

github.com

たいしたことはしてないけど、チカチカ点滅させる部分をasync/await使って書いているのがいい感じに書けたポイント(コールバックとかPromiseでやるとダルそう)。

for (let i = 0; i < 5; i++) {
  await writeLedMatrixState(microbit, PatternSmile);
  await sleep(100);
  await writeLedMatrixState(microbit, PatternBlank);
  await sleep(50);
}

ちょっと使ってみたところ、"紅白" みたいなキーワードだと無限にチカチカしていて意味がなかった。"ポケモン配布"みたいな微妙にニッチ感のあるキーワードだと程よい間隔で反応がある。普段は "はこべ" とかで検索しておくと良いか。

Twitterのキーワード監視だと微妙に使いでがないけど、要はイベントにトリガしてLEDが制御できるということなので、ログをtailしてERRORって文字列があったら光らせるとか、Googleカレンダーの予定の10分前から光らせておくとかできそう。

感想

振ったらデバイスが反応したり、LEDが光ったりするのは楽しい。1ボードで完結して動くので物理的な安定感があって扱いやすい感じがする。開発環境はとてもよくできてて使いやすい。電子工作のキットもいろいろあるので、ボード単体で飽きても拡張していけそう。

BLEで制御できるのが便利。いろいろ活用の仕方がありそうで、そのへんにあるRaspberry Piに母艦をやらせて、micro:bitをセンサ付きビーコンとして家とかオフィスにばらまくとかするとおもしろい?

年末年始のひまつぶしにはちょうど良いので、近所の電子部品店になどで購入しましょう。京都のマルツにはまだもうちょっとありました。電池ボックスが地味に便利なのでスターターキットがおすすめです。

micro:bitではじめるプログラミング ―親子で学べるプログラミングとエレクトロニクス (Make:PROJECTS)

micro:bitではじめるプログラミング ―親子で学べるプログラミングとエレクトロニクス (Make:PROJECTS)

  • 作者: スイッチエデュケーション編集部
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2017/11/25
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

Real World HTTP を読んだ

そんむーさんもおすすめの Real World HTTP を読んだ。たまには現代的なHTTP周辺の技術をおさらいして安心したいという気持ちで読み始めた。

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

著者の紹介 にもあるように、Web API: The Good Partsハイパフォーマンスブラウザネットワーキングの間を補完する内容で、HTTPとその周辺技術をかなり網羅的に紹介してくれている。

自分がWebアプリケーションを書き始めたころは、例えばフォームをsubmitした時のrequest bodyには実際にどういうデータが入っているのかとか、基本的なことが学ぼうとすると意外と情報源がなかった気がする(結局LWPの実装読んだりしてた思い出)。この本は、そういったHTTPの基本的なことも歴史を辿りながら丁寧に紹介していってくれる。

最近の新しいHTTP関連技術についても網羅的にとりあげられている。現代的な技術をおさらいしたかった自分にはちょうど良くて、あまり良く知らない部分を認識できた。HTTPライブストリーミングとかよく知らなかった。

ところどころGoでHTTPの機能を実装してみてみるコーナーも、実装を見ることで具体的な技術のイメージができてよかった。HTTPのプロトコルUpgradeなんかは実装をみるまでいまいちイメージできなかったので、とてもためになった。

最近のHTTP関連技術の見取り図がほしいという人にはぴったりという感じの本だった。個々の技術についてはさらっとした紹介になっているところがあるものの、参考資料への参照がしっかりしているのでこの本からスタートして学ぶことはできそうである。HTTPの基本を学ぼうとしているひとにもおすすめできる。そうでなくても普段からWebアプリケーションを書くときに辞書的にそばに置いておくと良さそう。

Amazon Web Service 基礎からのネットワーク&サーバー構築 を読んだ

一応仕事でAWSは使っているのだけど、必要に応じて調べては勘で使っていて、もうちょっと体系的に学ぼうと思い、評判の良さそうなこの本を読んでみた。あと re:Invent が盛り上がっていたし...。

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

この本は今年改定されたところで、管理画面のスクリーンショットが更新されていたり、改定前にはなかったVPCに付属のNATゲートウェイの機能を使うようになったりしていて最新の内容に追従している。

最近のAWSはサービスがめちゃくちゃ増えていて100くらいあり、勉強するにもどこから手を付けたら良いのか途方にくれていた。この本ではいきなりすべてを学ぶのではなく、AWSの基礎的なコンポーネントに絞り込んで学べる構成になっていて、取っ掛かりにはとても良かった。逆にAWSのいろんなマネージドサービスをそれぞれ詳しく知りたいという人のための本ではない。サービスとしては EC2とVPC くらいしか登場しない(VPCの中にいろんなコンポーネントが含まれてはいるけど)。

実現したいネットワークの構成や、途中経過が図示されているので、あんまり脳内スタックを使わずにストレス読める。よくあるネットワークの構成とそれをAWSでどう実現するかの対応も、章ごとにとりあげられていることでわかりやすかった。

自分はVPCがすでにきっちり設定されている環境でしかAWSをさわったことがなかったので、VPCの設定をぽちぽち自分で手を動かしてやることで、何をやっているのかのイメージが付いたのは良かった。TCP/IP などネットワーク知識についても要点が抑えられているので、初学者向けにも良さそう。

分量もコンパクトにまとまってるのですぐに読み終えられるうえに、基礎が抑えられるし、今はKindle版が半額っぽいのでお得です。

Visual Studio Code で編集中のテストコードを実行する

TL;DR

Visual Studio Codeではエディタからのコマンド実行がTasksという仕組みでできてとても便利。

背景

最近エディタをVisual Studio Codeに変えた。エディタのこだわりはそんなになくて、Vim → Emacs → Atom といった順番で2年に一度くらい乗り換えている。だいたいどのエディタにもVimキーバーインドエクステンションがあるのでなんとかなる。

Visual Studio CodeはAtomと同じElectronベースだけど、なぜかAtomよりサクサク動くので気に入っている。Microsoftのリソースパワーに感謝するしかない。

テストの話に移ると、テストを書くのはもちろんソフトウェア品質の担保やリグレッションの防止が目的だけれども、TDD的な文脈では開発のリズムを作るのも目的の一つだ。リズムよくテスト実行しつつ開発するには、エディタで開いているテストをさくさく実行できるのが重要になる。いちいちテストのためにターミナルにもどったりしてまごつきたくない。

仕事でPerlを書いている自分は、がんばってエディタからPerlのテストを実行できるようにしている。EmacsVimでも設定してたし、Atomでも拡張書いたりしていた(参考:
AtomからPerlのテストを直接実行するくん)。

Visual Studio Codeに乗り換えるにあたっても、エディタからテスト実行できるのかが重要なポイントだったのだけど、ちょっと調べたら実現することができた。他のエディタに比べて簡単で、ちょっとうれしくなったので紹介してみる。Perlのテストを実行するという話題だけど、エディタからコマンド実行したいならなんでも適用できる。

やりたいこと

  • エディタで編集中のテストコードをエディタの画面内で直接実行して結果を確かめたい
  • Perlでよく使うTest::Class形式のテストの場合、個別のテストメソッドだけを実行する機能がある。その機能を利用して、エディタ内のカーソル場所付近に書いてあるテストのみを実行したい

できたもの

コマンドパレットから "タスク: テスト タスクの実行" を選んで、自分で定義した"run Perl test here" を実行すれば、カーソルのある場所のテストが実行される。以下のスクリーンキャプチャの例ではmultiplyという名前のテストだけを実行してる。

f:id:hakobe932:20171109223909g:plain

やりかた

標準機能として用意されているTasksを使えばできる。カスタムタスクを自分で定義すれば、任意のコマンドをエディタから直接実行できる。

tasks.json

プロジェクトのディレクトリ直下に .vscodeというディレクトリを作成し、その中にtasks.jsonという設定ファイルを作成する。開いているPerlのテストファイルを実行するのでよければ以下のように書く。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "run Perl test all",
            "type": "shell",
            "command": "carton exec -- prove -v ${relativeFile}",
            "group": "test",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            }
        }
    ]
}

各項目の意味はドキュメントを参照していただくのが良い。

大事なのはcommandで設定されている内容で、文字通りここに実行したいコマンドを書く。設定内ではいくつか変数が使えて $relativeFile は現在エディタで開いているファイルのプロジェクト内の相対パスが入っている。変数の一覧を見れば使える変数がわかる。

この段階では、開いているテストファイル全体を実行することはできるけど、特定のテストのみを選択して実行することはできないので、工夫をする。

カーソル位置になるテストを実行するためのwrapperスクリプト

ここは少しPerlの事情になるのだけど、PerlのTest::Class形式のテストでは、メソッドごとにテストを書くようになっており、以下のように環境変数を設定することでテスト全体ではなく、特定のテストメソッドのみを実行することができる。

# multiply という名前のテストのみを実行する
$ TEST_METHOD=multiply cartone exec -- prove -v t/Calc.t 

エディタから特定のテストメソッドのみを実行したい場合、エディタのカーソル付近のテストメソッドの名前を取得し、上記の様なコマンドを実行できれば良いということになる。

tasks.jsonの定義ではあまり複雑なことはできないので、wrapperスクリプトを用いて実現する。つまり、tasks.jsonはからは以下のようなコマンドを呼び出すことにし

carton exec -- \
  perl .vscode/exec/run_test_at.pl ${relativeFile} ${lineNumber}

このコマンドの中で、${relativeFile}から得られるファイル名と${lineNumber}から得られるエディタのカーソル位置の行番号をもとに、実行すべきテストメソッド名を見つける。その後、見つけたテストメソッド名を用いてテストを実行する。

wrapperスクリプトは、こういう感じの実装になる。泥臭い感じだけど、特別遅かったりすることもないしちゃんと動く。

Perlにかぎらず同様のテクニックを使えば、カーソル位置の情報を使ってコマンドの実行ができる。

最終的な形

こういう感じ になる。以下のリポジトリに、設定例をまとめてあるので参考にされたい。

github.com

さらなる工夫

Taskはメニューから選ばなくても直接キーボードショートカットに登録できる

.vscode/tasks.json はプロジェクトディレクトリ内に設定するので、リポジトリにコミットして共有してしまえばチーム内で設定を共有できて便利。

これはまだ自分でもやっていないのだけれども、Probrem matcherという仕組みがあって、コマンドの出力結果から問題箇所をエディタ上でハイライトできるような仕組みがある。これを利用すれば、テストが落ちたときに落ちた箇所をハイライトできてかっこいいはず。

感想

Atomで同じことをしようとしたときは拡張を書いたりする必要があってたいへんだったけど、標準機能で達成できたのは手軽でよかった。Visual Studio Codeはターミナルが内蔵されていて、こういうサポートが発展しやすいのだと思う。

Visual Studio Code は TypeScript を書いている人に人気という印象だけど、普通に開発環境としても良くできているし、なぜかさくさく動いていいので、試してみると意外と気にいるかもしれずオススメです。

Java SE 8 実践プログラミングを読んだ

Java9がリリースされた昨今、今更だけど、Kindleで安くなってたので読んだ。

Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング

Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング

Java SE8 for the Really Impatientの翻訳本で、Java 8からの新機能であるラムダ式をはじめ、ストリームAPIや新しい日付クラスなどについて詳しく紹介されている。

新機能の紹介おいては、単に記法やライブラリの紹介をしてくれるだけでなく、言語の設計の方針や過去のバージョンのJavaとの互換性などを踏まえた説明がなされていて読み応えがある。例えば、ラムダ式をJavaという言語で表現するために、汎用的な関数型はほとんど使われておらず、用途ごとに関数のように扱えるinterface(= FunctionalInterfaceで注釈される)が定義されていて、そのinterfaceに合致するようにラムダ式を与えるというふうになっている。この方法では既存のJavaのプログラミングの方法を変えずに新しくラムダ式を採用できる……といった内容。

新機能の紹介以外では、9.4章 セキュリティ案件でコラム的に語られている、Java アプレットやJava Web Start がなぜうまくいかなかったかについて著者があれこれ分析しているところが興味深かった。Write once, run anywhereなんてなかったんや……。

あと、この本の特徴としては、章ごとにある練習問題がやたら充実しているというのがある。本に書かれている範囲を超えて自分で考えなければ解けないような難易度で、良い練習になる。僕も1章と2章の練習問題をためしに解いてみた。

github.com

一応問題ごとにテストを書いて動きを確かめられるようにしている。回答のコードはこういう調子。コードを書かないような問もあるので、抜けている番号もある。

3章以降の問題も気が向いたらやりたいけど、JavaFXに依存してる問題があったりしてなんかちょっとテストしずらいなーとなってあんまり気がすすまない。この練習問題は全体的には良い問題が揃ってるんだけど、仕様がはっきりしなかったり、妙に込み入ったことをする必要があったりする。やりやすい問題だけやるくらいでも良いと思う。

結構この練習問題にチャレンジしている人もいて、"Java SE 8 実践プログラミング 練習問題" とかで検索するといくつか見つかって、眺めると面白い。原著のタイトルで検索してもいくつか見つかる。

総じてJava 8の新機能をしっかり学べるし、特にJavaプログラミングの題材がなくても練習問題とかやって楽しめるので良い本だと思う。コレで僕も、「ラムダ式くらいかけますしね!」って言ってもよいはず。あとJava FXの章は読んでないです。すいません。

研究もJavaでやったし、2,3年前はAndroidアプリ書いてたりもしてたので、基本的なJavaは一応書けるというつもりだったけど、だいたい忘れているということもわかった。

ざっとわかるPythonの紹介

普段Perlを書いている自分がざっくりPythonについて調べて発表した時の資料が手元に転がっていたので、せっかくなので公開した。

普段、別の言語でWeb開発している人が、自分の言語のアレはPythonだとコレなのねって雰囲気わかるようになっているといいなと思って作ったけど、見返すとそうでもない気がする。

自分もPython初心者なので、「おいおいまったくまちがっているぜ! 」といったことがあったら教えてほしいです。京都に住んでいるのだけど、関西のPythonコミュニティの雰囲気もよく知らないので情報募集です。

あと資料で紹介しているブログのコードは以下においてある。自分がよくやる感じの薄い設計でかんたんなブログシステムをPythonで書いたらこんな感じかな~ってコードになっている。

github.com