【高専ベンチャー社xゆめみ社 2022ハッカソン春】なんか勝った話

# プロローグ

初めましての方は初めまして。
先日、高専ベンチャー社xゆめみ社 2022ハッカソン春の陣で優勝したチームDの私です。
備忘録ではないんですが、気合で作ったのでメモっておこうと思います。
**メモです。参考になる情報は書いてません。**

優秀な後輩くんのQiita記事はこちらから↓↓↓

https://qiita.com/naotiki/items/4c8b9d698164289f082c

## お前、何つくった

弊チームは「チャットx縛りお絵かきゲーム」を作成しました。

https://github.com/Yumemi-Hackathon22-D/DRAW-RUSH


しかし結論から言いますと、**俺自体は何も作ってない**、が正解です。
謎パワーで勝ちましたので。

謎パワーって書いてもあれなので、開発の経路をちゃんと書こうと思います。

### コンテスト概要

参加人数12名、4チームでのオンラインハッカソンです。

コンテストテーマは
**「コロナ禍でも使えるコミュニケーション加速系アプリを作ろう」**
みたいな感じでした。(多分)

開発期間はGW中で、5/7に最終開発と発表があります。


## --- 顔合わせ後 ---

```:開発会議にて
Dev A「ゲームをチャットでやったら盛り上がったよ(超簡略)」
後輩「お絵かきに制限時間入れたらいいじゃん(超簡略)」
私「じゃあ作ろうぜ」
```

この時点で私は **「じゃあ作ろうぜ」** しか言ってません。

```:開発会議にて Part2
Dev A「Firebase、使ったことあるから使おうよ時代の最先端だよ」(若干の脚色あり)
後輩「無料枠広いからいいね」(若干の脚(ry)
私「ふえぇ、、、Firebase使ったことないよぉ、、、(ょぅι゛ょ退行)」(若(ry)
```

この時点で私は **「Firebase使ったことない」** しか言ってません。

```:開発会議にて Part3
Dev A「React native使ってたのでReact開発どうですか？」
後輩「React少しだけ触ったことあるので、いいと思います」
私「ふえぇ、、、React.js書いたことないよぉ、、、(ょぅι゛ょ退行)」
```

とことん無能ですね、私。

そうそう、無能で思い出したんですけど、
Slackの招待リンクに気づかなくて2日くらい遅く合流したんですよね。

## --- 開発会議後 ---

開発したいものざっくり決めよう会議（略して開発会議）が終わって、結局以下の条件を満たすアプリケーションを作ろう！ということになりました。

 - チャットできる
 - 絵も書ける
 - めちゃくちゃおもしろい

「めちゃくちゃおもしろい」がなかなかアイデアが出なかったので後輩くんを召喚し、アイデアを生成してもらいました。

```
Kouhai.getIdea()
> 時間制限とか、書き手に負荷をつけたらカオスになって面白いかも
```

チームメイトに天才がおった。

さて、私の出る幕はないので丸々アイデアを採用して開発を始めよう。うん。

## --- 開発開始 ---

### 開発環境のはなし

```:俺の開発環境
Windows 11 Pro (OS Build:22000.613)

node: v16.15.0
npx, npm: v8.8.0
yarn: v1.22.18

コード管理: Sourcetree v3.4.8 (Windows)

エディタ: Visual Studio Code
```

どうでもいいけど「俺の〇〇」って書いてあったら基本的に説得力増すよね。知らんけど。

#### 初期設定でやったこと

VSCodeで適当なディレクトリを作り、おもむろにターミナルを開きます。
そして`create-react-app`を入れます。

```:Terminal
npm i create-react-app
```

`create-react-app`が入るのを待ちながらお茶を淹れましょう。多分後で飲むので。

入った後は`create-react-app`で整備します。

```:Terminal
npx create-react-app <Application Name>
```

np"m"ではなくnp"x"です。
詳しくは[そういう感じのページ](https://www.npmjs.com/package/npx)を調べてください。

いい感じに整備されたらディレクトリを開き直して、ひとまず開発環境の出来上がりです。

Sourcetreeをくくりつけて、ブランチ3本くらい立てて開発を始めます。

```:ブランチたち
feature: 基本はこのブランチをいじる。featureなのでバグがあっても怒ってはいけない。
dev: featureでコミットが溜まったり、機能として完成したらこのブランチにマージする。全然使わんかった。
main: 人に見せられるものが出来上がったらmainにぶちまけます。
```

### Day 1

お絵かき機能を作る後輩くん、行方不明になるDev A、Chat機能はおろかFirestoreにすら繋げられなくて(※1)涙が止まらない私。

書くことがないくらい何も書けなかった日でした。
※1 原因はFirebase v9でv8のコードを書いていたから
### Day 2

お絵かき機能の制限時間機構 / レスポンシブ対応 / その他FixをしながらuseStateにブチギレる後輩くん。
ゲームルームを作成できて(※2)、前前前世が動かなくて(※3)、部屋IDを入れられるようになって(※4)、心が折れ(※5)る私。

※2 Firestoreでゲームルームをドキュメントとして管理しています。
```:ドキュメント追加のコード
addDoc(collection(db, '<collectionの名前>'), { <props> })
```
 
※3 メソッドチェーンのことを前前前世[^1]と呼んでいます。
[^1]:https://github.com/approvers/RADWIMPS
```:前前前世の正解例
new Promise().then().then().then().世()
```

※4 ルームの参照先をそのまま保存し、参照先からIDだけをもぎ取ってくるという簡単なロジックです。

※5 チャットが表示できなくて涙を流していました。原因はStateだったらしいです。

### Day 3

Stateにブチギレ通り越して心配する、ついに壊れ始めた後輩くん。
react-cookieを導入し(※6)、さらにonSnapshotを完全に理解して ***†Contribute†*** を果たす(※7)私。

ちなみにStateは非同期処理中に変更されても即時反映されないみたいです。

※6 [そういうパッケージ](https://www.npmjs.com/package/react-cookie)があります。めちゃくちゃ使いやすい。

※7 v9のドキュメント見たら一瞬でした。なお、そういうことではなかったようで即修正commitが走りました。

### Day 4

お絵かき機能を気合で実装し、画像共有ができるようになって、最強の関数を実装する後輩くん。
コード整形で最強のコンフリクトコミットと、自分のコンフリクト解消コミットしか作らない私。

コード整形はテロなので、最初から読みやすいコードを書きましょう。

### Day 5

リザルト画面を実装している後輩くん。
chat画面を画面右に固定したり(※8)、bug fixの神と呼んでほしくなった(※9)私。

※8 `position: flex`で、`right: 0`にしたら右に固定できたので解説しません。

※9 nullチェックに失敗していたバグを修正しました。偉い。

### Day 6

正誤判定を実装する後輩くん。
チャットを完全に作成する(※10)私。

※10 CSSコピペです。というか他を整形しろ。

### Day 6 Night

朝一番のコミットは0:09です。
チャット画面の自動スクロール(※11)、Enterでチャットを送信できるように(※12)、空白で送信できてしまうバグをfix(※13)、服を着ろと言われ(※14)、就寝する私。

※11 `setTimeout`を挟んで`scrollTo`を呼ばないと描画が追いつかない的な記事を呼んだので、
```javascript:スクロールするやつ
setTimeout(() => <スクロールしたいやつのref>.current.scrollTo({
  top: <スクロールしたい高さ>
  left: 0,
  behavior: 'smooth'
}), 200);
```
みたいな実装をしました。で、結局なんかタイミングがズレて動かなかったので修正されました。
修正できた、って聞いたときは全裸でpush待機してました。(これが※14の服を着ろfixコミット)

※12 ただ単純な機構です。`onKeyDown`で発火したキーがEnterかどうか見るだけです。

※13 `<メッセージのstring>.trim() == ''`で弾くように実装しました。

※14 コミットログ見たらあります。探してみて下さい。

### Day 7 (発表日)

お腹が空きつつ足りない機能を実装してくれる後輩くん。
Firefoxで`overflow-y: overlay`が動かないということを知ったので、Firefoxにだけ適用される秘密のcss(※15)を実装しました。
自分の回答がハイライトされるやつ(※16)も追加してみました。

※15 Chromeは動いたんですけどね。適用できるブラウザは他にもあるみたいなので調べてみて下さい。
```css:Firefoxの場合
_:lang(x)::-moz-placeholder {
  /* Firefoxにだけ適用されるよ！ */
}
```

※16 回答リストのIDが自分のだったら`backgroundColor`を指定した、というだけです
Reactの`style={{ /* css */ }}`を使うときは、スネークケースをキャメルケースに変換するみたいです。

## --- 発表 ---

パワポ資料を気合でゴロゴロ作り、メンターさんにアドバイスを頂いてめちゃくちゃに書いてやりました。
なかなかカオスな資料になりましたが、見やすくする努力をしました。

弊チームは一番最後…これはプレッシャー…とか思いながら、他チームの成果発表を聞いていました、が、

**やばい。めちゃくちゃユニークでハイクオリティ。**

最初からめちゃくちゃハイクオリティで渾身の右ストレートをくらいました。
というか相手の中には未踏ジュニア受賞者様が居るんやぞ。勝てる気せーへん。

弊チームは、発表途中のデモでまさかの事件(※17)が発生しましたが、なんとか無事でした。
質疑応答が終わり、最終審査のためチームルームへ戻り、満身創痍な私。

※17 後輩くんの現代アートを同チーム開発者の私だけ当ててしまう事件。八百長や口裏合わせ等を疑われましたがマジで私がビックリしました。マジで。

## --- 審査結果 ---

題名のとおりです。優勝しました。これが謎パワーです。
私のプレゼンスキルも評価して頂けたみたいなんですが、私特有の早口なんですよね。頭、空っぽ。
他にも色々評価を頂いて、めちゃくちゃ勉強になりました。
というか他のチームのアイデア、面白かった。

## 結論

めちゃくちゃ楽しかったです。
勉強にもなりました。また参加しに行きたいです。

参加者の皆様、審査員の皆様、お疲れ様でした。