IT SURF CUP Judge System をリリースしました

iOS のネイティブアプリをリリースしました.

競技サーフィンの点数閲覧と採点が主な機能になります.
今回はこちらのアプリについて書いてみます.

経緯

@taiponrockさん経由で弊社の中村さんにご依頼いただきました.

中村さんはIT業界(特にベンダーやSIer)のサーフィン愛好者で作るサーフィン大会を主催されています.今回は第2回目開催に際し、アプリを利用できないかとご相談いただきました.

出来れば IBM Cloud を使いたいとのことだったので、IBM Cloud を用いた構成になっています.

 

クラウド・アーキテクチャ

使用したサービスは Cloud Foundry と Cloudant です.
無料のライト・アカウントで使えるサービスを選定しました.


Cloudant は NoSQL のサービスです.
ライト・アカウントには Db2 という RDB も用意されているのですが、Cloud Foundry のメモリが256MBに制限されているので、DB にコネクションを張るタイミングでメモリが足らず再起動ループに陥ってしまいました.
なので、コネクションを張る必要がない(Web API 化されている)Cloudant を選定しました.

 

フロントエンド

画面数は7枚、その中でも主な機能となる得点閲覧画面と採点画面は下記のようなデザインにしました。


デザインからフロントエンド開発合わせて、30時間ほどかかりました。iPhoneとiPadのマルチデバイス開発は初めてだったため、どのように開発していけば良いか検討つかず、苦労しました、

デザインで気をつけた点は得点画面では、パッとみて得点および順位がわかること。グラフは個人の採点を表示しています。

UIで使用したライブラリは下記になります。
Charts


XLPagerTabStrip

ライブラリは本当に便利です。思い描いていたデザインを簡単に表現することができました。

 

バックエンド

Spring Boot で実装しました.

例によって Cloudant SDK を使用しています.

ちょっと美しくない気がしますが、RDB の JOIN 処理をバックエンドアプリ側で行なっています.Cloudant で高級なクエリって書けないのかな…

Service の一例はこんな感じです.

@Service
@AllArgsConstructor
public class ScoreService {

    private IJudgeRepository judgeRepository;
    private ICompetitionRepository competitionRepository;

    public List getScores(int round, int heat) {

        val judges = judgeRepository.findJudgeByRoundHeat(round, heat);
        val competitions = competitionRepository.getCompetitionByRoundHeat(round,heat);

        val scores = competitions.stream()
                .map(new ScoreConverter(judges))
                .sorted(Comparator.comparing(ScoreResponse::getAggregate).reversed())
                .collect(Collectors.toList());

        int i[] = {1};
        scores.forEach(s -> {
            s.setRank(i[0]);
            i[0]++;
        });

        return scores.stream()
                .sorted(Comparator.comparing(ScoreResponse::getColorOrder))
                .collect(Collectors.toList());
    }
}

 

私は今回初めて知ったのですが、競技サーフィンって結構複雑な採点をしているのです.

3〜5人のパネルジャッジとヘッドジャッジでチーム編成して採点します。
パネルジャッジがヒート中すべてのライディングを採点しヘッドジャッジがまとめます。

ライディングの得点はパネルジャッジ(3〜5人)がつけたスコアの最高点と最低点をカットし、残りのスコアを平均して定められたライディング本数の上位2本の得点の合計点でヒート勝敗が決まります。

サーフィン競技の採点方法はどうなっているのか

この辺のサーフィンのルールを理解するのが一番苦労したかもしれません.
サーフィン奥が深い.

 

今後

任意のユーザーが使えるような汎用的なアプリに出来たらという希望があります(未定).

そのためには、バックエンドを Functions & RDB に改修したいです.常時稼働だと Cloud Foundry アプリだとコスパが悪いですし、データも RDB で扱った方が処理をシンプルにできそうです.
(RDB だとスケールしない問題は、まぁそんなにたくさんユーザーがいるタイプのアプリではないのでOKでしょう)

 

以上です.