Scratcher's AtCoder の紹介

※この記事は、[AtCoder関連サービス Advent Calendar 2018](https://adventar.org/calendars/2932) の 12日目の記事です。

こんにちは、yos1up です。好きなプログラミング言語は、C++ と Python3 と[スーパーマリオメーカー](https://www.youtube.com/watch?v=hd0EtsTUbmg)です。
今日は、プログラミング言語 Scratch (Scratch 3.0)で AtCoder に参加できるようになる Chrome 拡張 [Scratcher's AtCoder](https://chrome.google.com/webstore/detail/scratchers-atcoder/hackndbjgkehhjinjjoldifbhnfddklh?hl=ja) の紹介をしたいと思います。

# Get Started
とりあえず使ってみたい！という方は、[Scratcher's AtCoder のウェブストアのページ](https://chrome.google.com/webstore/detail/scratchers-atcoder/hackndbjgkehhjinjjoldifbhnfddklh?hl=ja) から早速インストールしてみてください！同ページに使い方も載せてあります！

ここから先のこの記事では、Scratcher's AtCoder ができあがるまでの経緯について記しておきます。

# きっかけ

競技プログラミングは楽しいですよね！自分は競プロを始めたのは18歳くらいからですが、最近はもっと若い頃から始めていてすごいレベルに到達している人もいるようで、すごいですよね！最近は小学生やそれ以下の年齢くらいでもプログラミングを楽しんでいる子どもが結構いるみたいなので、その辺りの層にも広まればいいですよね！もし身近にプログラミングが好きな子どもがいれば、競プロを勧めてみたくなります……が、ここで問題が生じます。

**子どもたちが使っているプログラミング言語に競プロ側が対応していない！**

試しに「子ども　プログラミング」あたりで画像検索をすると、多く目につくのが [Scratch](https://scratch.mit.edu/) です。Scratch は、GUI操作で画面上にブロックを並べていくことでアルゴリズムを組み立てていけるプログラミング言語です。UIの説明書きは全て日本語で書かれており、またキーボード入力も最低限で済むようになっており、子どもたちにはとてもとっつきやすくなっています[^1]。しかし、Scratch を公式に利用可能な競プロのサービスは現時点(2018年12月時点)では存在しません。

# Scratch を使ってみた

Scratch の存在は割と前から知っていましたが、使ったことは一度もなかったので、まずは実際に使ってみました。
開発環境のインストールなどは不要で、[このページ](https://scratch.mit.edu/projects/editor/)に行くだけでとりあえずプログラムを作って動かすことができます。書き捨てるだけならアカウント作成も不要です。

手始めに、[AtCoder Beginners Selection](https://beta.atcoder.jp/contests/abs) (ABS) の 10 問を [Scratch で解いてみました](https://scratch.mit.edu/studios/5346476/)。例えば、ABS の 3 問目の [ABC081B - Shift only](https://beta.atcoder.jp/contests/abs/tasks/abc081_b) は、C++での解答例は

```c++
#include <bits/stdc++.h>
using namespace std;
int a[200];
int main(){
    int n; cin >> n;
    for(int i=0;i<n;i++) cin >> a[i];
    for(int i=0;;i++){
        for(int j=0;j<n;j++){
            if (a[j] % 2 == 1){
                cout << i << endl;
                return 0;
            }
            a[j] /= 2;
        }
    }
}
```
のような感じですが、Scratch だと下のようになります[^10]。

<img width="421" alt="スクリーンショット 2018-12-13 22.56.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/145122/c9d5bfe6-67bf-afc9-70f3-2bce9419adbe.png" >

実際に[このページ](https://scratch.mit.edu/projects/245114038/#editor)で動かすこともできます。Scratch では標準入出力は使えないので、標準入力の代わりに「〜と聞いて待つ」ブロック（一つの値を受け付けるための文字列入力欄が現れます[^11]）、標準出力の代わりに「〜と言う」ブロック（指定された文字列をネコがしゃべります[^4]）を使っています。

ABS に登場する C 問題あたりまでの問題の多くは、問題中に登場する変数の個数が比較的少なく、要求されるアルゴリズムもシンプルなものであることが多いので、Scratch でも楽に実装できそうなことがわかりました[^3]。

# Scratch のプロジェクトを C++ のコードに変換

さて、Scratch で AtCoder の問題がある程度解ける（解答を実装できる）ことはわかりましたが、これだけでは Scratch で AtCoder のコンテストに参加することはできません。コンテストに参加するためには、**AtCoderでサポートされている言語で書かれたプログラムを提出**しなければなりません。そこで、Scratch のプログラムを C++ に変換することを考えました[^5]。
幸いなことに Scratch のプロジェクトはローカルファイルに書き出すことができるようになっているので、その中身をパースする[^8]ことで、煮るなり焼くなりすることができます。こうして、[ScratchプロジェクトをC++コードに変換する JavaScript のコード](https://github.com/yos1up/scratch2cpp/blob/master/web/crx/sb2_to_cpp.js)が完成しました[^6][^7]。

# UI

これで技術的には Scratcher[^9] が AtCoder のコンテストに参加できるようになりましたが、「Scratch でコーディング→プロジェクトファイルをC++に変換→提出」の手続きが煩雑なので、なるべくそれが自然な流れでできるような UI を用意したいなあと思いました。結果、このような感じに落ち着きました。

<img width="899" alt="スクリーンショット 2018-12-13 23.23.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/145122/340bf469-fcaa-6005-9368-f6579f28ff21.png">

個人的には、「しれっとボタンが増えている」感じが好きです。


# 今後

「プログラミング？ Scratch ならできるよ！」という人に、競プロを始めるきっかけを与えていくことができれば、嬉しい限りです。



[^1]: Scratch は多言語に対応していますが、「日本語」と「にほんご」が別言語として用意されていて、後者を選ぶと全てのUIの日本語がひらがなカタカナオンリーになり、子どもたち向けにローカライズできていて流石だなあと思いました。（それを見習って(?) Scratcher's AtCoder も UI の日本語は全てひらがなカタカナにしました）


[^3]: 例えば配列は Scratch では「数値or文字列or真偽値を各要素にもつ1次元配列」しかサポートされておらず、多次元配列を扱いたい場合は、何らかの方法でエミュレートする必要があります

[^4]: 正確にはフキダシが出現します

[^5]: どの言語に変換するかは少し迷いましたが「Scratch だけでもレッドコーダーを目指せるようになっていてほしい」という気持ちからコンパイラ言語にはしようと思いました（Python等のインタプリタ言語では速度が厳しい）。あとは競プロ関連の情報はやはり C++ で書かれているものが多いので Scratch から C++ に移行しやすいようにと思い C++ にしました

[^6]: JavaScript なのは、一般にChrome 拡張は JavaScript で開発する必要があるためです

[^7]: Scratch には色々な種類のブロックが用意されていますが、今回 C++ に変換できるようにしたブロックは、競プロで使う必要が生じそうなものだけです

[^8]: 正確にはローカルファイル (.sb2) は zip 形式になっており、それを展開すると得られる json ファイルをパースする必要があります

[^9]: Scratch プログラマーのこと

[^10]: 画像は Scratch 2.0 のものです（Scratch 3.0 とほとんど同じですが）

[^11]: 例えば入力が `3 4 hoge 2` の場合，一回目の「〜と聞いて待つ」では「答え」変数に `3` が代入されます．二回目の「〜と聞いて待つ」では「答え」に `4` が代入されます．三回目には `hoge` ，四回目には `2` が代入されます