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

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

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

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

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

shogix.jp

SHOGIX の構成

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

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

Firebase Hosting

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

Firebase Authentication

ユーザー登録やログイン処理、パスワード再発行など WEB サービスで必要な認証処理は Firebase Authentication を使っています。Twitter や Facebook などの 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 を操作するデータの流れを一方向にすることです。

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

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

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





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

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

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

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

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

最後に

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

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

shogix.jp

菊池