QRコードを人力解読するゲームの作成

# はじめに 
世の中には[GitHub-Guessr](https://github-guessr.vercel.app/)というゲームが存在します。ここからQRコードを当てる変人向けのゲームを思いついたので作成してみました。

制作物

https://yui10.github.io/QRCode-Reading/

ソースコード

https://github.com/yui10/QRCode-Reading

# QRコードの生成
QRコードの生成は[jquery-qrcode.js](https://github.com/jeromeetienne/jquery-qrcode)を使用しました。使い方はQiitaの記事[^1]を見ながらすぐに出来上がりました。

なお、QRコードで日本語を使用する場合はShift-JIS[^2]にする必要があります。[encoding.js(パッケージ名:encoding-japanese)](https://github.com/polygonplanet/encoding.js)を使い文字コードを変換します。

以上を元にしてコードにすると以下の通りです。
```javascript
    text = Encoding.convert(text, 'sjis');
    // QRコードの描画
    UI.$QRCode.qrcode({
      text: text,
      render: "table",
      width: size,
      height: size
    });
```

# QRコードへの細工
スマホで読み取れてしまっては意味がないので読み取れないように細工します。
QRコードの仕組み上、あの特徴的な見た目の**ファインダパターン**が読み取れないと認識することが出来ません。
今回使用したライブラリはtableとして出力もできるのでこれを配列として読み取り、塗りつぶをしたいと思います。

```javascript
  //読み取り
  function loadTable() {
    let table = [];
    UI.$QRCode.find('tr').each(function () {
      let row = [];
      $(this).children('td').each(function () {
        row.push($(this).css("background-color"));
      });
      table.push(row);
    });
    return table;
  }

  //塗りつぶし
  function fillFinderPattern(table, fill_item) {
    fillSevenField = (table, start_x, start_y) => {
      for (let y = 0; y < 8; y++) {
        for (let x = 0; x < 8; x++)
          table[start_y + y][start_x + x] = fill_item;
      }
      return table;
    };
    table = fillSevenField(table, 0, 0);//左上
    table = fillSevenField(table, 0, table.length - 8);//左下
    table = fillSevenField(table, table[0].length - 8, 0);//右上
    return table;
  }
  
  let QRCode_table = loadTable();
  QRCode_table = fillFinderPattern(QRCode_table, "rgb(68, 147, 249)");
  QRCode_table.forEach(function (row, i) {
      row.forEach(function (color, j) {
        UI.$QRCode.find('tr').eq(i).children('td').eq(j).css("background-color", color);
      });
  });
```
これで読み取れないQRコードができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519793/ccd35e42-0346-1c5f-afcf-4dccdffc1601.png)


# 人に優しい見た目にする
今のままでもいいかもしれませんが、マスク処理がされていることや色がなく見にくいなど、人に優しくない見た目をしているので改善をしたいと思います。
既にQRコードを人力解読している人がいるのでその方の記事[^3][^4]を参考します。具体的にはタイミングパターン、フォーマット情報、バージョン情報の部分を色付けし、マスク処理の解除をします。
コードは長くなるのでここでは省略します。
出来上がったものは以下の様になりました。
マスク処理が解除されているので解読はギリギリ人力でもできるレベルになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519793/0b31034c-01ce-a647-d882-79fba9be51cf.png)

# 成果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519793/55e46f46-d049-b9e0-05f0-8a978a328edf.png)

出来上がってこの様な形になりました。
選択肢で出てくるデータは国の名前がまとめられた[jsonデータ](https://github.com/stefangabos/world_countries)を使用しました。
なお、現時点では最初の1,2文字読み取るだけで推測出来てしまうので、数分で解けると思います。改善案としては、答えと選択肢の内容が近くなるようにするか、選択型ではなくテキスト入力させるなどの対応で、難易度が上げられると思います。


# さいごに
このゲームをする人は~~変人~~玄人しかいないため、やはり世間一般的にクソアプリと呼ばれるものが出来上がりました。誰もプレイしないかもしれないですが、QRコードについて少しは理解ができたので、取り組んだ意味はあったと思います。

要望、バグ報告などはGitHubのissueまで連絡ください。
最後まで読んで頂きありがとうございます。


[^1]:[QRコードをJavaScriptで作る方法](https://qiita.com/risuney/items/051572cf8b2398d6facf)

[^2]:[QRコードドットコム｜株式会社デンソーウェーブ](https://www.qrcode.com/)

[^3]:[QRコードを自力で読み取ってみる](https://note.com/kaido_729/n/n68655cea84d8)

[^4]:[QRコードを人力で読み取る](https://qiita.com/amanao/items/b7c54a3c73a8301b2412)