SHOGIX

ブラウザで将棋の対局ができます

将棋が指せる WEB サービスを個人で開発しました

みなさんこんにちは、はじめまして、菊池です。

先日、関数型言語Googleクラウドサービスを使って作った【SHOGIX 無料で将棋の対局ができる WEB サービス 】を公開しました。完全に個人の趣味プロジェクトです。

WEB ブラウザがあれば将棋の対局ができるので、よかったら友達と将棋を指す時とかに使ってみてください!

今回は SHOGIX を構成する技術について、その概要を紹介してみようと思います。

f:id:shogixjp:20190621090455p:plain:w250

今後の SHOGIX には、棋力が同じぐらいのユーザー同士でマッチング対局できる機能や、将棋が強くなれる機能を少しづつ追加していく予定です。お楽しみに!

f:id:shogixjp:20190621084853p:plain:w250

shogix.jp

SHOGIX の構成

SHOGIXGoogle の各種クラウドサービスを使って、サーバーレスで構成しています。インフラの運用は全てクラウドサービス側にお任せでスケールアウトもしてくれるので、ロジックの開発に集中することができました。

構成図をクリックすると拡大表示します。

Firebase Hosting

Elm + TypeScript で作った SPA のフロントエンドコンテンツ配信に使っています。対局 URL では OGP を変更したかったので、直接対局 URL にアクセスした場合は、Cloud Functions で HTML を書き換えています。Firebase Hosting は単純な静的ファイルの配信だけでなく、URL パスによって Cloud Functions や Cloud Run へリクエストをプロキシできるんですよね。

Firebase Authentication

ユーザー登録やログイン処理、パスワード再発行など WEB サービスで必要な認証処理は Firebase Authentication を使っています。TwitterFacebook などの SNS 認証も簡単に実装することができますが、SHOGIX ではシンプルに E-Mail / Password 認証だけを使っています。

Cloud Functions for Firebase

フロントエンドのリクエストを受け付けて、Cloud Firestore に格納している対局データの新規作成や読み込、更新といった簡単な処理を Cloud Functions で実装しています。フロントエンドから直接 Cloud Firestore のデータを操作するように実装することもできますが、全て Cloud Functions から操作するようにしています。

Cloud Run

Cloud Functions から対局中の駒配置と駒移動データを受け取って、駒を移動した後の駒配置や、盤上の各駒が移動できるマス目のデータを返すサーバーを動かしています。ロジックの量が多いので Haskell と Servant でコンテナを実装しています。

当初は Cloud Run で直接フロントエンドのリクエストを受け取り、Cloud Firestore を REST API で操作するように Haskell で実装していました。しかしながら、Cloud Firestore の REST アクセス時に時々パフォーマンスが落ちる現象が発生したので、この構成に変更しています。想像ですが REST アクセスの処理でスペースリークしてたかも。

Cloud Firestore

対局データは全て Cloud Firestore に格納しています。Cloud Firestore にはクライアント側のデータをリアルタイムに更新する機能があります。Cloud Firestore に格納しているデータを変更すると、データを購読しているクライアントのデータもほぼリアルタイムで更新されます。このリアルタイムアップデート機能を使って、フロントエンドの駒を動かしています。Cloud Functions で更新した Cloud Firestore の対局データが、クライアント側に反映される動作を SHOGIX で体験してみてください。この機能のおかけで WebSocket サーバーを構築しなくて済みました。

データの流れ

SHOGIX を作るにあたって意識したのが、Cloud Firestore を操作するデータの流れを一方向にすることです。

  1. フロントエンドの SPA は Cloud Functions に駒移動リクエストを送信
  2. Cloud Functions は Cloud Firestore の対局データを更新
  3. Cloud Firestore は更新された対局データをフロントエンドに反映

将棋では盤面によって駒の移動を細かく制限する必要があります。この流れだと Cloud Firestore のルール設定を『外部読み取り許可』にするだけで済みました。

フロントエンドを Elm で書いていたので、ここにも Elm アーキテクチャが反映されたのかもしれません。



View フロントエンド SPA
Update Cloud Functions
Model Cloud Firestore

関数型言語

SHOGIX のメインロジックはそれぞれ、フロントエンドを Elm バックエンドを Haskell で書きました。これらの言語を採用したのは、個人的に関数型言語で何か作ってみたかったのと、静的型付けバリバリな言語の雰囲気を知りたかったのが動機です(それと、関数型言語がカッコ良さそうだからというミーハーな理由もなくもない笑)

関数型言語は慣れるにつれて、型に導かれて実装が進む感じが心地よくなってきます。コンパイラのエラーメッセージも支援してくれるので、いつのまにか大幅リファクタも捗りました。コンパイルが通ると実行時に落ちることはほとんど無いし、思っていた通りに動くので開発も楽になってくる印象です。

記述も簡潔で分かりやすく感じているので、今ではすっかり関数型言語のファンです。

この辺の体験記は改めて書くかもしれません。

最後に

作りたてほやほやの SHOGIX ですが、よかったら使ってみてください。感想や応援メッセージなどもらえると嬉しいです。こちらの問い合わせフォームからお気軽にどうぞ!

将棋を指したくなったら SHOGIX を使ってみてくださいね。

shogix.jp

菊池