Analyzing a Grid of Random Stars

Ever since I was a little boy and coded my first nested loop, I’ve enjoyed messing with grids in C. I’ve done monthly calendars in grids, rotated grids, manipulated grids mathematically — all sorts of fun girddy stuff. But I’m not done yet.

Populating a grid randomly fascinates me. I look for patterns in the randomness. To sate this desire, I wrote the program below. It outputs a two-dimensional array randomly populated with asterisks.

2024_05_18-Lesson.c

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

#define ROWS 16
#define COLS ROWS*2
#define PROB 5

int main()
{
    char grid[ROWS][COLS];
    int row,col;

    /* seed the randomizer */
    srand( (unsigned)time(NULL) );

    /* fill the grid */
    for( row=0; row<ROWS; row++ )
    {
        for( col=0; col<COLS; col++ )
        {
            if( rand() % PROB )
                grid[row][col] = '.';
            else
                grid[row][col] = '*';
            putchar(grid[row][col]);
        }
        putchar('\n');
    }

    return 0;
}

Three defined constants set two aspects of the grid: its dimensions and the randomness of the asterisks. ROWS sets the number rows and COLS is set to twice the number of rows, which looks better on the standard text screen. PROB sets the probability of a character being an asterisk as opposed to the default period.

Nested for loops fill the grid. In the inner loop, an if statement bases its condition on the return value from the rand() function modulo constant PROB. For non-zero values (most of them), a period is set in the matrix. Otherwise, an asterisk is set. A putchar() function outputs the character set in the grid.

Here’s sample output:

...*.*......*...*........*...*..
................**...*...*..**..
.*.....*.*.....*...........*....
....**...........*..*...*......*
.......*..........*..**....*...*
.....*.*.........*......*....*..
*..............*..........*.*..*
.**.........*.........*..**..*.*
*....*........*....*.....*..*...
......**...**.....*..........*..
.....*......*.*..*..*.....*....*
**..*....*.*.....*......***....*
..............................*.
....*....*.......*..*....*..*...
*...........*.....*...*.....*..*
.*.......*...*.*......*.....**..

Adjusting the value of PROB increases or decreases the density of the asterisk characters. If I set PROB equal to 20, here is the output:

................*...............
.....................*..........
...........................*....
.................*......*.......
......................*.........
.......*........................
...............*................
......................*.........
*.............*.............*...
...........*....................
............*.......*...........
....*.....................*.....
................................
....*....................*..*...
............*...................
.*.............*......*.........

If I set it to two, you see this grid:

.*....**..*.*..*****.*..***....*
**...*.*....*.**.*.*.**.***...*.
*.*...*.*.*.**.*.*****..*.****.*
***..***...*.***.**...*.*.......
...*..*.*..**.*...***.*.*.*.*...
.***.*.*****.*.....**..*..*.*...
..**..*.**...*******...**.*.*.*.
**..**.***...**.**..****.*...**.
*****.*****.*****..**....*.**...
.*...**.*********..*.*.***..***.
*..*.....*..*..*.******.*.******
..*.***.****...**.**...**.**.*..
..*..**.*****.***.******.*...***
.**.***..*.....**.**.*..***.***.
*****....**.*..*...*.*..*..*....
.**....**..*.***..**.**.....*.*.

I think five is a good value. But going back to my point, what catches my eye in the grid are patterns. What I want to do with the grid is to find rectangles based on coordinates of the asterisks. For example:

.......*--**---------*--*--*---*
....*--*--*----*-*-**---*..|...|
*...|..|..**---------|--*..|...|
....|*-|*-||-----*-|||*.|..|...|
....||*|**||-----*-|*||*|*-|*--*
..***--*----*----*-*---*----*--*
..|.*-*|--||------**|**-|*-||*..
..|.||.|..*|-*---|-|*|||||.|||..
..|.||.*--*------------**|-|||*.
**|.|*-|---|-----|-|||*|||*||**.
..|.|*-|---*--*--*---|--*|-|||*.
..|.*--|---|-----*-||*--|--*|||.
..*-|*-|---|-*---|-|||-**||||||.
....|..*----*------*-*--*||||||.
....*------|-----*--*----|-*|*|.
....*------*------*------****-*.

Above you see output from the final rendition of this program. The program searches for a pair of asterisks that are in the same columns across two rows, which forms a rectangle. Once found, the program draws ASCII lines between the asterisks, setting them in the grid. Above, 79 rectangles are found in the grid. Each rectangle is marked, though you see a lot of overlap.

Over the next few Lessons, I will modify the base program to scan for, document, and show the various rectangles in the random grid. This task took several generations of coding to accomplish. Many times I’d start down one path, then realize a better way exists. I document all of that, failures and successes, to show you how the final program was concocted.

In next week’s Lesson, I convert the two-dimensional array into pointer notation so that it can be easily passed to various functions. It’s my assumption that perhaps some form of recursion is necessary to accomplish this task. I’ll explain how it works (or not) as the program progresses.

Leave a Reply