ヴォイニッチ計算記という選択肢

クソアプリ Advent Calendar 2021　23日目の投稿です。
今年も電卓の季節がやってきました。皆様、どうお過ごしでしょうか。電卓していますか？
私はしてません。

#前科
前回のAdvent Calendar [漢数電卓という選択肢](https://qiita.com/NekoCan/items/fda279d2faf4c393d64b)
電卓を漢数字で表現することで、電卓の可能性を広げました
（使うかどうかの話はしないものとする）

今回も電卓の可能性を広げようと思います
#####とりあえず今回の現物を見たい人は[こちら](https://unityroom.com/games/voynich-calclator)

#テーマ
今回のテーマは「ヴォイニッチ手稿」
[ヴォイニッチ手稿 -Wikipedia-](https://ja.wikipedia.org/wiki/%E3%83%B4%E3%82%A9%E3%82%A4%E3%83%8B%E3%83%83%E3%83%81%E6%89%8B%E7%A8%BF)
![image.png](https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Voynich_Manuscript_%28141%29.jpg/300px-Voynich_Manuscript_%28141%29.jpg)

これをモチーフに作成します


#作る
環境は
Unity：2020.2.7f1
で作ります

##下地
背景にはこちらを使います
[![image.jpeg](https://thumb.ac-illust.com/73/7321cb1888ebcbef13a2117f98d3f41c_w.jpeg)](https://www.ac-illust.com/main/detail.php?id=79945&word=%E5%B7%BB%E7%89%A9&searchId=2066958590#)
[イラスト素材：巻物](https://www.ac-illust.com/main/detail.php?id=79945&word=%E5%B7%BB%E7%89%A9&searchId=2066958590#)





##ヴォイニッチる
以前、ヴォイニッチのことを知った際に、フォントがないかなと思ったらありました。
そのため、今回のヴォイニッチ計算記の作成を思いついた訳です
[ヴォイニッチ等幅 -あらむぎ-](https://aramugi.com/?page_id=5404)
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/14066118-e2e4-1b64-5262-5d6450dede8b.png)](https://aramugi.com/?page_id=5404)









###Hello World
つまりこのようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/42660469-3a2a-fa9a-41f0-ea0a1166795b.png)
なるほど読めん

全然世界に挨拶した気分になれないヴォイニッチさんこんにちは。

思ったより雰囲気があるので
ついでに遊んでみる




###DeepL 走れメロス ヴォイニッチ
>
DeepL
走れメロス
ヴォイニッチ

~~これはDeepLで走れメロスを翻訳した上でヴォイニッチることを表した一句で、
翻訳を実行する「Run」と「走れ」をかけたものになっており、
季語はメロスですかね~~

走れメロスの冒頭部分をDeepLで翻訳し、

```
Melos was furious. He decided that he must get rid of the evil and tyrannical king. Melos did not understand politics. ...略 
```
見てみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/b8345578-442d-b2b9-2f79-d77471c6856b.png)
**も う こ れ だ け で 面 白 い**

# デザイン

今回の計算機はこのような見た目をイメージして作ります。

InputFieldに数字を入れて四則演算していって履歴が見れればいいかなって感じで設計を考えました
（記録を残すって意味で 計算記 ってね）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/0df8a604-be7e-2c19-1754-24571763d3c1.png)

しかし問題が

- 数字キー押すのとマウスのボタン操作が面倒くさい
- 改ページが面倒くさい~~（作るのが）~~
- ページのデータ保持とページ移動が面倒くさい~~（作るのが）~~



## 思い切って根本的にGUIを変更

「クソアプリ」なので、使い勝手がクソでも問題ないんですが、
「クソ」なアプリを作りたいのであってクソGUIを操作したくはないです
結論としては「使いやすいクソアプリ」
そんなアプリをわたしは作りたい

更新内容としてはこんな感じ

- 画像を縦に使い、縦スクロールで履歴を保存する形式
- すべてボタン操作
- 流石に何を計算しているか見たいので、ボタンの上に計算する数値を表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/0165fd1d-b3cc-831b-a640-b249cb0103fb.png)


~~これは書いている紙（スクロール）と縦移動（スクロール）をかけたもので
季語はないです~~

# プログラム
ヴォイニッチフォントはアルファベットのみ対応しているので、文字をアルファベットに変換する必要があります
`Dictionary`を使って数字、記号、括弧をアルファベットに対応づけます
イコールボタンが押されたら選択した四則演算に従って計算されて、
計算過程が記録される形となっております

``` Calculator.cs
public class Calculator : MonoBehaviour
{
    [SerializeField] Transform textParent;
    [SerializeField] Text textPrefab;
    [SerializeField] Text inputText;
    [SerializeField] Text lastInputText;
    [SerializeField] Text operateText;
    [SerializeField] Scrollbar verticalBar;
    Dictionary<char, string> number = new Dictionary<char, string>();
    Text display;
    public enum Operate { Add, Sub, Multi, Divide}
    [SerializeField]
    Operate operate = Operate.Add;
    void Start()
    {
        InstText();
        number.Add('-', "Minus");
        number.Add('0', "Zero");
        number.Add('1', "One");
        number.Add('2', "Two");
        number.Add('3', "Three");
        number.Add('4', "Four");
        number.Add('5', "Five");
        number.Add('6', "Six");
        number.Add('7', "Seven");
        number.Add('8', "Eight");
        number.Add('9', "Nine");
        number.Add('.', "Dot");
        number.Add('E', "NaturalLogarithm");
        number.Add('+', "Plus");
        number.Add(':', "Colon");
        number.Add(',', "Comma");
        number.Add(' ', " ");
        //括弧の英語
        //https://www.rarejob.com/englishlab/column/20210928_02/
        number.Add('[', "OpenSquareBrackets");
        number.Add(']', "CloseSquareBrackets");
        number.Add('(', "OpenParentheses");
        number.Add(')', "CloseParentheses");
        number.Add('{', "OpenCurlyBrackets");
        number.Add('}', "CloseCurlyBrackets");
        number.Add('<', "OpenAngleBrackets");
        number.Add('>', "CloseAngleBrackets");
    }
    public void InstText()
    {
        display = Instantiate(textPrefab, textParent);
        VerticalBar();
    }
    // 文字変換関数
    public string translate(string nums)
    {
        print(nums);
        string str = "";
        for (int i = 0; i < nums.Length; i++)
        {
            if (number.ContainsKey(nums[i]))
            {
                str += number[nums[i]];
            }
            else
            {
                str += nums[i];
            }
        }
        return str;
    }
    //四則演算ボタンからの呼び出し
    public void Operation(int operation)
    {
        operate = (Operate)operation;
        operateText.text = (operate == Operate.Add ? "+" :
            (operate == Operate.Sub ? "-" :
            (operate == Operate.Multi ? "*" :
            (operate == Operate.Divide ? "/" : "?"))));
    }
    //Equalボタンからの呼び出し
    public void EqualButton()
    {
        if (inputText.text.Length == 0) return;
        double inputed = 0; 
        double lastInput = 0;
        try
        {
            lastInput = double.Parse(lastInputText.text);
            inputed = double.Parse(inputText.text);
        }
        catch (Exception e)
        {
            Debug.LogError(e);
            //エラーも表示
            display.text += translate(e.ToString());
        }
        switch (operate)
        {
            case Operate.Add:
                lastInput += inputed;
                break;
            case Operate.Sub:
                lastInput -= inputed;
                break;
            case Operate.Multi:
                lastInput *= inputed;
                break;
            case Operate.Divide:
                lastInput /= inputed;
                break;
        }
        display.text += operate + translate(inputText.text) + "Equal" + translate(lastInput + "");
        lastInputText.text = lastInput + "";
        ClearInputingText();
        VerticalBar();
    }
    //クリアボタンからの呼び出し
    public void ClearButton()
    {
        ClearInputingText();
        display.text = "";
        lastInputText.text = "0";
    }
    //数字ボタンからの入力
    public void PushButtonNum(string num)
    {
        string text = inputText.text;
        if (text.Length >= 1 && text[0] == '0')
        {
            inputText.text = text.Substring(1, text.Length - 1);
        }
        inputText.text += num + "";
    }
    void ClearInputingText()
    {
        inputText.text = "";
    }
    void VerticalBar()
    {
        StartCoroutine(VerticalBarDown());
    }
    IEnumerator VerticalBarDown()
    {
        yield return new WaitForEndOfFrame();
        yield return new WaitForEndOfFrame();
        verticalBar.value = 0;
    }
}
```
この後に変更した箇所もありますが、他クラスの関数呼び出しとかなのでスルーします。

## 実行してみる
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/785fb791-7984-6743-649d-f838e3a7b013.gif)

まぁ動作に特別問題はない

が引っかかる点があるので一部変更

## エラーが起きない
プログラムをよく見ると

```一部.cs
        double inputed = 0; 
        double lastInput = 0;
        try
        {
            lastInput = double.Parse(lastInputText.text);
            inputed = double.Parse(inputText.text);
        }
        catch (Exception e)
        {
            Debug.LogError(e);
            //エラーも表示
            display.text += translate(e.ToString());
        }
```

文字列をdoubleに型変換する時にエラーが起きたらそのまま表示する仕様となっている
しかし、なかなかエラーは起きないため、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/0123169c-e157-36da-9390-5e8c6c6b4e64.png)
入力欄をインプットフィールドに変更し、**ヒューマンエラーを誘発させる**

## 挿絵がない
ヴォイニッチ手稿には植物の挿絵がちょくちょく入ってくる
[![kabu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/713867a3-7d2a-1176-5c70-b42b2806f168.jpeg)](https://www.dropbox.com/s/8bz5dxxd2u4gg2x/Voynich%20Manuscript.pdf)

なので、
クソアプリにしては**「うざさ」がない現状、不定期に挿し絵を差し込む**ことにする

挿絵を取得するにあたり、ヴォイニッチ手稿がスキャンされてることを知ったのでダウンロードしてきました
[解読不能の奇書「ヴォイニッチ手稿」が電子書籍化され誰でもダウンロード可能に - GIGAZINE](
https://gigazine.net/news/20160405-voynich-manuscript-ebook/)


# クソアプリの実行
![voynich1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554244/dfe571a7-13b0-60ca-3e35-844a62a387ff.gif)

## クソアプリポイント
- 読めない
- 数字のボタンも四則演算ボタンも分からない
- イコールボタン押さないと計算されない
- **数値入力欄にアルファベットが打てる**
- **なんならエラーも表示する**
- **ちょくちょく挿絵が飛び込んでくる**
- 今更ながら、履歴欄に表示してるの文字なんだから右寄せである必要がなかった

# 遊びたい方はこちら
[unityroom](https://unityroom.com/games/voynich-calclator)にアップロードしました
ゲームではないのでこのリンク共有のみの限定公開にしています
（ゲームじゃないものをゲーム投稿サイトに載せるのは流石に違うかなって思いまして）



あと、特に意味はないですが、unityroomに投稿した時に、**ゲーム実況**という項目は**OK**にしてます


#ヴォイニッチ計算記という選択肢
以上のようにヴォイニッチ計算記には様々な可能性を秘めています
そのため、今後 電卓を使う際の選択肢にヴォイニッチ計算記は、`なし`です
当たり前ですね