/*	$Id: robot_random_board.c,v 1.2 2001/04/04 15:37:28 riq Exp $	*/
/* 
 * Archivo que contiene los algoritmos para generar
 * una tabla aleatoria valida
 */

#include <stdlib.h>
#include <config.h>
#include <gnome.h>

#include "robot_cliente.h"
#include "robot_random_board.h"
#include "protocol.h"

void generar( void )
{
	gint x,y,d,t,i,j;

	cliente.random = gnome_config_get_int_with_default("/gbnrobot/data/random=1995",NULL);
	srandom( cliente.random );
	cliente.random = random();		
	gnome_config_set_int("/gbnrobot/data/random",  cliente.random);
	gnome_config_sync();

	for(i=0;i<10;i++) { /* clean tabla */
		for(j=0;j<10;j++)
			cliente.mitabla[i][j]=NOBARCO;
	}

	for(i=1;i<=10;i++) {	
		x = 1+(int) (10.0*rand()/(RAND_MAX+1.0));
		y = 1+(int) (10.0*rand()/(RAND_MAX+1.0));
		d = (x + y) & 1;		/* Direccion */
		t = tamano( i );		/* Tamaņo */

		buscar_poscicion(x,y,d,t);
	}

}

gint posible( gint x, gint y, gint d, gint t)
{
	gint i;

	/* Por tamano, entra ? */	
	if( !entra( x,y,d,t) )
		return FALSE;
	
	/* Por colision, vale ? */
	if(d==0) {				/* Horizontal */ 
		for( i=0; i<=t+1; i++ ) {
			if(!( vacio_board(x-1+i,y) && vacio_board( x-1+i,y-1) && vacio_board( x-1+i,y+1))	)
				return FALSE;
		}
		return TRUE;
	} else {					/* Vertical */
		for( i=0; i<=t+1; i++ ) {
			if(! (vacio_board( x, y-1+i ) && vacio_board( x-1, y-1+i ) && vacio_board( x+1, y-1+i ))	)
				return FALSE;
		}
		return TRUE;
	}
}

/*
 * Algoritmo recursivo
 */
void 
buscar_poscicion( gint x, gint y, gint d, gint t)
{
	/* Pregunta si es posible en la otra direccion */
	if( posible( x,y, ((d^1) & 1),t )) {
		poner_barco( x,y,  ((d^1) &1), t);
		return;
	}

	/* FIXME: Usar algo mas potable (backtracking talvez ?) */
	/* Incrementa Y en uno y asi sucesivamente */
	/* Digamos que recorre todo */	
	y++;
	if(y>10) {
		y=1;
		x++;
		if(x>10)
			x=1;
	}
	if( posible( x,y,d,t) ) {
		poner_barco( x,y,d,t);
		return ;
	} else
		return buscar_poscicion( x,y,d,t);
}


gint tamano( gint i )
{
	gint a;

	switch(i) {	
	case 1:
	case 3:
	case 7:
	case 8:
		a = 1;
		break;
	case 2:
	case 9:
	case 5:
		a = 2;
		break;
	case 4:
	case 10:
		a = 3;
		break;
	case 6:
		a = 4;
		break;
	}
	return a;
}

/* Pregunta si un barco entra por tamano */
gint entra( gint x, gint y, gint d, gint t)
{
	if(d==0) { /* Horizontal */
		if(x+t-1<=10)
			return TRUE;
		else
			return FALSE;
	} else { /* Vertical */
		if(y+t-1<=10)
			return TRUE;
		else
			return FALSE;
	}
}

gint vacio_board( gint x, gint y)
{
	if(x<1 || x>10 || y<1 || y>10)
		return TRUE;

	if( cliente.mitabla[x-1][y-1]==NOBARCO || cliente.mitabla[x-1][y-1]==AGUA )
		return TRUE;
	else
		return FALSE;
}

void poner_barco( gint x, gint y, gint d, gint t)
{
	gint i;

	if(d==0) {				/* Horizontal */
		for(i=1;i<=t;i++)
			cliente.mitabla[x-2+i][y-1]=BARCO;
	} else {				/* Vertical */
		for(i=1;i<=t;i++)
			cliente.mitabla[x-1][y-2+i]=BARCO;
	}
}
