awk でテトリスみたいなゲームをつくろう! (嘘)

セキュリティ&プログラミングキャンプの資料に、上級者向けの章を追加しましたを見て JavaScript 界隈の楽しさが聞こえてくるので、awk でも作ろうかと思いましたが・・・ちょっと根性ありません。 実は awk でできたテトリスは既に存在しています。

が、しかし、こいつを見てどう思う。 読めませんよね。 もしも読めたら凄いのですが、実はこのスクリプトはある意味暗号化されています。 以下、少しネタばらしになりますので、一度自分でこいつと格闘してみてください。

さて、実は最後の system() 関数で復号化された一行野郎 (変数名 p) を実行しているわけですので、system() 関数の前に以下のような命令を挿入すると復号化されたものを見ることができます。

print p;exit;

それでもかなり長い一行野郎ですので、解読するのはしんどい作業です。 ここではあえて解読しませんが、夏休みの宿題としてはいかがでしょうか?

キー入力とタイムアウト

さて、リアルタイムゲームに必須な項目があります。

  • リターンなしでキーの入力を得る。
  • タイムアウト機能。

これらは共に awk には存在しませんし、Linux であっても簡便なコマンドすら用意されていません。 こいつを読み解いた人は分かると思いますが、echo と dd と stty を使っています。

ここでは練習用に簡単なスクリプトを用意しました。 'l' を押すと 'ls -al' の結果を返し、'a' を押すと 'awk' と表示し、'q' を押すと終了します。 それ以外では画面をクリアして、1 秒毎に時刻を表示します。

#! /usr/bin/gawk -f
# background.awk

BEGIN {

    clear_cmd = "echo -n '\033[H\033[2J'";
    get_key_cmd = "stty -icanon min 1 ; "\
                  "((while :; do echo '~'; sleep 1; done) &"\
                  "(while :; do echo `dd bs=1 count=1`; done)) 2> /dev/null";

    for (;;) {
        get_key_cmd | getline;

        if ($1 == "q") {
            close(cmd);
            exit 0;
        }

        if ($1 == "a") {
            print "awk";
        }

        if ($1 == "l") {
            system("ls -al");
        }

        if ($1 == "~") {
            system(clear_cmd);
            print strftime("%Y-%m-%d %H:%M:%S",systime());
        }
    }
}

Linux 以外の Unix 系 OS は考慮していませんので、動かない場合もあるかもしれませんが、使うコマンドは同じですのでオプションを変更してみてください。

さて、これで、鬼門であった「リアルタイムのキーの取得」と「タイムアウト」ができるようになりました。 時間があれば何かを作ってみたいと思いますが、awk でアクションゲームにチャレンジしてみてはいかがでしょうか。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png