#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define INVALID -1
#define NROWS 11
#define NCOLS 11
#define NCELLS (NROWS * NCOLS)
enum ShipID { INVALID_ID=-1, WATER=0, NAYARXIDA=1, ANTITORPILIKO=2, NSHIPS };
enum ShipDir { INVALID_DIR=-1, HORZ=0, VERT=1, NDIRS };
#define VALID_ID( id ) ( (id) > INVALID_ID && (id) < NSHIPS )
#define VALID_DIR( dir ) ( (dir) > INVALID_DIR && (dir) < NDIRS )
#define VALID_POS( pos ) ( (pos) > -1 && (pos) < NCELLS )
typedef enum { FALSE=0, TRUE } Bool;
typedef struct Cell {
int shipId; /* ti periexei to keli (tipota, nero h kapoio ploio) */
Bool isbombed; /* einai h oxi xtyphmeno to keli ? */
} Cell;
typedef struct Ship {
enum ShipID id; /* typos ploioy */
int len; /* mhkos se kelia plegmatos */
int pos; /* thesh sto plegma */
enum ShipDir dir; /* prosanatolismos (HORZ h VERT) */
} Ship;
/* -------------------------------------------
*
* -------------------------------------------
*/
Bool grid_init( Cell grid[ NCELLS ] )
{
int n = 0;
if ( !grid )
return FALSE;
for (n=0; n < NCELLS; n++) {
grid[ n ].shipId = WATER;
grid[ n ].isbombed = FALSE;
}
return TRUE;
}
/* -------------------------------------------
*
* -------------------------------------------
*/
Bool grid_print( const Cell grid[ NCELLS ] )
{
int n = 0;
if ( !grid )
return FALSE;
for (n=0; n < NCELLS; n++)
{
if ( grid[ n ].shipId == WATER )
else if ( grid[ n ].shipId == NAYARXIDA )
else if ( grid[ n ].shipId == ANTITORPILIKO )
else
if ( n % NCOLS == NCOLS-1 )
}
return TRUE;
}
/* -------------------------------------------
*
* -------------------------------------------
*/
Bool ship_fits_ongrid( Ship *ship, Cell grid[ NCELLS ] )
{
int n, endpos = INVALID;
if ( !ship || !grid || !VALID_ID(ship->id) || !VALID_DIR(ship->dir) || !VALID_POS(ship->pos) )
return FALSE;
if ( ship->dir == HORZ )
{
endpos = ship->pos + ship->len - 1;
if ( ship->pos / NCOLS != endpos / NCOLS ) /* START & END not in same row*/
return FALSE;
for (n = ship->pos; n <= endpos; n++ )
if ( grid[ n ].shipId != WATER )
return FALSE;
}
else if ( ship->dir == VERT )
{
endpos = ship->pos + (ship->len-1) * NCOLS;
if ( endpos / NCOLS > NCOLS-1 ) /* END goes beyond last row */
return FALSE;
for (n=ship->pos; n <= endpos; n += NCOLS)
if ( grid[ n ].shipId != WATER )
return FALSE;
}
return TRUE;
}
/* -------------------------------------------
*
* -------------------------------------------
*/
Bool ship_put_ongrid( Ship *ship, Cell grid[ NCELLS ] )
{
int n, endpos = INVALID;
if ( !ship || !grid || !VALID_ID(ship->id) || !VALID_DIR(ship->dir) || !VALID_POS(ship->pos) )
return FALSE;
if ( ship->dir == HORZ )
{
endpos = ship->pos + ship->len - 1;
for (n = ship->pos; n <= endpos; n++ )
grid[ n ].shipId = ship->id;
}
else if ( ship->dir == VERT )
{
endpos = ship->pos + (ship->len-1) * NCOLS;
for (n=ship->pos; n <= endpos; n += NCOLS)
grid[ n ].shipId = ship->id;
}
return TRUE;
}
/* -------------------------------------------
*
* -------------------------------------------
*/
Bool ship_put_ongrid_randomly( Ship *ship, Cell grid[ NCELLS ] )
{
if ( !ship || !VALID_ID(ship->id) || !grid )
return FALSE;
do {
ship
->pos
= rand() % NCELLS
; ship
->dir
= rand() % NDIRS
; } while ( !ship_fits_ongrid( ship, grid ) );
ship_put_ongrid( ship, grid );
printf( "Ship %d was put at pos %d (%d,%d) with direction %d\n", ship->id, ship->pos, (ship->pos / NCOLS), (ship->pos % NCOLS), ship->dir );
return TRUE;
}
/* -------------------------------------------
*
* -------------------------------------------
*/
int main( void )
{
Cell grid[ NCELLS ]; /* to plegma mas (tha to arxikopoihsoyme argotera: game_init) */
Ship navarxida = { .id=NAYARXIDA, .len=5, .pos=INVALID, .dir=INVALID };
Ship antitorpiliko = { .id=ANTITORPILIKO, .len=4, .pos=INVALID, .dir=INVALID };
grid_init( grid );
ship_put_ongrid_randomly( &navarxida, grid );
ship_put_ongrid_randomly( &antitorpiliko, grid );
grid_print( grid );
return 0;
}