tekiehei2317's blog

ホームポジションだけで入力できる配列を練習している

投稿日: 2025-04-12

エイプリルフールのジョークで「アルファベットを10文字にすればタイピングが楽になるんじゃね…?」みたいなことを考えていました。

もう少し考えを進めると、別にアルファベットが10文字じゃなくても、シフトキーを2つ使って配列を切り替えれば、ホームポジションだけでアルファベットを全て打てること気づきました↓ 無シフト、左シフト、右シフトで合計10x3文字を割り当てられるからです。

鉄馬 on X: "キーボードの配列について、親指シフトみたいにスペースを分割して3通り(無シフト、右シフト、左シフト)の状態を表せるようにすれば、一列だけでアルファベットを網羅できるので音ゲーみたいになりませんかね" / X

ということで、実際にやってみました。

配列を使えるように設定する

あるキーを押している間だけキーマップが変わるというのは、キーボード・配列界隈ではレイヤーという一般的な考え方のようです。レイヤーは、例えばキー数の少ない40%キーボードなどでは、キー数が足りないので必然的に必要になってきます。

レイヤーの切り替えには、スペースキーとかなキー(Windowsだと変換キー)を使うことにしました。私の環境はMacなので、Karabiner-Elementsを使って設定していきます。

Karabiner-Elementsのmodifierという設定項目を使えればいいのですが、modifierにはShiftやControlなどの一般的な修飾キーしか入れることができません。そのため、キーを押したときと離したときに変数のオンオフを切り替えることで、スペースキー等でのレイヤー切り替えを実現しました。

設定ファイル(karabiner.json)
{
    "profiles": [
        {
            "complex_modifications": {
                "rules": [
                    {
                        "description": "英数キーで入力をトグルできるようにする",
                        "manipulators": [
                            {
                                "conditions": [
                                    {
                                        "input_sources": [{ "language": "en" }],
                                        "type": "input_source_if"
                                    }
                                ],
                                "description": "入力ソースが英語の場合、英数キーをかなキーにする",
                                "from": { "key_code": "japanese_eisuu" },
                                "to": [{ "key_code": "japanese_kana" }],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "spaceを仮想修飾キーとして使う",
                        "manipulators": [
                            {
                                "from": {
                                    "key_code": "spacebar",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [
                                    {
                                        "set_variable": {
                                            "name": "space_pressed",
                                            "value": 1
                                        }
                                    }
                                ],
                                "to_after_key_up": [
                                    {
                                        "set_variable": {
                                            "name": "space_pressed",
                                            "value": 0
                                        }
                                    }
                                ],
                                "to_if_alone": [{ "key_code": "spacebar" }],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "かなを仮想修飾キーとして使う",
                        "manipulators": [
                            {
                                "from": {
                                    "key_code": "japanese_kana",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [
                                    {
                                        "set_variable": {
                                            "name": "kana_pressed",
                                            "value": 1
                                        }
                                    }
                                ],
                                "to_after_key_up": [
                                    {
                                        "set_variable": {
                                            "name": "kana_pressed",
                                            "value": 0
                                        }
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "spaceと中段の同時押しで、上段アルファベットを入力する",
                        "manipulators": [
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "a",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "q" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "s",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "w" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "d",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "e" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "f",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "r" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "g",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "t" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "h",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "y" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "j",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "u" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "k",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "i" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "l",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "o" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "space_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "semicolon",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "p" }],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "かなと中段の同時押しで、下段アルファベットを入力する",
                        "manipulators": [
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "a",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "z" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "s",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "x" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "d",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "c" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "f",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "v" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "g",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "b" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "h",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "n" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "j",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "m" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "k",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "comma" }],
                                "type": "basic"
                            },
                            {
                                "conditions": [
                                    {
                                        "name": "kana_pressed",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "l",
                                    "modifiers": { "optional": ["any"] }
                                },
                                "to": [{ "key_code": "period" }],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "上段と下段のアルファベット入力を無効化する",
                        "manipulators": [
                            {
                                "from": { "key_code": "q" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "w" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "e" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "r" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "t" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "y" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "u" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "i" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "o" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "p" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "z" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "x" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "c" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "v" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "b" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "n" },
                                "to": [],
                                "type": "basic"
                            },
                            {
                                "from": { "key_code": "m" },
                                "to": [],
                                "type": "basic"
                            }
                        ]
                    }
                ]
            },
            "name": "美曲配列(実験中)",
            "virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
        }
    ]
}

この配列は、美曲配列と仮称しています。由来は、音ゲー→OTOGE→尾棘→BIKYOKU→美曲です。

練習記録

4/1日に練習を始めたので、現時点で11日間練習しています。最初は同時押しに慣れておらず絶望的なタイプ速度でしたが、今は4.0~5.0key/sくらいで打てるようになってきました。配列の中身はQWERTYなので、習得は早かったです。

また同じ理由から、QWERTY↔︎美曲配列の切り替えも、特に大きな問題なく行えています。ある程度打てるようになった8日目くらいから一瞬混乱することがありましたが、どっちを使っているか意識して、何キーか打てばすぐ戻っています。e-typing腕試しを毎日やっていますが、現状ではQWERTYの腕が落ちたという感じもありません。

具体的な練習について、最初はマイタイピングの「ひよこでもできるタイピング講座」を使って、ひらがなの入力方法を覚えました。昔タッチタイピングを覚えるときにお世話になった講座なのですが、改めて完成度の高い講座だと思いました。

ひよこでも出来るタイピング練習講座 | タイピング練習の「マイタイピング」

1日目: 1.4key/s(ひよこのタイピング練習6「た~な行の単語」)

2日目: 2.2key/s(ひよこのタイピング練習11「五十音まとめ」)

3日目: 2.5key/s(ひよこのタイピング練習11「五十音まとめ」)

5日目: 3.4key/s(ひよこのタイピング練習11「五十音まとめ」)

8日目: 3.9key/s(ひよこのタイピング練習17「まとめ2」)

次に、e-typingの長文を使って練習しました。長文は、最初はまったく入力できず間違いまくりだったので、打てるようになるまでいい練習になりました。

タイピングバラエティ 長文 - インターネットでタイピング練習 イータイピング | e-typing ローマ字タイピング

8日目: スコア260(日本の昔話、桃太郎)

9日目: スコア300(日本の昔話、おむすびころりん)

10日目: スコア329(日本の昔話、さるかに合戦)

長文での練習で正確性が低いことがわかったので、長文の練習と並行して、正確性を上げるためにマイタイピングの短文で練習しました。マイタイピングの短文は、ワードが20種類しかなかったり、間違った文章のリトライを何度もできるので、反復練習にちょうど良いです。

今週のタイピング練習367-簡単短文 | タイピング練習の「マイタイピング」

11日目(今日)はスコアの更新はなく、少し停滞し始めています。e-typingでスコア400を出すことができたら、手元動画を撮ってみる予定です。ホームポジションと親指しか使っていないので、面白い絵面になるのではと思っています。

音ゲー風タイピングゲームを作った(プロトタイプ)

最初にこの入力方式を思いついたとき、一列だけを使うのであれば音ゲーっぽく見せられるのでは?と思いついたので、作ってみました。

音ゲー風タイピングゲームのプロトタイプ

鉄馬 on X: "プロトタイプを公開しました!↓からプレイできます。 よかったら遊んでみてください。 Windowsで動作確認できていないので、動かなかったら教えていただけると助かります。" / X

譜面は10レーンあり、それぞれホームポジションのキーに対応しています。ノーツの色はレイヤー切り替えを表しており、無シフトが黄色、左シフトが赤、右シフトが青です。

作ってから気づいたのは、別にこの配列ではなく普通のローマ字入力でも、譜面という形式は有効だということです。なぜなら、ノーツを黄色が中段、赤が上段、青が下段を表していると読めばよいからです。つまり、譜面はキーガイドの一種だと言うことができます。

一般的なキーガイドでは、キーボードを表示し、次の文字がある場所をハイライトします。譜面がキーガイドと違う部分は、列の情報を色に圧縮しているので、次に打つキーだけでなく、次の次の…キーもわかるようになっていることです。

この配列と譜面の可能性について

この入力方式や譜面には大きな可能性があるのではないかと思っています。具体的には、次のような問いがあります。

  • シフトを使ったホームポジションのみの入力方式の、パフォーマンスの限界はどれくらいか
  • QWERTYと比較して、習得コスト、実用性、使いやすさなどはどうか
  • この入力方式における最適なキー配列は何で、どうやって導出できるか
  • 音ゲーとタイピングの実力帯の比較できるようにすることは可能か
  • 譜面によるキーガイドに慣れれば、新しい配列を試しやすくなったり、別の配列もすぐ使えるようになるのではないか
  • この配列を使った自作キーボードを作ってみたらどのようなものになるか

作ったタイピングゲームを拡張しながら、これらの問いを解くための環境を作っていきます。タイピングゲームの構想については、また今度書きます。

自作キーボードの配列について

自作キーボードについては、↓で少し考えてみました。

鉄馬 on X: "図を作ってみた!アルファベット・数字・記号が合わせて68個だったので、2行x12列x3レイヤーにしたらちょうどいい感じに。アルファベットの配列を考えたときはどこまで実用性があるのか未知数だったけど、多少の不便はあるものの使えそうな気はしている。 / X

画像はKeyboard Layout Editorで作りました。楽しくなって色もつけちゃった。