/* Prova scritta del 14/10/99 -- Ambiente e Territorio */


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

#define LEN 25
#define R 10
#define C 10

struct elem {
	int x,y;
	struct elem *next;
};

typedef struct elem punto;

typedef enum {spento,acceso} stato;
typedef stato schermo[R][C]; /* R=righe, C=colonne */


/* prototipi */
	void LeggiNomeFile(char *, char *);
	FILE *ApriFile(char *, char *);
	void Spegni(schermo);
	void linea(void);
	void seqnumeri(void);
	void VisualizzaSchermo(schermo);
	int LeggiEVisualizza(char *, schermo);
	punto *CreaElemento(void);
	void Aggiungi(punto **, punto **, int, int);
	int ContaVicini(schermo, int, int);
	punto *CostruisciListaIsolati(char *);
	void StampaLista(punto *);
	int main(void);



void LeggiNomeFile(char *messaggio, char *nome)
{
	printf("%s",messaggio);
	gets(nome);
	return;
}


FILE *ApriFile(char *nome, char *modo)
{
	FILE *f;
	f=fopen(nome,modo);
	if(f==NULL) {
		fprintf(stderr,"Errore apertura file %s in modo %s. Esecuzione terminata.\n",nome,modo);
		exit(1);
	}
	return f;
}


void Spegni(schermo z)
{
	int i,j;
	for(i=0;i<R;i++)
		for(j=0;j<C;j++)
			z[i][j]=spento;
	return;
}


void linea(void)
{
	int j;
	printf("  +"); /* n.ro spazi bianchi == n.ro cifre intere */
	for(j=0;j<C-1;j++)
		printf("--");
	printf("-+\n");
	return;
}


void seqnumeri(void)
{
	int j;
	printf("   "); /* n.ro spazi bianchi == n.ro cifre intere + 1 */
	for(j=0;j<C;j++)
		printf("%1d ",j%10);
	printf("\n");
	return;
}


void VisualizzaSchermo(schermo z)
{
	/* molto piu` complicata del necessario per mettere una cornice */
	
	int i,j;
	seqnumeri();
	linea();
	for(i=0;i<R;i++) {
		printf("%2d|",i);
		for(j=0;j<C;j++)
			if(z[i][j]==acceso)
				printf("*|");
			else
				printf(" |");
		printf("%-2d\n",i);
		linea();
	}
	seqnumeri();
	return;
}


int LeggiEVisualizza(char *nome, schermo griglia)
{
	FILE *f;
	int i,j,k,n;
	
	Spegni(griglia);
	f=ApriFile(nome,"r");
	for(;fscanf(f,"%d %d %d",&i,&k,&n)==3;) {
		/* accendere n celle a partire da [i][k] */
		
		/* se impossibile scrive messaggio errore e ritorna */
		if(n+k>C) {
			printf("Specifiche in \"%s\" scorrette. Elaborazione interrotta.\n",nome);
			fclose(f);
			return 1; /* errore */
		}
		
		/* possibile! */
		for(j=k;j<n+k;j++)
			griglia[i][j]=acceso;
	}
	fclose(f);
	VisualizzaSchermo(griglia);
	return 0; /* ok */
}


punto *CreaElemento(void)
{
	punto *nuovo;
	nuovo=malloc(sizeof(punto));
	if(nuovo==NULL) {
		fprintf(stderr,"Allocazione memoria fallita. Esecuzione terminata.\n");
		exit(2);
	}
	return nuovo;
}


void Aggiungi(punto **testa, punto **coda, int i, int j)
{
	punto *nuovo;
	nuovo=CreaElemento();
	nuovo->x=j;
	nuovo->y=i;
	nuovo->next=NULL;
	if(*testa==NULL)
		*testa=nuovo;
	else
		(*coda)->next=nuovo;
	*coda=nuovo;
	return;
}


int ContaVicini(schermo z, int i, int j)
{
	int vicini=0;
	
	if(i>0) {
		if((j>0)&&(z[i-1][j-1]==acceso))
			vicini++;
		if(z[i-1][j]==acceso)
			vicini++;
		if((j<C-1)&&(z[i-1][j+1]==acceso))
			vicini++;
	}
	if(i<R-1) {
		if((j<C-1)&&(z[i+1][j+1]==acceso))
			vicini++;
		if(z[i+1][j]==acceso)
			vicini++;
		if((j>0)&&(z[i+1][j-1]==acceso))
			vicini++;
	}
	if((j<C-1)&&(z[i][j+1]==acceso))
		vicini++;
	if((j>0)&&(z[i][j-1]==acceso))
		vicini++;
	return vicini;
}


punto *CostruisciListaIsolati(char *nome)
{
	punto *testa, *coda;
	schermo griglia;
	int i,j;
	
	if(LeggiEVisualizza(nome,griglia)==1)
		return NULL;
		
	testa=NULL;
	for(i=0;i<R;i++)
		for(j=0;j<C;j++)
			if((griglia[i][j]==acceso)&&(ContaVicini(griglia,i,j)==0))
				Aggiungi(&testa,&coda,i,j);

	return testa;
}


void StampaLista(punto *p)
{
	for(;p!=NULL;p=p->next)
		printf("(%d,%d) ",p->y,p->x);
	return;
}


main(void)
{
	punto *primo;
	char nomefile[LEN];
	
	LeggiNomeFile("Inserisci nome file specifica: ",nomefile);
	primo=CostruisciListaIsolati(nomefile);
	StampaLista(primo);
	return 0;
}