Other short programming examples I wrote


An implementation of the popular "Four in a row" game in GNU AWK.
Raffi asked me for a reference implementation for board-game AIs like for chess programs... so here it is. (Almost the same thing written in plain C can be found here.)
#!/usr/bin/gawk -f

# Copyright (C) 2004 Clifford Wolf <clifford@clifford.at>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. A copy of the GNU General Public
# License can be found at COPYING.

function print_board( \
        x, y)
{
        print "\n\n ";
        for (x=1; x<=size; x++)
                print "   " x;
        print "\n";
        for (y=size; y>0; y--) {
                print y;
                for (x=1; x<=size; x++)
                        print " | " board[x,y];
                print " |\n  ";
                for (x=1; x<=size; x++)
                        print "+---";
                print "+\n";
        }
        print "\n";
}

function calc_line(x1, y1, x2, y2, x3, y3, x4, y4, checkpos,
                points)
{
        if ( x1<1 || x1>size ) return 0;
        if ( y1<1 || y1>size ) return 0;
        if ( x4<1 || x4>size ) return 0;
        if ( y4<1 || y4>size ) return 0;
        points = 0;

        if ( board[x1,y1] != "O" &&
             board[x2,y2] != "O" &&
             board[x3,y3] != "O" &&
             board[x4,y4] != "O" ) {
                j = 0;
                if ( board[x1,y1] == "X" ) j++;
                if ( board[x2,y2] == "X" ) j++;
                if ( board[x3,y3] == "X" ) j++;
                if ( board[x4,y4] == "X" ) j++;
                if ( j == 2 ) points += 10;
                if ( j == 3 ) points += 20;
                if ( j == 4 ) points += 100000000;
                if ( j == 4 && checkpos )
                        print "4 in a row: " x1 "," y1 " " x2 "," y2 " " \
                                x3 "," y3 " " x4 "," y4 "\n";
        }
        if ( board[x1,y1] != "X" &&
             board[x2,y2] != "X" &&
             board[x3,y3] != "X" &&
             board[x4,y4] != "X" ) {
                j = 0;
                if ( board[x1,y1] == "O" ) j++;
                if ( board[x2,y2] == "O" ) j++;
                if ( board[x3,y3] == "O" ) j++;
                if ( board[x4,y4] == "O" ) j++;
                if ( j == 2 ) points -= 10;
                if ( j == 3 ) points -= 20;
                if ( j == 4 ) points -= 100000000;
                if ( j == 4 && checkpos )
                        print "4 in a row: " x1 "," y1 " " x2 "," y2 " " \
                                x3 "," y3 " " x4 "," y4 "\n";
        }

        return points;
}

function calc_situation(checkpos, xp, yp,
                i, x, y, points)
{
        points=0;
        if ( checkpos ) {
                for (x=4; x<=size; x++)
                for (y=4; y<=size; y++) {
                        points += calc_line(x, y, x-1, y-1,
                                        x-2, y-2, x-3, y-3, 1);
                        points += calc_line(x-3, y, x-2, y-1,
                                        x-1, y-2, x, y-3, 1);
                }
                for (x=4; x<=size; x++)
                for (y=1; y<=size; y++) {
                        points += calc_line(x, y, x-1, y, x-2, y, x-3, y, 1);
                        points += calc_line(y, x, y, x-1, y, x-2, y, x-3, 1);
                }
        } else {
                for (i=0; i<4; i++) {
                        points += calc_line(xp+i, yp+i, xp+i-1, yp+i-1,
                                        xp+i-2, yp+i-2, xp+i-3, yp+i-3, 0);
                        points += calc_line(xp-i, yp+i, xp-i+1, yp+i-1,
                                        xp-i+2, yp+i-2, xp-i+3, yp+i-3, 0);
                        points += calc_line(xp+i, yp, xp+i-1, yp,
                                        xp+i-2, yp, xp+i-3, yp, 0);
                        points += calc_line(xp, yp+i, xp, yp+i-1,
                                        xp, yp+i-2, xp, yp+i-3, 0);
                }
        }
        return points;
}

function comp_move(xo, recur,
        bnr, bvl, x, y, vl)
{
        bnr = bvl = -1;
        for (x=1; x<=size; x++)
                for (y=1; y<=size; y++)
                        if ( board[x,y] == " " ) {
                                vl = -calc_situation(0, x, y);
                                board[x,y] = xo;
                                vl += calc_situation(0, x, y);
                                if ( vl > -10000000 && vl < 10000000 &&
                                     recur < recursion_max )
                                        vl += comp_move(xo == "O" ? "X" : "O",
                                                       recur + 1);
                                if ( bnr == -1 || 
                                     (xo == "X" && bvl < vl) ||
                                     (xo == "O" && bvl > vl) ) {
                                        bnr=x;
                                        bvl=vl;
                                }
                                board[x,y] = " ";
                                break;
                        }
        if ( recur == 0 )
                for (y=1; y<=size; y++)
                        if ( board[bnr,y] == " " ) {
                                board[bnr,y] = xo;
                                break;
                        }
        return bvl;
}

function checkpos( \
                val, free, x, y)
{
        val = calc_situation(1, 0, 0);
        if ( val < -10000000 ) {
                print "\n!!! Player O won !!!\n\n";
                exit 0;
        }
        if ( val > +10000000 ) {
                print "\n!!! Player X won !!!\n\n";
                exit 0;
        }
        free=0;
        for (x=1; x<=size; x++)
                if ( board[x, size] == " " ) free=1;
        if (!free) {
                print "\n!!! Nobody won !!!\n\n";
                exit 0;
        }
        return val;
}

BEGIN {
        ORS="";
        size = 8;
        demo_mode = 0;
        recursion_max = 3;
        for (x=1; x<=size; x++)
        for (y=1; y<=size; y++)
                board[x,y] = " ";
        print_board();
        if ( demo_mode )
                while ( 1 ) {
                        comp_move("X", 0);
                        print_board();
                        checkpos();
                        comp_move("O", 0);
                        print_board();
                        checkpos();
                }
        print "Enter column number> ";
        fflush();
}

/^[0-9]$/ {
        domove=0;
        for (y=1; y<=size; y++)
                if ( board[$1,y] == " " ) {
                        board[$1,y] = "X";
                        domove = 1;
                        break;
                }
        print_board();
        if ( domove ) {
                checkpos();
                comp_move("O", 0);
                print_board();
                checkpos();
        }
}

! /^[0-9]$/ {
        print_board();
}

{
        print "Enter column number> ";
        fflush();
}

(
download)


An ASCII-Art to Obfuscated-C translator in Brainf*ck
The following Brainf*ck program reads an ascii art only containing the characters / \ _ | ' ' and \n from input and outputs an obfuscated c-program which prints the ascii art out.

I didn't write the brainf*ck code manually, instead I wrote this perl program to do the job for me.
>>+++[<+++++[<+++++++>-]>-]<<.>>>+++++[<+++++++++++[<++>-]>-]<<.>++++>>++++
[<++++[<+++++++>-]>-]<<.>++>+++++[<++++++>-]<.>+>>++++[<+++++++++[<+++>-]>-
]<<.>+>>++++[<++++[<++++++>-]>-]<<.<<<<<.>.>>>>>+>+++++++++++++[<+++>-]<.>+
+>+++++++++++++[<+++>-]<.>++>+++++++++++[<+++++++++++>-]<.>>+++++++++[<++++
+++++++>-]<.>++>+++++++++++++++++[<++++++>-]<.<<<<<.>>>>>>++>>++++[<++++[<+
++++++>-]>-]<<.>>+++++++[<++++++>-]<.<<<<<<<.>>>>>>>>+>>++++[<+++++[<+++>-]
>-]<<.>+>+++++++++++[<+++>-]<.>+[[-]>,[>+>[-]+>+<<<-]>>[[-]>+[<[-]+>-]<[<<<
+>>>[-]]]>[-]<<[>+>+<<-]>[<+>-]+>----------[<[-]>[-]]<[-<<+>>]<[>+>+<<-]>[<
+>-]+>-->+++++[<------>-]<[<[-]>[-]]<[-<<++>>]<[>+>+<<-]>[<+>-]+>-->+++++++
++[<----->-]<[<[-]>[-]]<[-<<+++>>]<[>+>+<<-]>[<+>-]+>>+++++[<--------------
----->-]<[<[-]>[-]]<[-<<++++>>]<[>+>+<<-]>[<+>-]+>->+++++++[<------------->
-]<[<[-]>[-]]<[-<<+++++>>]<[>+>+<<-]>[<+>-]+>--->+++++++++++[<----------->-
]<[<[-]>[-]]<[-<<++++++>>]<[-]>[-],[>+>+<<-]>[<+>-]+>----------[<[-]>[-]]<[
-<<+>>]<[>+>+<<-]>[<+>-]+>-->+++++[<------>-]<[<[-]>[-]]<[-<<++>>]<[>+>+<<-
]>[<+>-]+>-->+++++++++[<----->-]<[<[-]>[-]]<[-<<+++>>]<[>+>+<<-]>[<+>-]+>>+
++++[<------------------->-]<[<[-]>[-]]<[-<<++++>>]<[>+>+<<-]>[<+>-]+>->+++
++++[<------------->-]<[<[-]>[-]]<[-<<+++++>>]<[>+>+<<-]>[<+>-]+>--->++++++
+++++[<----------->-]<[<[-]>[-]]<[-<<++++++>>]<[-]<[->+<]>[-<+++++++>]<[-<+
>]<>+++++[<+++++++>-]<<[>.>+<<[-]]>[-]>[-<<+>>]<<]<.>>>>>++++[<+++++++++++>
-]<.<<<<<<.>>>>>>>>>+++++++[<+++++++[<++>-]>-]<<.<<<<<<.>.>>>>>>>+++++++++[
<+++++++>-]<.>+>+++++++[<+++++++++++++>-]<.<<<<<<<<<<<<<<<<<<<<.>>.>>>>>>>>
>>>>>>>>>>>++>+++++++++[<+++++>-]<.>>+++++[<+++++++++++++++++++>-]<.<<..>>>
+++>+++++++++++[<+++++++++++>-]<.<<<<<<<<<<.>>>>>>>>>>>++++>+++++[<++++++++
+++>-]<.>>+++++++[<+++++++++++++++++>-]<.<<<<<<<<<<<<<<<<.<<<<<<<<<<.>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>++++[<+++++++++[<+++>-]>-]<<.>+>>++++[<+++++[<+++++>
-]>-]<<.<<<<<<<<<<<<<<<<<<<<<<.>>>>>>.<<<<<<<.>>.>.>>>>>>>>>>>>>>>>>>>>>>>+
+++[<++++[<+++++++>-]>-]<<.>>+++++++++[<+++++++++++++>-]<.<<<<<<<<<<<<<<<<<
<<<<<<<<<<<.>>>>>>>.>.<<<<<.>>>>>>.<<<<<.>>>>>>>>>>>>>.>>>>>>>>>>>>>+++++++
[<+++++++++++++>-]<.<<<<<<<<<<<<<<<<<<<<<<<<<.>>>>>>.<<<<<<<.>>>>>>>>>>>>>>
>>>>>>>>>>>>>>+++++++++[<+++++>-]<.>>+++++++++++++[<+++>-]<.>>+++++[<++++++
+>-]<.<.<<<<<<<<<<<<<<<<<<<<<<<<<<.>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>++++[<++++
+++++>-]<.>>+++++[<+++++++++++>-]<.>++>+++++++[<+++++++++++++>-]<.<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<.>>>>>>>>>>>>>>>>>>.>>>>.>.<<<<<<<<<<<<<<<<<<<<<<<<<<<
<.>>>>>>>.>.<<<<<.>>>>>>.<<<<<.>>>>>>>>>>>>>.>>>>>>>>>>>>.<<<<<<<<<<<<<<<<<
<<<<<<<<.>>>>>>.<<<<<<.<.>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+++++++[<++++++
>-]<..<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<.>>>>>>>>>>>>>>>>>>>>>>>>>.>>>>>>>++>+
++++++[<+++++++>-]<.>+>++++[<+++++++++++++>-]<.<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<.>>>>>>>>>>>>>>>.>>>>>>>>>>>>>>.>.<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<.>>>>>
>>>>>>>>>>>>>.>>>>>>>>>>>>>>>>>>+++++[<+++++[<+++++>-]>-]<<.<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<.>>>>>>>>>>>>>>>>>.<<<<<<<<<<<<<<<<<<<<<<<<<<.>>>>>>>>>>>>>>
>>>>>>>>>>>>>>.<<<<<<<<<<<<<<<<<<<.<<<<<<<<<<.>>.>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>+++>+++++++++[<+++++>-]<.<<<<<<<<<<<<<<<<<.>>>>>>>>>>>>>>>>.>>
++++++++++.
(
download)