Dudas con STRUCTS y save/load en fichero externo

Started by FreeYourMind, May 18, 2011, 09:26:05 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

FreeYourMind

Hola.
Tengo un par de dudas.

Tengo 2 tablas de Hiscores, son 2 STRUCT con el mismo contenido (variables):

// Tabla 1: Player 1 Vs. CPU
STRUCT HiscoreP1VsCPU[5];
         int _Score;
         string _Name;
    int _Difficult;
    int _Player;
     End =
         100000, "W", 0, 1,
         90000, "M", 1, 2,
         80000, "q", 2, 3,
         70000, "d", 2, 4,
         60000, "S", 1, 5,
         50000, "F", 2, 6;
      
     // Tabla 2: Player 1 - Story Mode
     STRUCT HiscoreP1StoryMode[5];
         int _Score;
         string _Name;
    int _Difficult;
    int _Player;
     End =
         200000, "A", 0, 1,
         100000, "L", 1, 2,
         90000, "P", 1, 3,
         80000, "G", 1, 4,
         70000, "Y", 1, 5,
         60000, "S", 1, 6;


1 - Hay alguna forma de guardar las 2 estructuras en el mismo fichero externo ?
Si hago por ejemplo:

save("records.cfg", HiscoreP1VsCPU);
save("records.cfg", HiscoreP1StoryMode);

solo se salva la ultima estructura

2 -

Pensaba que al hacer un load, como le pasamos el nombre de la estructura
se comprobaria el nombre de la misma, pero parece que ignora el nombre
y le el fichero al completo, por ejemplo si hago esto:


Primero hago un
save("records.cfg", HiscoreP1StoryMode);

con lo cual voy a generar un records.cfg con la estructura
HiscoreP1StoryMode guardada en el.

despues al leer hago esto en un proceso:

IF (ScoreTable == 1)
      load("records.cfg", HiscoreP1VsCPU); 
      Tabla = HiscoreP1VsCPU;

ELSEIF (ScoreTable == 2)
      load("records.cfg", HiscoreP1StoryMode);
      Tabla = HiscoreP1StoryMode;
END

Tanto para ScoreTable 1 como ScoreTable 2, se asignan los mismos
datos del fichero y salen los registros de HiscoreP1StoryMode,
pero para ScoreTable 1 no deberia salir nada (o mejor, deberia
leer los datos de la estructura por defecto creada como global),
pero tambien esta pintando los datos de HiscoreP1StoryMode cuando
yo estoy leyendo datos de la struct HiscoreP1VsCPU la cual no existe
en el fichero externo...

A ver si me podeis ayudar, primero ver porque ignora el nombre
de la estructura del fichero externo y despues saber como poder
guardar las dos estrucutras en el mismo fichero sin tener que crear
uno distinto para cada una.

Gracias.

SplinterGU

tiene que estar en la misma variable para estar en el mismo archivo, sino te toca no usar la funcion save, y currartelo tu mismo como almacenar cada dato
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Entiendo que eso responde a la 1, y sobre la 2 ?

SplinterGU

no entiendo que queres decir con el punto 2, los archivos se llaman iguales, no le veo sentido.

pone un ejemplo, que entiendo mejor codigo que castellano.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

En el punto 2, el archivo es solo uno, donde guardo la estructura HiscoreP1StoryMode

save("records.cfg", HiscoreP1StoryMode);

o sea, si estoy leyendo de ese fichero despues la struct HiscoreP1VsCPU, no me deberia devolver los datos de HiscoreP1StoryMode, pero si valores null ya que HiscoreP1VsCPU  no se ha guardado en el fichero externo (en este caso no seria valores null, porque cuando son null lo que hace es leer los valores de HiscoreP1VsCPU definidos por defecto al crear la estructura en global).

SplinterGU

lo que decis no puede ser, pone un ejemplo compilable.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

me resulta dificl separartelo en un ejemplo, pero te aseguro que es lo que ocurre, no será porque las estructuras son iguales y solo cambia el nombre de ella ?

SplinterGU

no tiene nada que ver, no son punteros, son areas de memoria alocada.

a ver, es que ni con un bug en el core se puede hacer que al querer hacer un load de una variable se cargue otra variable.

imposible, por eso quiero un codigo que demuestre lo que decis, asi lo veo.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2


FreeYourMind

Aqui lo tienes, cuando se enseña la 'Tabla 1' esta poniendo los datos de una estructura guardada en el fichero externo que no deberia, porque estamos indicando otra que no se ha guardado en el fichero externo.


PROGRAM TestStructFile;

GLOBAL

STRUCT HiscoreP1VsCPU[5];
     int _Score;
     string _Name;
int _Difficult;
int _Player;
     End =
         100000, "Geca", 0, 1,
         90000, "Toni", 1, 2,
         80000, "José", 2, 3,
         70000, "Remondes", 2, 4,
         60000, "Ole", 1, 5,
         50000, "Splinter", 2, 6;

STRUCT HiscoreP1StoryMode[5];
     int _Score;
     string _Name;
int _Difficult;
int _Player;
     End =
         200000, "BennuGD", 0, 1,
         100000, "Toni", 1, 2,
         90000, "Geca", 1, 3,
         80000, "Mogadouro", 1, 4,
         70000, "Fernandes", 1, 5,
         60000, "Bragança", 1, 6;


BEGIN

set_mode(320, 240, 16);
set_fps(60, 0);

save("Datos.cfg", HiscoreP1StoryMode);

SeeRecordTables();

END


PROCESS SeeRecordTables()
PRIVATE
time;

BEGIN

  LOOP
   
time++;

SWITCH (time)
  CASE 1:
    write(0, 160, 20, 4, "TABLA 1");
    SeeRecords(1);
  END
  CASE 401:
delete_text(all_text);
write(0, 160, 20, 4, "TABLA 2");
SeeRecords(2);
  END
  CASE 801:
break;
  END

END

FRAME;
  END
END

PROCESS SeeRecords(ScoreTable)
PRIVATE
i;
inc_y;
file_cfg;

STRUCT Tabela[5];
     int _Score;
     string _Name;
int _Difficult;
int _Player;
     End =
         0, "", 0, 0,
         0, "", 0, 0,
         0, "", 0, 0,
         0, "", 0, 0,
         0, "", 0, 0,
         0, "", 0, 0;

BEGIN

  IF (ScoreTable == 1)
      load("Datos.cfg", HiscoreP1VsCPU);
      Tabela = HiscoreP1VsCPU;
  ELSEIF (ScoreTable == 2)
      load("Datos.cfg", HiscoreP1StoryMode);
      Tabela = HiscoreP1StoryMode;
  END

  FOR(i = 0; i < 6; i++)
     
IF (Tabela[i]._Difficult == 0)
write(0, 44, 58 + inc_y, 4, "easy");
ELSEIF (Tabela[i]._Difficult == 1)
write(0, 64, 58 + inc_y, 4, "medium");
     ELSE
write(0, 44, 58 + inc_y, 4, "hard");
END

write(0, 173, 58 + inc_y, 4, (string)(Tabela[i]._Score));
write(0, 268 + text_width(0, Tabela[i]._Name) / 4, 58 + inc_y, 4, Tabela[i]._Name);

inc_y = inc_y + 33;

  END
 
  LOOP
    FRAME;
  END

END 

SplinterGU

pero esta perfecto lo que esta haciendo el programa

1) no matas el proceso SeeRecords(1) antes de llamar al 2

2) estas guardando HiscoreP1StoryMode en Datos.cfg, luego en SeeRecords(1) y SeeRecords(2), cargas lo guardado en Datos.cfg, tanto en HiscoreP1VsCPU como en HiscoreP1StoryMode, entonces no entiendo como pretendes que muestren datos diferentes.

sos vos el que esta duplicando los datos en las 2 estructuras.

el funcionamiento esta bien, esta haciendo lo que le dijiste que haga en el prg.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

vaya que tonto soy, yo pensaba que en el load le estaba diciendo que estructura leer xDDDD
Ya me parecia raro, porque despues no se asignaba, es que lo estaba haciendo en el propio load xDDDD

Por cierto, entonces sobre la 1, en un fichero solo se puede guardar una estructura usando el save ? Con las otras funciones de escritura es posible guardar mas de una estructura y otras variables en el mismo fichero ?

Estaria bien un ejemplo de esto... Me imagino que bomber si lo hace en su sorr, pero nos ha dejado...

SplinterGU

podes hacer con las otras funciones, pero no de manera simple, te lo tenes que currar.

pero en tu caso, ambas structs son iguales, con hacer un array de las mismas, y guardar el array ya seria suficiente.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Eso ya me habia fijado, puedo crear una estructura para todas las variables que use en el juego, era por saber hacerlo de otra forma. Gracias.

Drumpi

Siento no haber respondido antes, pero estaba de siesta liado.

SAVE y LOAD sólo permiten guardar una única variable, array o estructura en un fichero.

Si quieren aprender cómo guardar varias estructuras, os lo contaremos en unos sencillos y cómodos pasos, para lo que necesitaremos:
-Bennu.
-Un editor de Bennu (preferiblemente, el paintbrush).
-Café.
-Un elefante rosa colgado de una farola.

Bien, empecemos:
1- Declarar una nueva variable tipo int, que almacenará el ID del fichero que vamos a usar (igual que se hace con LOAD_FPG y demás).
2- Ya dentro del código, usaremos FOPEN para abrir el fichero. Requiere la dirección/nombre del fichero, y el modo: O_READ para leer los datos, o O_WRITE para escribirlos. Podríamos usar el modo O_READWRITE para leer y escribir, pero lo ideal es abrirlo sólo para leer o sólo para escribir. Guardar el valor que devuelva FOPEN en la variable ( variable=FOPEN(... ).

MODO ESCRITURA
3- Usaremos FWRITE para guardar la primera estructura. Requiere la variable con el valor devuelto por FOPEN y el nombre de la variable/estructura.
4- Repetir el paso anterior con cada una de las variables a guardar.
5- Usar FCLOSE para cerrar (descargar) el fichero y que se guarden los cambios. Requiere el valor de la variable.

MODO LECTURA
3- Asegurarse de que se ha abierto el fichero. Al contrario que el modo escritura, si no existe fichero con ese nombre, este no se crea.
4- Usaremos FREAD para leer la primera estructura. Requiere la variable con el valor devuelto por FOPEN y el nombre de la variable/estructura donde almacenar los datos.
4- Repetir el paso anterior con cada una de las variables a leer.
5- Usar FCLOSE para cerrar (descargar) el fichero. Requiere el valor de la variable.

Así de fácil. Se recomienda hacer todas las lecturas/escrituras de golpe, y mantener abierto el fichero el menor tiempo posible. Ten en cuenta que cada vez que se lee un dato, el "puntero de lectura" avanza tantas posiciones como tamaño tenga la estructura que leas/escribas, por lo que el orden es fundamental (de lo contrario, tendrás que usar FSEEK, pero eso es algo más complicado).

Y ya tenemos los datos guardados en un fichero. Si os parece compicado, volved al usar SAVE/LOAD, pero usad un fichero distinto por cada variable que querais guardar.

La semana que viene, aprenderemos a manejar un satélite espacial ruso usando Matlab y papel higiénico. Abur ;D
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)