# プログラム言語構文専門タイピングゲーム「scriptyper」
htmlのタグ名、cssのプロパティ、jsのイベントハンドラ、
jQuery,Reactなどの特殊な構文・・・
それらの言語構文をタイピングしていく。
Webページに興味がある人から、単にタイピングやりたいっていう人にも勧められるようなゲームにしていく予定。
## About
- タイピングゲームはタイピングゲームだが、お題として出てくるのがプログラム言語の様々な構文。
- 対象言語は、
- html
- css
- javascript
- jquery(非推奨)
- php(出来たら)
- react(出来たら)
- git **←NEW!!**
**↑ここまでが最低でも実装したい箇所。ここから先は検討中。**
- 構文をタイピングしていくことで、一つのwebページを作っていくという機能。
画面イメージとしてはこのhackMD。
左側で指定されたタグ名をタイピングしていけば、そのタグが右側で反映され、ページが出来上がっていく。
html部門で骨組みを作り、css部門で装飾。js部門で動きを追加。
完成予想図でステージを選び、指示通りの構文を打っていくことでリアルタイムに反映されていく。
上級者向けになると単語の指示が、例えば、html部門にて、「h1」であれば「見出し1」、css部門で「background-color: green」であれば「緑の背景色」等と表示される仕組みに。
## 開発環境
react typescript
ライブラリ: react-typing-game-hook
### プロジェクト名:scriptyper
## 機能
- ゲームオーバーの条件:
- タイムオーバー
- ミス単語が一定数超える
- バックスペース機能は装備。
- 一構文づつ出していく
- 単語の下に意味を備えておく。
- レベルごとにノルマ単語数が違う。
- html部門・css部門・js部門・ごちゃまぜ部門の三つを設ける。
- 単語は**JSONファイルに全て格納**。この際、意味とレベルも合わせて設定。
- 単語ごとにレベルを設定。長ければ長いほどレベルは上がる。レベルは全部で1-5段階。
- 別途gitコマンドバージョンを製作。モードとして選べるように。**←NEW!!**
- モードはそれぞれ以下の通り
- 単語の下に意味を載せるチュートリアルモード
- ただタイピングしていくタイプモード
- 意味だけで単語を予測しタイピングしていくチャレンジモード
- 入力部分の下にそれぞれ以下の物を表示
- 今現在の単語数
- 正解単語数/ノルマ単語数
- ミス単語数
- ## 単語数カウントの方法
react-hooksが恐らく望ましいのだろうが、あまりよく知らない・・。
## 得点の仕組み検討
ノルマを10単語とし、その単語に間違いがあるか確認する。その結果を配列に格納する。
もしあった場合は**false**、ない場合は**true**を格納。
配列に10コ値が入ったら繰り返し構文で配列の中のfalseの数をカウントしそれを表示する。
配列名: CalculatingScore: boolean
単語一文字一文字にspanが指定されており、それで打った文字が一致していればそれに応じたクラスをつけるという仕組み。
すべてのspanにクラス「char__true」もしくは「char__false」または両方がついたら上の配列にtrueかfalseをプッシュ。
それと同時に単語を新しいものを出したいのだがこれが一番の関門。
レベルはいったん置いておく。
ゲームオーバーの条件は今回は無視。タイピングゲームとして最低限の機能だけつけて中間発表!!
今回はgitのものだけを出していく。
## 単語入力メカニズム
変数**chars**にJSONから持ってきたワード(**randomWord[intRandom]**)を入れている。
その単語の入力が正解か間違っているか、それとも何も入力されていないか(0(未入力),1(正解),2(間違い))を**charsState**に入れる。
charsの中の文字を一つ一つ抽出して配列化したものが**chars.split("")**
照合の際の変数にstateを適用させる。名前:charsArray
chars.split("")の一文字一文字と入力された文字(e.key)を照合し、
- あっていればcharsStateに1をpush
- 間違っていれば2をpush
- 未入力であれば0をpush
pushされ次第照合変数のstateをカウントアップしてつぎの文字へ進む。
↑ここまでが関数insertTyping
削除を行う際は、charsStateの中の最新の数を削除する。
## 得点換算
得点を格納するデータベースはpostgreSQLの予定。(でも時間がないので切羽詰まったときはmySQL)
そこにpythonもしくはexpressなどといったAPIでreactから受け渡された得点などを用いてデータ操作を行う。
### 具体的な換算方法
charsStateの中身を一つ一つ確認して全部1の場合は得点換算、2が含まれている場合は得点は0として送る。
データベース名はscriptyper
テーブルはhtml,css,js,git等のモード別に用意
行は
- 単語の出てきた順番 intRandom
- 単語のレベル randomLevel
- 用意される点数 randomScore(
- lv1:1
- lv2:2
- lv3:3
- lv4:4
- lv5:5
)
- 正誤 judge(bit)
- (かかった時間)
- 得点 calculatingScore
以上
create table git(intRandom smallint, randomLevel smallint, randomScore smallint, judge bit, calculatingScore smallint);
合計点でランク分けがされる。(詳細未定)
react側で単語ごとに1(true)か0(false)の値を入れた配列calculatingScore、そして単語ごとのレベルを入れた配列「randomLevel: number[]」をAPIに渡して1単語目は1か0か、2単語目は・・と繰り返し処理を実行し、その後に1だった単語のレベルを見て点数にそのレベルの数をかけてこれで点数配列の出来上がり。
postgresqlなりデータベースに提出したのちにJSONテーブルとしてAPIに返す。その値をフロントの各変数に割り当てて結果を表示する。
~~**単語を入れるJSONはいずれひとつのJSONファイルにまとめ上げる**予定~~**(完了)**
## 構文に間違いがないか確認する方法
charsStateの中に2が入っていればcalculatingScoreには0がプッシュされる。
charsStateの中に2が入っていなければcalculatingScoreには1がプッシュされる。
#### expressプロジェクト作成
cd Desktop/program-warehouse/scriptyper
mkdir backend
cd backend
yarn init -y
yarn tsc --init
yarn add express
yarn add -D @types/express
フロントに情報を届けるのはapi.js。
~~[html,css,js,git]の四つの文字の入った配列を用意。
選択されたモードにあった文字列をフロントに渡す~~
INSERT INTO html (randomLevel, judge) VALUES (randomLevel[], calculatingScore[])
wordContainment.git
wordContainment.html
wordContainment.css
wordContainment.javascript
~~もう一つコンポーネントを作成。その中にはモード選択のためのボタンを表示。
app.jsの中でどのモードを選択されたかを判断し、そのファイルを読み込ませる。~~
randomWord、randomMean、randomLevelはbackendの中に配置し、wordContainment.jsonもbackendの中に配置。
## 課題
- モード選択時にexpressサーバーに選択したモードを送信する
- モードに対するjsonをexpressサーバーから返してもらう
- word.tsにてタイピングする構文の配列を作成しTypingGameComponentに返す
- ゲームを進行し結果が表示されるところまで行ったら正誤をbackendに送る
- 正誤とrandomLevelから得点を計算しexpressサーバーに送信する
- モードに対する得点をデータベースに登録する
**react-express-dockerにて試しにwordContainment.jsonをコピペしてモード作成並びにフロントに完成した構文配列を送りウィンドウ上に表示させるデモンストレーションを行う**
## docker管理方法
コンテナ名:scriptyper
コンテナ作成コマンド docker-compose up -d
コンテナ侵入方法
- フロント: **docker exec -u node -it front /bin/bash**
- バック: **docker exec -u node -it back /bin/bash**
frontend内のpackage.jsonに以下を追記
"proxy": "http://backend:3010"
~~フロントとバックそれぞれのDockerfileを作成しているので
docker-compose up --build
で起動可能な筈。~~
# 最終発表資料ここから
## 流れ
- モード選択
- 入力(ノルマ10単語)
- 得点表示**←バグ発生中!!**
ミニゲーム、気休め感覚でプレイする想定なので機能やグラフィックのこだわりは一切なし。
ちなみにreactロゴを最後まで何で残してるのかは自分でもわかりません。
## 問題点
- 実際に表示されるコンポーネントの型がおかしいことになっており一時エラーが出るが動作には問題ない
- 得点表示が何故か4倍されている(処理が4回繰り返されている模様)
- モード追加も検討中だが、各コンポーネントの細かい無数のところを書き直さなくてはならず、面倒(知識不足が原因ですが致し方なし)
# 今後の課題
- changeTyping実行時にはアニメーションを適用させる(入力完了した単語のフェードアウトと次の単語のフェードインと別々で分け、各々のクラスを付けたり外したりする(useStateをうまく活用))<br>
- タイマーの付加&配列に付加させ最後に表示させる(レベルごとにノルマタイムを計算させる関数をTypingGameResult.tsxに加える)<br>
- ゲーム進行時にカウントアップするタイマーは回ってるロゴの前に入れる。可能であればコンポーネント化<br>