Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - do-while

#751
XD, es cierto, mira que lo he dicho, pero se me ha olvidado quitar el =. Hay sueño...
#752
¡Buenas!

El error esta aqui:

#define PATH = "/home/daniel/.drawsom/wordlist"


Te sobra el =

Deberia ser:

#define PATH = "/home/daniel/.drawsom/wordlist"


Cuando utilizas #define para definir constantes se hace asi:

#define CONSTANTE VALOR

no

#define CONSTANTE = VALOR

¡Saludos!
#753
¡Buenas a todos!

Estoy intentando crear una aventura conversacional (luego la pasare a grafica, pero esto es lo basico), y estoy atascado con distintos planteamientos. Quiero crear una estructura lo mas general posible para poder hacer aventuras posteriormente cambiando tan solo los datos de los objetos y escenarios que intervienen en ella.

De momento, la estructura que relaciona los escenarios la tengo clara. Voy a utilizar un ADT grafo que ya tengo construido, asi cada vertice sera un escenario y las aristas los caminos que llevan de un escenario a otro. La informacion la cargaria desde un fichero, asi distintos ficheros tendran distintos escenarios para distintas aventuras.

Los objetos tendran una ID, un nombre y una descripcion, tambien los cargare desde un fichero, asi que tambien es bastante general. Solo tendre que crear ficheros de datos para las distintas aventuras.

Cada escenario tendra una descripcion y una lista de objetos con los que se pueda interactuar, y el inventario del protagonista tambien sera una lista de objetos, por lo que tampoco pierdo generalidad.

El problema lo tengo a la hora de decidir como llevar a cabo las acciones (sera una cantidad pequeña de comandos, del estilo del Day Of Tentacle) sobre los distintos objetos.

Se me ocurren distintas opciones pero no se por cual decidirme ni que sera mejor o peor, aqui es donde me hace falta vuestra experiencia o sentido comun.

Tengo claro (o creo que lo tengo, si veis que voy dando palos de ciego avisad) que la estructura de la funcion que lleve a cabo la accion sobre el/los objetos tiene que ser la siguiente:

nombre_funcion(referencia a tipo_escenario, referencia a personaje, referencia a objeto1, referencia a objeto2, lista_de_objetos).

Asi podre modificar la lista de objetos del escenario y del protagonista, y decidir si el resultado es otro objeto distinto a los dos dados de entre todos los objetos que haya en el juego y realizar las modificaciones en consecuencia.

Por ejemplo:

Usar sombrero con perchero. Busco sombrero, busco perchero, compruebo que puedo realizar la accion, elimino el sombrero del inventario, elimino perchero del escenario y sustituyo perchero por perchero con sombrero que se encontrara en la lista de los objetos.

Las opciones que barajo son las siguientes:

- Crear una funcion, que dependiendo del comando introducido, discrimine con if-elses los objetos sobre los que se lleva a cabo, por ejemplo.

ejecutar_accion(accion, escenario, prota, objeto1, objeto2, lista_objetos)
{
    if(accion == UNA_ACCION)
    {
        if(objeto1 == UN_OBJETO)
        {
            if(objeto2 == OTRO_OBJETO)
            {
                una_accion(escenario, prota, objeto1, objeto2, lista_objetos);
            }
            else if(objeto2 == MAS_OBJETOS)
            {
                ...
            }
            ...
        }
    }
}
una_accion(escenario, prota, objeto1, objeto2, lista_objetos)
{
    Lo mismo de arriba, con if elses compruebo con que par de objetos estoy tratando y actuo en consecuencia.
}


Con este tipo de codigo me puedo volver loco discriminando todos los posibles casos y para cada aventura tendria que modificar todas las relaciones en el codigo fuente...

- La segunda opcion que estoy pensando es crear ficheros dependientes de cada accion con matrices NxN, donde N es la cantidad de objetos, con la siguiente estructura:


     ID1  ID2 ... IDN

ID1  R11  R12 ... R1N

ID2  R21  R22 ... R2N

.     .    .  .    .
.     .    .   .   .
.     .    .    .  .

IDN  RN1  RN2 ... RNN


Rij es el nombre de una funcion que realiza acciones sobre el protagonista y el escenario correspondiente dependiendo de la accion.

Rij, en el ejecutable, sera unsigned long funcion(escenario *, protagonista *, objeto1*, objeto2 *, listaobjetos*)

Rij con i < j sera una funcion binaria (relacionara dos objetos)
Rij con i >= j sera una funcion unaria (la accion recaera sobre un solo objeto, segundo = NULL)
Rij = NULL si los objetos no se relacionan por la accion indicada.

La forma de relacionar el nombre de la funcion con la funcion que cree en el codigo, seria utilizando una lista de pares (nombre funcion, puntero a funcion), asi al leer el nombre de la funcion en el fichero podria traducirlo a la direccion de dicha funcion para asignarlo en la matriz del ejecutable.

Lo malo de este metodo es, que aunque gano en generalidad, si por ejemplo tengo 30 objetos, tendria que rellenar 900 datos de una matriz por cada accion.

¿Cual es la mejor forma para trabajar este problema?

Si conoceis o se os ocurre otro metodo me gustaria saberlo. Si quereis que os aclare algo mas sobre lo que tengo pensado, preguntad. Solo quiero tener las ideas claras antes de empezar a teclear codigo.

Muchas gracias por vuestra atencion.

¡Saludos!
#754
¡Buenas!

Sagrini, si prestas atencion a los post anteriores, veras que esa es la forma en la que ellos estaban generando numeros aleatorios (no la misma, pero si basada en busquedas de numeros repetidos). Si miras la tabla que he dejado, veras que es muy ineficiente y cuanto mas crece el tamaño de los datos mas ineficiente se vuelve.

Cuenta tu mismo las iteraciones que esta realizando el codigo que has puesto y luego las que realiza el codigo que he indicado, y comprobaras tu mismo, que estas generando muchisimas mas de las necesarias.

¡Saludos!
#755
¡Buenas!

Buf... Esa forma de generar numeros aleatorios distintos en un intervalo es muy farragosa. Te propongo esta otra:


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

#define LONGITUD_INTERVALO_FUENTE 20
#define MIN_FUENTE 1
#define NUMERO_VALORES 15

int main(int argc, char *argv[])
{
   int vector_fuente[LONGITUD_INTERVALO_FUENTE];
   int v1[NUMERO_VALORES] , v2[NUMERO_VALORES] , i , indice , aux;

   srand(time(NULL));

   /* inicializamos la fuente de los datos */
   for(i = 0 ; i < LONGITUD_INTERVALO_FUENTE ; i++)
       vector_fuente[i] = MIN_FUENTE + i;

   /* Reordenamos los valores*/
   for(i = 0 ; i < NUMERO_VALORES ; i++)
   {
       aux = vector_fuente[i];
       vector_fuente[i] = vector_fuente[indice = rand() % LONGITUD_INTERVALO_FUENTE];
       vector_fuente[indice] = aux;
   }

   /* copiamos los valores en el primer vector */
   for(i = 0 ; i < NUMERO_VALORES ; i++)
       v1[i] = vector_fuente[i];

   /* reordenar de nuevo y asignar al segundo vector */
}


Aunque parezca mas largo, imagina que tienes que asignar N valores aleatorios distintos en un vector de N posiciones, en este caso, una vez que hayas introducido n valores, la probabilidad de repetir alguno de los valores introducidos es de n/N, es decir, cuanto mayor sea n, mayores posibilidades tendras de repetir alguno de los numeros introducidos, por lo que vuestros bucles se pueden repetir una cantidad de veces considerablemente mas alta de la necesaria. Por ejemplo en un vector de 100 posiciones, una vez introducidos 99 numeros, 99 de cada 100 veces generareis un numero repetido.

Sin embargo, con el metodo que he propuesto, quitando la inicializacion del vector que contiene el origen de los datos, siempre realizareis la misma cantidad de iteraciones, asegurandoos de que nunca se repetiran los valores.

La contrapartida del metodo que he utilizado es que utiliza mas memoria al tener un vector para almacenar todos los posibles datos.

Si quereis luego hago una simulacion con vuestro metodo y dejo las estadisticas para que las veais.

¡Saludos!

PD: Aqui una salida de la simulacion:


10 valores entre 1 y 16. Media 86.00 iteraciones

Vector resultante:
11   9   6  14  10   7  15   1   3   4

15 valores entre 1 y 16. Media 358.11 iteraciones

Vector resultante:
13  15  14   2   5   9   3  10  11   4   1   6   8  12   7

25 valores entre 1 y 51. Media 432.91 iteraciones

Vector resultante:
46  20  28  40  43  17  22  42  36   7  16  10  47   6  34  18  49  30  33   8
26  13  27  25  38

50 valores entre 1 y 51. Media 5217.88 iteraciones

Vector resultante:
39  42  36  25   7  19  23  22  50  41  44  26   2  45  29  18   8  31  28  33
14   4  20  46  30  48  27  10  47  15  40   6  32  16  24   3  21  43  38  49
12   9  13  17  11   1   5  35  37  34


Y aqui el codigo fuente que he utilizado para hacerla:


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

#define RANGO_1 15
#define RANGO_2 50

#define MINIMO 1

#define NUMERO_VALORES_1 10
#define NUMERO_VALORES_2 15
#define NUMERO_VALORES_3 25
#define NUMERO_VALORES_4 50

#define REPETICIONES 2000

int main(int argc, char *argv[])
{
   int numero_valores[] = {NUMERO_VALORES_1,NUMERO_VALORES_2,NUMERO_VALORES_3,NUMERO_VALORES_4};
   int rangos[] = {RANGO_1,RANGO_2};
   int v[NUMERO_VALORES_4];
   int total_iteraciones, n_iteraciones , i,j,k, valores_introducidos,valor;

   srand(time(NULL));

   for(i = 0 ; i < 4 ; i++)
   {
       total_iteraciones = 0;

       for(j = 0 ; j < REPETICIONES ; j++)
       {
           n_iteraciones = 0;

           valores_introducidos = 0;

           while(valores_introducidos != numero_valores[i])
           {
               if(valores_introducidos == 0)
                   v[0] = rand() % rangos[i / 2] + MINIMO;
               else
               {
                   do{
                       valor = rand() % rangos[i / 2] + MINIMO;

                       for(k = 0 ; k < valores_introducidos && v[k] != valor ; k++)
                           n_iteraciones++;

                       n_iteraciones++;

                   }while(k < valores_introducidos);

                   v[valores_introducidos] = valor;
               }

               valores_introducidos++;
               n_iteraciones++;
           }

           total_iteraciones += n_iteraciones;
       }

       printf("%d valores entre %d y %d. Media %.2f iteraciones\n\n",
               numero_valores[i], MINIMO , MINIMO + rangos[i / 2], ((float) total_iteraciones) / REPETICIONES);

       printf("Vector resultante:\n");

       for(k = 0 ; k < numero_valores[i] ; k++)
           printf("%3d ",v[k]);
       printf("\n\n");
   }

   return 0;
}


¡Saludos de nuevo!
#756
Hum... Jeroen Vader ahora va a pasar a ser Darth Vader  ;-)
#757
Pitudox27, ¿no ves que lo que hace esta aplicacion es lo mismo que hace google, facebook, los distintos goviernos en mayor o menor medida, distintas webs o incluso las empresas antes de contratar personal? Recopilar toda la informacion que hay a mano sobre distintas personas para utilizarla en su beneficio.

No entiendo tanto revuelo por algo que se lleva haciendo ya durante varios años por otras personas o entidades...

¡Saludos!
#758
Supongo que te refieres a esto:

class Rectangulo::Objetogeometrico
#759
¡Buenas!

Aqui tienes otro error de logica:


           scanf ("%s", &ptr_clientes->ciudad);
           ptr_clientes++;
        }
        ptr_clientes++;


Si se escoge introducir los datos de un cliente se esta avanzando por el vector de clientes de dos en dos, por lo que si escoges rellenar todo el vector al llegar a la mitad estaras apuntando a una zona de memoria a la que, en principio, no te corresponderia acceder.

Tendras que avanzar el puntero siempre, bien introduzcas datos o decidas no introducirlos en la posicion dada, por lo que el avance del puntero dentro del if te sobra.

¡Saludos!

PD: No te preocupes, si el usuario solo introduce un cliente tu codigo no supone ningun problema, directamente sale del for y vuelve a la funcion llamadora. Al mostrar datos lo mas posible es que muestre basura al acceder a datos no inicializados. He mentido. Como tienes cadenas de caracteres, si no contienen caracteres nulos, las funciones que las acceden seguramente de daran errores por acceder a posiciones de memoria indebidas al seguir leyendo la memoria en busca del caracter nulo que indica su fin. Puedes añadir una funcion que inicialice los datos de forma consistente.

Otra cosa, si no quieres encontrarte cosas raras, asegurate de que los datos introducidos estan dentro de rango, y luego actua en consecuencia. Si no te aseguras de que los datos de los distintos menus esten en el rango adecuado, tendras que añadir elses a los ifs para discriminar los datos que no te interesen.
#760
Programación C/C++ / Re: Duda tabla [5][5]
31 Marzo 2012, 13:21 PM
¡Buenas!

No se si te acepta esa inicializacion de la matriz, si mal no recuerdo (aunque hace bastante que mire la teoria sobre esto), las matrices habia que inicializarlas por filas:


int tabla[5][5] =
                {{1,2,3,4,5} ,
                 {6,7,8,9,10},
                 {11,12,13,14,15},
                 {16,17,18,19,20},
                 {21,22,23,24,25}};


¡Saludos!