Pages

19 March 2013

fun with a basic algorithm

On Twitter Ed announced that he was playing around with a BASIC program that ran on the venerable Commodore 64. I myself am not a professional programmer, but I've taken several programming courses and have played with code from time to time. I fondly remember programming instructions in BASIC or Pascal on the school computers and was always a bit saddened that my home didn't have one for our personal use.

Naturally, Ed posting about 10 PRINT made me curious. Since I run OpenBSD on my workstation I don't have a native version of BASIC, but I do have a C compiler in the form of GCC. So I set out to port "10 PRINT" in C.

10 PRINT

The Code

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

10 PRINT Output - Frodo C64 Emulator

My First Porting Attempts

The variant of UNIX that I doesn't have the PETSCII character set that the Commodore 64 uses in the 10 PRINT program. As a result my first attempts used the slash "/" and the backslash "\" characters from the standard ASCII library.

maze.c


/* auto maze generator */

#include <stdio.h>
#include <stdlib.h>

/* print to screen the backslash or forward
 * slash depending if the value of i is
 * odd or even. */

int main (int argc, char *argv[])
{
        do {
                int i = random();

                if ( i%2 == 0 )
                        printf ("\\");
                else
                        printf ("/");

        } while ( 1 );

        return 0;
}

maze1.c


/* auto maze generator, mk1 */

#include <stdio.h>
#include <stdlib.h>

/* determine if the number passed is
 * odd or even and return result. */

int odd_even (number)
        int number;
{
        if ( number % 2 == 0)
                return 0;
        else
                return 1;
}

/* print the forward slash or backslash
 * depending on returned result. */

int main (int argc, char *argv[])
{
        do {
                int i = random();

                if ( odd_even(i) == 0 )
                        printf ("\\");
                else
                        printf ("/");

        } while ( 1 );

        return 0;
}

maze2.c


/* auto maze generator, mk3 */

#include <stdio.h>
#include <stdlib.h>

/* print to screen the backslash or forward
 * slash depending if the value of i is
 * odd or even. */

int main (int argc, char *argv[]){do {int i = random();if (i%2==0) printf("\\");else printf("/");}while(1);return 0;}

Output of First Attempts

My Following Attempts

I wasn't satisfied with the use of slash and back slash to build the output. While using slash and backslash approximated the output of 10 PRINT somewhat, it was obvious that the approximation was lacking. Fortunately, it turns out that Unicode has a solution that more approximates the diagonal lines used in PETSCII. The right leaning line has the Unicode symbol

0x2571
and the left leaning line has the symbol
0x2572
in C. So, using those symbols I modified my code accordingly. I also used an terminal emulator that was capable of rendering the Unicode symbols I was using to view my output, in this case Gnome Terminal.

maze4.c


/* auto maze generator, mk4 */

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>

/* print the forward slash or backslash
 * depending on returned result. */

int main (int argc, char *argv[])
{
        char *locale;
        locale = setlocale (LC_CTYPE, "en_US.UTF-8");
        int i;

        while (1) {
                wprintf (L"%lc", (i = 2571.5 + arc4random_uniform(2), i == 2571) ? L'\x2571' : L'\x2572');
        }

        printf ("\n");

        return 0;
}

maze5.c


/* auto maze generator, mk5 */

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>

/* Adds a value 0 < x < 1 to passed float
 * value and return an integer. */

int find_value (given)
        float given;
{
        given = given + arc4random_uniform(2);
        return (given);
}

/* print the forward slash or backslash
 * depending on returned result. */

int main (int argc, char *argv[])
{
        char *locale;
        locale = setlocale (LC_CTYPE, "en_US.UTF-8");
        int i;

        while (1) {
                wprintf (L"%lc", (i = find_value(2571.5), i == 2571) ? L'\x2571' : L'\x2572');
        }

        printf ("\n");

        return 0;
}

Output of Following Attempts

Thoughts

I find the original algorithm in C64 BASIC interesting for a couple of reasons.

  1. The entire script is one line.
  2. The script uses a 'goto' statement.
  3. The script takes advantage of how characters are defined in PETSCII

If I were to do this properly in C I would either have to have a similar set of characters that I could call on, or I would have to call on C's graphical abilities and define line segments for various values in the algorithm.

The fact that there are two opposing slash characters in Unicode that are numerically adjacent to each other is fortuitous. I don't know if the spec for Unicode came before 10 PRINT and PETSCII or after, but I suspect that if it's the latter then perhaps the designers were influenced by 10 PRINT? This is something that I may have to look into a bit, just to satisfy my curiosity.

No comments:

Post a Comment