Ir al contenido

publicidad

Foto

C++ , estructura "lista" de la STL , inventarios


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
11 respuestas en este tema

#1

Escrito 26 abril 2009 - 17:23

          Hola, os voy a dar un poco de código fuente para que aprendáis a usar una estructura de la Standard Template Library.

          La STL dispone de unas cuantas estructuras muy útiles que nos evitan mucho trabajo. Una de ellas es una lista doble-enlazada circular. Esto significa que es una lista de elementos, que cada elemento contiene un puntero al anterior y al siguiente, y que si nos pasamos del final volvemos al principio (o si nos pasamos del principio volvemos al final). Los elementos de la lista no tienen que estar almacenados en memoria de forma consecutiva y pueden borrarse y añadirse tantos como nos permita la memoria (al contrario que una tabla que siempre ocupa lo mismo en memoria y si se llena no permite añadir más). El código fuente que pongo abajo hace uso de las funciones más comunes, hay otras muchas pero sabiendo utilizar éstas las demás son pan comido.

          Es una buena forma de almacenar un inventario. Y también para crear la lista de objetos que hay en cada casilla de un mapa. Para guardar la lista habrá que usar un iterador y recorrerla entera guardando cada uno de los datos y para leerla lo mismo. Al principio del archivo pondremos el número de elementos que contiene la lista para saber cuántos tenemos que leer al cargarla en memoria.

[code:1]
#include //hay que añadir este archivo.
#include
#include

using namespace std; //esto es imprescindible, nos evita usar constantemente "std::"

//creo la lista de números enteros.
list listanum;
//creo un iterador.
list::iterator i; //el iterador es un índice especial para estructuras.

void PrintList()
{
cout << "\n";
for(i = listanum.begin(); i != listanum.end(); ++i)
{
cout << *i;
}
getch();
}

void main()
{
//introduzco cinco números.
listanum.insert(listanum.begin(),20);
listanum.insert(listanum.begin(),30);
listanum.insert(listanum.begin(),40);
listanum.push_back(50);
listanum.push_front(10);
//ahora la lista contiene 10,40,30,20,50
//para ordenar la lista:
listanum.sort();
PrintList();
// cambiar el valor 30 por 60
*find(listanum.begin(),listanum.end(),30) = 60;
PrintList();
//inserto un 70 delante del 40
listanum.insert(find(listanum.begin(),listanum.end(),40),70);
PrintList();
//escribo el tamaño de la lista.
cout << "\n" << listanum.size();
getch();
//borro el primer número.
listanum.erase(listanum.begin());
PrintList();
//sitúo el iterador en el valor 70 y lo borro.
i = find(listanum.begin(),listanum.end(),70);
listanum.erase(i);
PrintList();
//Ahora voy a crear otra lista y voy a meterla entera en la anterior.
//Esto es muy útil cuando abres un contenedor y quieres cogerlo todo.
i = listanum.begin(); //pongo la segunda lista al principio de la primera.
list listanum2;
listanum2.push_back(1);
listanum2.push_back(2);
listanum2.push_back(3);
listanum2.push_back(4);
listanum.splice(i,listanum2);
PrintList();
//Ahora voy a buscar el valor 4 en la lista y sumarle 3. Así
//se puede añadir un objeto apilable a un inventario.
if((i=find(listanum.begin(),listanum.end(),4))!=listanum.end())
{
*i = *i + 3;
PrintList();
}
}
[/code]

          Espero que os sea de ayuda.

  • IsGreen

  • Neonate

  • vida restante: 100%
  • Registrado: 12 ene 2009
  • Mensajes: 73
#2

Escrito 26 abril 2009 - 19:45

¿Has probado este código junto a un motor de juego?.

Saludos.

#3

Escrito 26 abril 2009 - 20:52

          No , pero tengo un motor en el que se usa la clase vector, que para el caso es más o menos lo mismo. La clase vector es lo que comunmente conocemos como tablas, solo que mejorada. Un vector incluso se redimensiona automáticamente si es necesario.

          En el motor se utiliza un vector para almacenar la lista de sprites. Además se puede usar cualquier tipo de dato o estructura ( o clase).

  • IsGreen

  • Neonate

  • vida restante: 100%
  • Registrado: 12 ene 2009
  • Mensajes: 73
#4

Escrito 26 abril 2009 - 21:44

Las veces que he intentado utilizar una biblioteca diferente a la del motor de juego, he tenido errores de compilación, por ejemplo, utilizar fstream con DarkGDK.

El motor que vengo utilizando últimamente, Esenthel, incorpora unos contenedores de memoria (los llama memory containers ), que son matrices dinámicas de datos, similar al ejemplo que has puesto.

Con este motor no he podido utilizar ni la biblioteca iostream, salta el error: warning C4627: '#include ': se omite al buscar el uso del encabezado precompilado Agregar directiva a 'stdafx.h' o volver a generar el encabezado precompilado.

#5

Escrito 26 abril 2009 - 22:15

IsGreen, el problema que comentas viene de usar IDE's concretos, como Visual Studio en este caso, que tienen determinadas extensiones que no son estándar.

El problema de stdafx.h viene dado por tener el proyecto configurado para usar encabezados precompilados. Se puede resolver de varias formas, en función de si te interesa hacer tu código más estándar o más dependiente de Microsoft.

Dicho sea de paso, en el ejemplo que abre el hilo, la librería conio.h tampoco es estándar, y debería ser evitable a toda costa.

Y respecto a los frameworks, pues dependerá de cada uno y de lo intrusivo que sea. Los hay que utilizan sus propias estructuras (que muchas veces no hacen más que encapsular las estándar) y los hay que no, o que te permiten gestionar la lógica por tu cuenta y solo se encargan del dibujado, la entrada, el sonido, etc.

  • wiyarmir

  • Elder

  • vida restante: 100%
  • Registrado: 27 mar 2009
  • Mensajes: 108
#6

Escrito 30 abril 2009 - 23:26

Permíteme ser quisquilloso y decirte que has usado variables globales!! :twisted:

Ahora en serio... se me antoja algo lioso siempre que puedas hacerte las tuyas propias... claro que si no sabes, es lo mejor.

Bueno, quizás no, porque de todas maneras necesitas saber cómo funcionan para usarla así que.... :-D

Puede que me haga un mini-tuto de estructuras avanzadas de datos y su aplicación en videojuegos, y verás lo sencillo que es usar una lista creada por ti mismo :)

Saludines

#7

Escrito 30 abril 2009 - 23:44

No creo que puedas programar una estructura más optimizada que las de la STL.

  • wiyarmir

  • Elder

  • vida restante: 100%
  • Registrado: 27 mar 2009
  • Mensajes: 108
#8

Escrito 01 mayo 2009 - 00:01

Lo dudo mucho, ya que la STL está muy rodada, pero no hablaba de optimización, sino de sencillez de manejo. La STL trata de ser tan general que se sale de complejidad.
Claro que también he pecado un poco de subjetividad, dado que a mi me gusta saber qué hago en cada momento, pero allá cada uno consigo mismo :)

  • Ellolo17

  • Ganondorf

  • vida restante: 100%
  • Registrado: 16 nov 2006
  • Mensajes: 6.208
#9

Escrito 01 mayo 2009 - 01:58

IsGreen, si has usado el Dark GDK las colisiones tienen dos formas muy faciles de tratarse con dos dll externas:

Sparky Collision, que te calcula muy rapidamente cualquier colision y amplia las del darkgdk con ovaloide y cosas asi.

DarkPhysics, que es el que tengo yo. Un motor en el que al cargar un modelo 3d dices si es solido o no, le das un par de datos y al actualizar se encarga de toda la fisica olvidandote de colisiones y asi.

Un saludo.

  • IsGreen

  • Neonate

  • vida restante: 100%
  • Registrado: 12 ene 2009
  • Mensajes: 73
#10

Escrito 01 mayo 2009 - 20:49

Saludos, el problema lo tuve con la biblioteca fstream junto a DarkGDK. Si alguien conoce la solución aquí tiene la pregunta que envié al foro anglosajón.

http://forum.thegame...w&t=139289&b=22

Os felicito por los bastos conocimientos sobre informática O:) , pero yo no voy a reinventar la rueda. :]

Prefiero ahorrar tiempo y utilizar las herramientas que me facilita un buen motor de juego, como Esenthel. Realizado en Polonia, que aunque no son la octava potencia mundial, la gente que ha estudiado informática en aquel país ya tiene algo a lo que llamar motor de juego :-D .

#11

Escrito 01 mayo 2009 - 22:05

¿Hay alguna función para leer los caracteres de uno en uno?, porque si lees una cadena de un archivo que solo tiene 0 y 1 intentará leer hasta el final de la cadena o hasta el final del archivo y no cabe en szCodigo.

Eso es lo más que te puedo decir sin saber darkgdk.

Aquí estaría bien saber qué está leyendo dbReadString(1,szCodigo);

[code:1]for (int y=1; y < 129; y++)
{
dbReadString (1,szCodigo);
for (int x=1; x < 129; x++)
{
if ((szCodigo [x-1]) == '0')
bBit_Map [ x ] [ y ] = 0;
else bBit_Map [ x ] [ y ] = 1;
}
}
[/code]

#12

Escrito 01 mayo 2009 - 22:27

Saludos, el problema lo tuve con la biblioteca fstream junto a DarkGDK. Si alguien conoce la solución aquí tiene la pregunta que envié al foro anglosajón.

http://forum.thegame...w&t=139289&b=22

Os felicito por los bastos conocimientos sobre informática O:) , pero yo no voy a reinventar la rueda. :]

Prefiero ahorrar tiempo y utilizar las herramientas que me facilita un buen motor de juego, como Esenthel. Realizado en Polonia, que aunque no son la octava potencia mundial, la gente que ha estudiado informática en aquel país ya tiene algo a lo que llamar motor de juego :-D .


En el último bloque de código, el error es de linkado, es decir, que no estás añadiendo correctamente las librerías. La verdad es que suelen errores un poco más difíciles de resolver, porque un error de código sabes dónde mirar, pero si es de linkado es problema de configuración. Revisa el código externo que uses, que están bien añadidos los .lib , prueba la solución que te da el linkador (usar /NODEFAULTLIB:nombre_biblioteca).

De los otros bloques de código, no sé cómo van las funciones de DarkGDK, así que ni idea.

Lo único destacable sería lo que te responden en el foro: las comparaciones. Es cuestión de ponerte a depurarlo y ver el contenido de las variables en memoria en tiempo real, para ver si los datos cargan correctamente y lo erróneo es el manejo de los mismos.


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
publicidad