awk で sl

Real UNIX MAGAZINE Day の中で歌代さんが sl の話をしてくださったのと、awk が結構活躍していた時代の話をしてくださったので、無謀にも awk で sl を書いてみた。sl に関しては、http://log.utashiro.com/pub/2007/04/sl_2eae.html を見つつ、再現してみた。
awk の printf() 関数を使っているので、curse を使った sl のようにスムーズでもないし、以前作った お題5:行列の回転 で作った plot() 関数を流用したため、どうしても遅くなってしまったり、スクリーンの行数と高さを取得できないので、いろいろと大問題はあるが、それなりに動いてくれるのではないだろうか? (苦笑)

#! /usr/bin/gawk -f
# sl.awk - draw SL on your screen
#   input:  none
#   output: draw SL on your screen

BEGIN {

    # SL design
    sl[1] = "     o     ";
    sl[2] = "    o      ";
    sl[3] = "   o       ";
    sl[4] = "   --  ----";
    sl[5] = "   ||  |OO|";
    sl[6] = "  -  --|  |";
    sl[7] = " |        |";
    sl[8] = "/-O=O O=O--";

    # settings
    width  = 80;
    height = 8;
    speed  = 5;
    clear_com = "/usr/bin/clear";

    # store into another array
    for (i in sl) {
        for (j = 1; j <= length(sl[i]); j++) {
            a_sl[j + width - length(sl[i]), i] = substr(sl[i], j, 1);
        }
        n_sl++;
    }

    # plot SL and clear
    for (k = 1; k <= (width - length(sl[i])) / speed;k++) {
        for (i = 1; i <= width; i++) {
            for (j = 1; j <= n_sl; j++) {
                a_sl[i, j] = a_sl[i + speed, j];
            }
        }
        plot(a_sl);
        system(clear_com);
    }
}

# plot - plot the array
#   input:  array name
#   output: print on your screen
function plot(arr,    x_size, y_size, i, j, k, len, str) {
    if (x_size == "") {x_size = width}
    if (y_size == "") {y_size = height}
    for (j = 1; j <= y_size; j++) {
        for (i = 1; i <= x_size; i++) {
            if (arr[i, j] == "") {
                arr[i, j] = " ";
            } else {
                len = length(arr[i, j]);
                str = arr[i, j];
                for (k = 1; k <= len; k++) {
                    arr[i + k - 1, j] = substr(str, k, 1);
                }
            }
            line = sprintf("%s%s", line, arr[i, j]);
        }
        print line;
        line = "";
    }
}

使い方は、

$ awk -f sl.awk

とします。