19
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

無職がElm勉強してタイピングゲームを作った話

Last updated at Posted at 2019-12-25

趣味でプログラミングしていましたが、Elmを勉強しタイピングゲームを作ったので記事を書いてみたいと思いました。
よろしくおねがいします。

これが作ったものです
追加の別バージョン
適当に試してみてください!

Elmの難しさ

正直、自分は難しいと思いました。
関数型プログラミング言語に触れるのは初めてでそれが理由かどうかはわかりません。
うまく説明できないのですが、型です。
数学の公式をわけもわからず使って、調べてみたら難解だったというのと似てる気がします。

コンパイルエラーがたくさん親切に出てくれるので、慣れてしまおうと愚直にすすめることにしました。

恥ずかしながらいまだにHtml.mapのサンプルなどが理解できていません。

タイピングゲームの難しさ

パターンが多い

簡単なものなら「sushi」と表示させそれをそのまま入力させればいいのですが、「し」を「si」と入力したい人は困ってしまいます。
「ん」の処理となると「nn」「xn」「n」と3パターンの入力方法があります。
「ん」は厄介で、「んこ」だと「nko」で打てるのですが、「んよ」などは「nyo」では打てません。
「んっこ」だとこの3文字で30パターンくらいになります。

テストを早めに作る

パターンが多すぎて手で入力できるか試してられないので、「これは入力可能」だから成功しなければならない、「これは入力不可能」だから失敗しなければならない、というものを簡単なものから追加していきました。

Google日本語入力

google_input
この方法を知ったおかげでタイピングゲームを作ってみようという気になりました。
これと「基礎からわかる Elm」が出版されたことで開発が始まりました。
ありがとうございます。

実際には自分の理解が足りないのか苦労が多かったです。
高速化などは考えず実装しましたが、今のところ自分には問題ないように見えます。
これがコードになります

ElmでSPA

SPAにする必要はあるのかとも思いましたが、勉強にもなるということでチャレンジしてみました。
どのような構造がいいのか変わって行き苦労しました。

共通情報をどうするか

各ページ共通で利用するかもしれないデータをどうするか悩みました。

Main.elm
type alias Model =
    { env : Env
    , page : Page
    }

このenvを各ページのinitとupdateに引数で渡してしまうことにしましたが、viewには渡していません。
理由があるわけではありません。
良い設計かどうかわからず、たぶんまた変わります。

Main.elm
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
-- 略
        ( TypeLongWordMsg subMsg, TypeLongWordPage subModel ) ->
            let
                ( newModel, topCmd, newEnv ) =
                    Page.TypeLongWord.update subMsg subModel model.env
            in
            ( { model | env = newEnv, page = TypeLongWordPage newModel }
            , Cmd.map TypeLongWordMsg topCmd
            )
-- 略

Parser

そのまま使うことはできそうですが型が追えなくてあきらめました。
かわりにfragmentで代用してしまうことにしました。

Main.elm
goTo : Url.Url -> Model -> ( Model, Cmd Msg )
goTo url model =
    let
        pEnv =
            model.env

        env =
            { pEnv | url = url }
    in
    case env.url.fragment of
        Just "post" ->
-- 略

しかし、後でクエリーからデータを取りたくなりページ内で結局使い「しまった」と思いました。

困りごと

現在あきらめてますが、ページが切り替わるとデータが消えてしまうということに気づきました。
編集ページ -> 別のページ -> 編集ページ(消えてる)

Urlでなく、ページからページへ直接データを渡すのもどうしようと悩んでいます。

おしまい

愚直に進め過ぎで、Elmの真髄に触れていないままかもしれません。
かなり苦労もありました。
しかし最も好きな言語になりそうなので、さらにElmを勉強していきたいと思います。

ここまで読んでいただきありがとうございました。

19
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?