/*********************************************************//**
* Author: migf1
* from Book: C Programming, A Modern Approach (2nd edition)
* Chapter: 8 (Arrays)
* Programming project: 9 (page 179) - Better implementation
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NROWS 10 /* table height in rows */
#define NCOLS 10 /* table width in cols */
#define NDIRS 4 /* # next-mv directions */
//enum Dir { UP=0, DN, LF, RT, NDIRS }; /* allowed mv directions*/
#define EMPTY '.' /* empty cells' content */
#define USED "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* used cells' contents */
#define ISEMPTY(pos, tab) ( EMPTY == (tab)[ (pos) ] ) /* is tab[pos] empty? */
#define ROW(pos) ( (pos) / NCOLS ) /* calc row-index of pos*/
#define COL(pos) ( (pos) % NCOLS ) /* calc col-index of pos*/
#define POSUP(pos) ( (pos) - NCOLS ) /* calc pos minus 1 row */
#define POSDN(pos) ( (pos) + NCOLS ) /* calc pos plus 1 row */
#define POSLF(pos) ( (pos) - 1 ) /* calc pos minus 1 col */
#define POSRT(pos) ( (pos) + 1 ) /* calc pos plus 1 col */
#define myMIN(x,y) ( (x) < (y) ? (x) : (y) )
/*********************************************************//**
* Store into avail[] all those positions adjacent to pos which are available to
* be selected for the next move.
* Return the count of the available posistions found.
************************************************************/
int avail_count( const int pos, const char tab[], int avail[ NDIRS ] )
{
int temp = 0;
int navail = 0;
/* is row-up'ed pos available? */
if ( ROW(pos) > 0 && ISEMPTY( (temp=POSUP(pos)), tab ) )
avail[ navail++ ] = temp;
/* is row-dn'ed pos available? */
if ( ROW(pos) < NROWS-1 && ISEMPTY( (temp=POSDN(pos)), tab ) )
avail[ navail++ ] = temp;
/* is col-lf'ed pos available? */
if ( COL(pos) > 0 && ISEMPTY( (temp=POSLF(pos)), tab ) )
avail[ navail++ ] = temp;
/* is col-rt'ed pos available? */
if ( COL(pos) < NCOLS-1 && ISEMPTY( (temp=POSRT(pos)), tab ) )
avail[ navail++ ] = temp;
return navail;
}
/*********************************************************//**
* Print the contents of the board.
************************************************************/
void tab_print( const char tab[] )
{
for (int i=0; i < NROWS * NCOLS; i++)
{
if ( i != 0 && i % NCOLS == 0 )
}
}
/*********************************************************//**
*
************************************************************/
int main( void )
{
/* total # of moves allowed */
const int NMOVES
= myMIN
( NROWS
*NCOLS
, (int)(strlen(USED
) - 1) ); int pos = 0, imove = 0; /* current pos & moves counter */
char tab[ NROWS * NCOLS ]; /* our un-initialized board */
int avail[ NDIRS ] = {-1,-1,-1,-1}; /* available neighbor positions */
srand( (unsigned)time(NULL
) ); /* init pseudo-random seed */ memset( tab
, EMPTY
, sizeof(tab
) ); /* init table with dots */
tab[0] = USED[0]; /* start with filled 1st pos */
while ( imove < NMOVES )
{
int navail = avail_count(pos, tab, avail);
if ( 0 == navail )
break;
pos
= avail
[ rand() % navail
]; tab[ pos ] = USED[ ++imove ];
}
tab_print( tab );
}