社内の忘年会の余興に使う『謎解き Web アプリ～天使 vs 悪魔～』を開発した（アプリ紹介・クライアント編）

# 概要
この記事は [NSSOL Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nssol) の 13 日目の記事です。
会社のアドベントカレンダーに参加しているので、看板を背負っていることになりますが、
いつも通り自由に書こうと思います。

## 何をしたの〜？
NSSOL の[システム研究開発センター](https://www.nssol.nipponsteel.com/value/technology_01.html)配属の新入社員 3 人で、 Web アプリを開発しました。
仲の良い 3 人が休日に趣味で勝手に開発した、という理解でお願いいたします。（本当にそうです。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387790/77fcff4c-44c8-89dd-0ba0-767f17d352e6.png)

こんな感じです。

Bootstrap でフロント作って〜、
Flask でバックエンド作って〜、
EC2 でサーバたてて……

と、やったことが盛りだくさんでした。

今となっては、「技術的に難しいことはしていない」と振り返れてしまうのですが、
2 ヶ月間、予想以上に苦労したので、温かい目で記事を読んでいただけたら幸いです。

## どんな記事なの～？
本アプリに関する記事は、全 3 編になる予定です。
アプリのほうがペラペラなので、Qiita の記事は引き伸ばし商法を使っていきます。

①　アプリ紹介・クライアント編　（本記事）
②　[サーバサイド編](https://qiita.com/thtitech/items/85f489e485135e578914)
③　裏話・開発手法編

また、私たち 3 人が理解した技術要素は以下の通りです。

- CSS、Bootstrap、完全に理解した。
- Flask、完全に理解した。
- AWS、EC2、完全に理解した。
- アジャイル開発、完全に理解した。

何も目新しい技術を使っていないというのに、本っっっっっっっ当に時間がかかりました。
お恥ずかしい限りです。ﾟ(ﾟ´ω`ﾟ)ﾟ｡ﾋﾟｰ

## ※アプリの公開について
このアプリは新人の自己紹介などを含めて作成しています。
そのため、プライバシーに関わる情報が内容に含まれており、
現段階では、公開できない状態です。
今後、そのような内容を変更して公開することがあるかもしれません。
（現在 AWS の EC2 を借りているため、金銭的な意味でも少し難しいと思います）

# アプリ紹介
開発したアプリについて説明を行います。
本アプリは、**全 4 問 +α から成る『謎解き Web アプリ』です。**
プレイ時間は約 20 分を想定しています。
ブラウザで見ることが出来ます。 Chrome と Safari で動作確認を行っています。
faviconもいらすとやさんの画像を使って、作りました。

![favicon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387790/df6d1848-e6e8-e294-03d2-714fb3fe02c4.png)


レスポンシブデザインのフレームワークを使っているのに、スマホ推奨です。
Bootstrap を勉強する時間と、各サイズに対応する時間がありませんでした。すみません。

## 着想、前提条件
まず、今回のアプリ開発を行う上で、必要な要件と、達成したい条件がいくつかありました。

- 会社の忘年会の 30 分間を使って、出し物を行う。
- 余興では何かしらの順位をつけ、景品を渡す。
- 最大 150 人程度の人間が、同時に参加する。
- 新人に興味を持ってもらえるような要素があると嬉しい。
- 技術的な要素を見せられると嬉しい。ので新人がアプリ開発をする年も多い。

「景品を渡す」という条件が難しく、少なくとも何かしらの順位がつくものでなければなりません。
また、忘年会というお楽しみの場で、しっかり考えないと解けないものを作っても興ざめでしょう。
という感じで、いくつかの制約のもと、どんなアプリを作るか考えました。

結局、「**どうせ作るなら開発者が作りたいものを作ろう**」と考え、
 3 人の中に謎解き大好きマンが 2 人居たため、今回の謎解きアプリの開発に至りました。

- 導入と結果発表などを除いた、 20 分以内で解ける謎解きを作る。
- お酒の場なので「知らないと解けない」「アクロバティックなことをしない」。
- 故に、解ける問題を始めに置きつつ、最後は順位に差が生まれる問題を作る。
- スマホでやりたいので、iPhone と Android どちらでも出来るように、Web ページで作成する。
- そこそこいいサーバーを借りる。

のような、アプリになっています。
また、配布するしおりに新人の自己紹介に謎の答えを含めて、参照させるということもしています。

## シナリオ
どうせなら謎解きにシナリオも含めると理想よね、みたいな欲張りな心が生まれてしまい、
シナリオにそって謎解きを行うアプリを開発することにしました。
（というのは建前で、勝手にシナリオを書いた人間がいたので含めました）

ただ、長い文章を読ませて、理解に時間がかかるような難解なシナリオがあっても仕方ないので、

- **「心の中の天使 vs 心の中の悪魔」** ～誰もが一度は見たことがあるはず～
- **「SIer」** ～愛社精神の塊～

を合わせて、キャッチーなものを作ろうと心がけました。
（結局、シナリオが無くても成立するような内容になりましたｗ）

というわけで、
**「悪魔に心をやられてしまった新人が、自社システムを炎上させるけど、
　天使が残してくれたヒントを手がかりに、他人が鎮火する」**
という、謎のシナリオが生まれました。

謎解きは、天使のヒントが画面上部に常に表示され、
「プレイヤーが次に何をすればよいか」が、そのヒントを読めば理解できるようにしています。
なっているはずです！　なっていなけりゃ、ごめんなさい。


# アプリ外観
本章では、本アプリのデザインとページ構成について、クライアント的な観点のみから説明します。

## 画面遷移
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387790/d68fab04-bb47-568f-7e36-e0788e3c8cdc.png)

こんな感じです。想定された遷移順としては、

①　導入ページ
②　page1 で、問題 1 と問題 2 を考えて 1 つの答えを入力
③　page2 で、問題 3 と問題 4 を考えて 1 つの答えを入力
④　page1 で、別の答えを入力
⑤　page2 で、問題 3 と問題 4 と同じ答えを入力
⑥　ゴール

となっています。
Cookie で、今ユーザーがどの問題に正解したかを記録しています。
その情報を用いて、天使のヒント欄で次にどのような誘導をするべきかを判定しています。

## 画面レイアウト
少し画面レイアウトについて説明します。
基本的に Bootstrap を使用していますが、現在の設定では画面サイズによるレイアウトの変更は行えていません。

### 導入画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387790/ac2d33b9-4c3d-b918-9592-2204f12925de.png)

はじめひらひらと手紙が落ちてきます。しばらくすると、Tap! という文字が出ます。
タップすると中身がぼわんと表示されるような、演出が入ります。
そこで手紙の内容を読んでもらって、なんとなくシナリオを理解してもらいたいと思ってます。
PC だとレイアウトが大崩壊します（笑）

### 基本画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387790/c8c8f090-4e66-b885-2a67-ce9a14b0281a.png)
こんな感じです。特に言うことは無いです。
レスポンシブなレイアウトを想定して要素を組みましたが、うまくはめる時間がありませんでした。


# 感想

投稿予定の裏話・開発手法編では、
「何をしたか、何が悪かったか、どうするべきだったか」
について、もう少し詳しく語る予定です。ですが、ここでも少しだけ書かせてください。

## まず謝辞

関わってくださった、全ての人に感謝します。

テストプレイをしていただいた、たくさんの同期、出身研究室の後輩、高校の同級生。
そして、恐らく本番プレイしていただいたはずの忘年会の参加者の皆様。
コソコソ開発しているのを、温かい目で見逃してくださったデスク周りの皆様。

本当にありがとうございました。以上を持って、謝辞とさせていただきます。

というわけで、感想です。
本音と建前を使い分けろってのは、ビジネス研修で習った一番大切なことですァァーー！！！！！

## （建前）

- うぇぶさーびすをこうせいする、たくさんのぎじゅつをかんぜんにりかいしました。
- のうきをみすえながら、すぷりんとばっくろぐをさだめ、しっかりあじゃいるかいはつしました。
- しゅみのかいはつだったので、みんなたのしくできました。しんじんのなかではじっそうがとくいなひとをあつめたので、じっそうじかんがみじかかった。

## （本音）
正直、この Web アプリを開発してほんまに良かったと思ってます。その気持ちに嘘はありません。
メンバーには、感謝しかないです。手伝ってくれた友達、ほんまに感謝してます。
でも、その中で僕は、いろんな後悔、してきました。
僕なりに真剣に考えて、考え抜いた結果です。今回の開発で思ったこと全部、包み隠さず話します。

### うぇぶさーびすをこうせいする、たくさんのぎじゅつをかんぜんにりかいしました。

「正直、まったく分かりませんでした。僕の理解が追いついてない。最悪です。」

開発に慣れていないフロントの実装に時間がかかりました。
Bootstrap を使用したものの、レスポンシブデザインは達成されていません。
プロトタイプ版からのデザインはかなり向上しましたが、それでも足りないと思っています。
Bootstrap という世間的には別に新しくもないような技術を使って、
詰まりに詰まってるのは普通に辛かったです。

### のうきをみすえながら、すぷりんとばっくろぐをさだめ、しっかりあじゃいるかいはつしました。

「正直、間に合いませんでした。忘年会の直前まで、開発やってました。」

レビューなどでもらった意見を反映に時間がかかりました。
レビューのたびにフィードバックをもらって、そのたびに修正しても、
利用者と開発者のプレイ感覚の差は発生し、是正することを繰り返しました。

特に謎解きにおいては、その時のひらめきに依存する部分が多く、解けたり解けなかったりするせいで、
**一体このアプリに何が足りていなくて、どれくらいの難易度なのかがわかりませんでした。**
どの程度ヒントを出せば良いか、などに非常に迷いながら謎解きの作成を進めました。
その試行錯誤の結果、楽に誘導してくれる存在として生まれたのが「天使のガイド」だったりします。

また開発が長引いた結果として、 Qiita を執筆する時間がありませんでした！！！！！！！！！！！！
僕が担当する記事を2つに分けたのは、そのせいです。まあ内容はまとまったと思います。

### しゅみのかいはつだったので、みんなたのしくできました。しんじんのなかではじっそうがとくいなひとをあつめたので、じっそうじかんがみじかかった。

「正直、楽しくないことも多かったです。信じられないくらい時間がかかりました。
　ほんまに、ストレスで肌荒れが MAX になって、思わずヒゲ脱毛に通い始めました」

本当に趣味だけなら、恐らくこれは完成していません……
趣味の開発のはずなのに、どうしてこんなにつらいの！？
みんな普段から実装が大好きで、得意なはずなのにどうしてこんなことになっているのだろう。
なんで、こんなつらい思いをして、開発をしているのだろうか。
そんなことばかり、最後のほうは考えていました。悲しかったです。
でも楽しかったのは本当です。

**作りたいものを大きく設定しすぎ、その割に計画性が無かったことが原因だと思っています。**

# まとめ
今回は、忘年会の余興のために開発した『謎解き Web アプリ』の紹介を行いました。
本日は簡単ですが、ここまでが 1 本目の記事、とさせて頂いて、
明日 14 日に 2 本目の記事が thtitech くんから、
25 日までのどこかで 3 つ目の記事が私（？）から上がると思います。

## Appendix.
本番では、謎解きの前に『寸劇』を行い、形だけですが謎解きへの導入を行っています。
寸劇の台本を公開しない代わりに、寸劇の書き言葉版を公開したいと思います。
供養として、ここに置かせてください。

ではみなさん、ここまで読んでいただきありがとうございました。
次の記事で、お会いしましょう。

<details><summary>ポエム</summary><div>

「SIerに入社したばかり彼は、アサインされた案件の厳しさに毎日てんてこ舞いだ。
家に帰れば、仕事での鬱憤を晴らすためにサンバを踊っていた[（参考文献）](https://qiita.com/ychNext9/items/0a56da4793e4c06b5d30)。
しかし、サンバだけではストレス解消が追いつかず、何もできない己への無力感が募るばかり。
ついには、心身共に追い詰められてしまい、自殺を考えてしまう。

ある日。
それは彼がいつも通り仕事を終え、やっとこさ疲弊した体を自宅まで持ち帰ったときの話だった。
とりあえずサンバでも踊るかと彼が思い立った時、

『俺は君の心の中の悪魔だよ。心が炎上してるね～』

突然、心の中の邪悪な部分が悪魔となって実体化した。

悪魔は新人に語りかける。
『あのね～、ウイルス手にいれたんだけどさぁ〜、最期にこれバラまいて会社壊そうよ〜』
心が弱ってしまった彼は、悪魔の言う通り、死ぬ前に散々暴れてやるのも良いかもしれないと考えた。

『ダメよ！　ウイルスなんて！』
彼の心が闇に堕ちきる寸前、心の中の善良な部分も天使となって実体化した。
『強く生きるのよ！　一緒に悪魔を倒しましょう！！！！』
まさか、自分の中にそのような善良な部分が未だに存在したとは思いもしなかった。
しかし、疑問だ。
「自分は男性なのに、何故心の中の天使は女性なんだろう」
下らない疑問を持つぐらいの余裕はあることに、自分で自分に少し安心した。
天使の言う通り、今まで真面目に生きてきたんだから、ここで馬鹿なことをしても勿体ない。

いや、でも。

「天使に協力して悪魔を倒したところで、別に社会は変わらないのになぁ」
冷静に、本質的な問題点に思考を巡らせた。冷静沈着な自分に安心した。
「まあ、別に一緒に戦うほどでもないか」
と、天使と悪魔の戦いをぼーっと見守ることにした。

そこから、天使と悪魔の不毛な戦いが始まった。
その戦いは、本当に見るに耐えないものだった。
天界的な異能力とか魔法を使うわけではない。
殴り合い掴み合いとか、そんなものでもない。
突然、『ラップバトル』を始めたのだ。

「ナナナナ～ナナナナ～」

謎のステップと謎のラップ。
どこかのお笑い芸人に感化されたのか、二人はゆるいテンポのラップを交互に披露しあっていた。
俺が勝った私が勝った、あーでもないこーでもないと、よくわからない基準で争い合っている。
なんとも形容し難い気の抜けるようなラップに、いかなる基準で優劣が付けられているのか、甚だ疑問であった。

天使と悪魔が判断に揉めた時、勝敗が彼の判断に委ねられることがあった。
そこで適当に感想を言ってみたら、「お前は何にもラップをわかっていない」と二人して貶してきた。
彼は呆れるしかなかった。天使は味方ではなかったのか。

彼の心が追い詰められているのと同じように、天使と悪魔の心もまた追い詰められていたのである。
彼はため息をつき、二人の不毛な戦いを尻目に、その日は眠りにつくことにした。
その戦いは彼が眠りについたあとも、夜通し続いた。

次の朝、悪魔はこう呟いた。
『彼さん、爆散』
勝敗の天秤は悪魔に傾いたのだ。
そのラップを最後に、彼は体のコントロールを悪魔に乗っ取られ、会社にウイルスを撒き散らしてしまった。

天使は実体化を解かれる寸前、最後の力を振り絞り、
ウイルスの解除プログラムを社内に残すことに成功した。
悪魔にバレないように、解除のためのヒントを謎として残し、他の社員に協力を仰いだのだった。ﾟ(ﾟ´ω`ﾟ)ﾟ｡ﾋﾟｰ
」</div></details>