Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Menu

Mostrar Mensajes

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

Mostrar Mensajes Menu

Temas - Neodivert

#1
Buenas noches gente

Hoy estuve viendo un vídeo sobre los distintos finales de un videojuego y, para mi sorpresa, vi un final que exigía que el jugador estuviera 4 HORAS pulsando dos botones para desbloquearlo. Súbitamente recordé el caso de otro videojuego, donde uno de los requisitos para desbloquear un final alternativo incluía realizar cierta acción y esperar 2 horas. También recordé otro videojuego, en el que si querías ver el final bueno tenías que ir a cierto mapa y hablar con un personaje tan pequeño que costaba verlo. Por si fuera poco, en ninguno de estos casos se te daba la más mínima pista de lo que tenías que hacer.

Estos casos me hicieron pensar en dónde está el límite de lo que se le puede o se le debería exigir al jugador para poder completar el 100% de tu juego, y quise saber que opinaban ustedes. ¿Están de acuerdo con incluir estas "odiseas" en los videojuegos? ¿Cuál es el objetivo de exigir semejante sacrificio de tiempo? ¿El que no forme parte de la historia principal justifica el probar hasta tales extremos la paciencia del jugador sin ni siquiera darle pistas sobre lo que tiene qué hacer?

Por mi parte yo no estoy de acuerdo con usar estos recursos aunque no formen parte del "núcleo" del videojuego. Me parece hasta cruel tener al jugador en un estado de tensión permanente preguntándose "¿me estoy dejando algo por hacer? ¿y si hago esto 1000 veces más a ver si pasa algo? :P
#2
¿Saben ese proyecto que empiezas cuando eres puro e inocente y que abandonas varias veces, pero siempre vuelves a él, sintiendo que no alcanzarás la paz interior hasta que lo termines? Pues bien, este es UNO de los míos.  :..

El juego de los bocadillos (o JDB) es un juego de habilidad 2D que he comenzado tres veces (contando con esta), y que ya había presentado en estos foros: http://www.stratos-ad.com/forums/index.php?topic=6805.msg78110#msg78110 (cuando lo volví a mirar no me creía que fuera del 2006). A continuación dejo una ficha resumen del proyecto:

Trasfondo
La historia de JDB se centra en la ambición de un joven por ganar un record mundial: pretende comerse el mayor número de bocadillos nunca visto, ayudándose para ello de una trituradora gigante que ha construido. Sin embargo, en su prisa por alcanzar la gloria, ha preparado los bocadillos a lo loco, sin preocuparse en controlar qué metía (o qué se metía) en ellos.

Mecánica
La acción del videojuego se centra en la cinta transportadora que mueve los bocadillos hasta la trituradora. El jugador contará con un elenco de herramientas que deberá combinar para eliminar los peligros de los bocadillos antes de que puedan dañar a nuestro protagonista y le impidan cumplir su objetivo.

Vídeos
El último vídeo que he grabado se llama "Infinite sandwiches" y lo subí el mes pasado a Youtube: http://www.youtube.com/watch?v=_mKGM9kUhN8
Sobre el vídeo...

  • Sé lo que están pensando y sí, he tenido que recurrir a supercomputadores para mover esos gráficos de última generación.
  • Los "tres" bocadillos diferentes que salen (el tercero es igual al segundo pero más grande) estaban para ver cómo quedaba cada uno. Ahora mismo me he quedado con el tercero porque me parecía que era el que menos pena daba ¿conformes? :P

Diario de desarrollo
Un proyecto que he comenzado tres veces se merece un extra de motivación para evitar que haya una cuarta vez. En mi caso se trata de mi blog (http://neodivert.com/blog/), donde he ido publicando cada semana los avances que realizo en el proyecto (a partir de ahora lo haré cada dos semanas). ¿Que donde está la motivación? Si me echo atrás y quiero abandonar el proyecto de nuevo, no podré escurrir el bulto tan fácilmente (la segunda vez que abandoné el proyecto, como no lo publiqué en ningún sitio, fue un "aquí no ha pasado nada"  0:-)).

Creo que con esto he hecho un resumen más o menos "comestible". Acepto críticas sobre mi capacidad nula como grafista, y porras sobre si abandonaré el proyecto una tercera vez o alcanzaré el Nirvana.

PD. El siguiente paso tras finalizar el juego es convertirlo en un MMORPG. Ya tengo el sistema de magias, por lo que el resto tiene que ser "cocer y cantar", ¿no?  :..
#3
General Programadores / Conflicto de Entrada/Salida en C++
28 de Junio de 2009, 05:42:34 PM
Buenas, estoy creando una clase en C++ para crear y controlar archivos de idiomas para mis próximos programas. Por ejemplo, tengo un archivo "Prueba.txt" con el siguiente contenido:


<PREGUNTA_NOMBRE>
Hola! Como te llamas? :

<PREGUNTA_EDAD>
Muy bien \s, cuantos annos tienes? :

<RESPUESTA_EDAD>
Oh! Asi que tienes \i annos... \n


Al usar el método "Generar_Archivo" de mi clase se genera el siguiente fichero:


// Entero que indica el número de cabeceras guardadas en el fichero
// Entero que indica el tamaño del mayor texto guardado en el archivo.
PREGUNTA_EDAD                  1 Muy bien \s, cuantos annos tienes? :
PREGUNTA_NOMBRE           0 Hola! Como te llamas? :
RESPUESTA_EDAD               1 Oh! Asi que tienes \i annos... \n


Mi clase podrá acceder al fichero generado y mostrar el texto asociado a la cabecera que yo le pase como parámetro al método "Mostrar".  El 0 o 1 que separa cabecera y texto indica si en el texto se muestran variables. Por ejemplo, puedo llamar a mostrar "PREGUNTA_EDAD" con un string (char *) y que en vez de \s me muestre ese string.

Bueno, ahora que he explicado lo que pretendo, comento mi problema.

Sobre el mismo fichero anterior he montado un programa de prueba:


int main(){
   try{
       cLD A;
       char Nombre[30];
       int Edad;

       A.Generar_Archivo( "Prueba.txt" );


       A.Mostrar( "PREGUNTA_NOMBRE" );
       cin.getline( Nombre, 30 );

       A.Mostrar( "PREGUNTA_EDAD", Nombre );
       cin >> Edad;


       A.Mostrar( "RESPUESTA_EDAD", Edad );


   }catch( bad_alloc& ){
       cout << "Error de memoria" << endl;
   }catch( eEscritura& ){
       cout << "Error de escritura" << endl;
   }catch( eLectura& ){
       cout << "Error de lectura" << endl;
   }catch( eArchivo_No_Abierto& ){
       cout << "Error: No se pudo abrir el archivo solicitado" << endl;
   }

   cin.get();
}


El problema surge al pedir los datos. Por ejemplo después de

A.Mostrar( "PREGUNTA_NOMBRE" );

Se muestra en pantalla "Hola! Como te llamas? : "

Pero a continuación, al hacer

cin.getline( Nombre, 30 );

al tratar de escribir el nombre me va sobrescribiendo el mensaje anterior. Por ejemplo, si escribo que mi nombre es Moises, en la pantalla aparece:

MoisesComo te llamas?:

o si escribo la edad después de mostrar el mensaje "Muy bien \s, cuantos annos tienes? :" por pantalla me aparece:

19y bien Moises, cuantos annos tienes? :

El código del prototipo de la clase y de la declaración de los métodos "Generar_Archivo" y "Mostrar" es el siguiente:



#include<cstdarg>
#include<fstream>
#include"cLista_Ordenada.cpp"

/*
 Nombre: "Lingva Dosiero" (LD) v1.0
 Autor: Moises Bonilla (Neodivert)
 Fecha de inicio: 06/06/09
 Fecha de finalización:
 Descripcion:
*/


/*                             Constantes y variables globales                                 */
/***********************************************************************************************/

const int TAM_LINEA = 101;
const int TAM_CABECERA = 41;
int P_No_Liberados = 0;
class eEscritura : public exception {};
class eLectura : public exception {};
class eArchivo_No_Abierto : public exception {};


/*                                Prototipos de clases y funciones                             */
/***********************************************************************************************/



/*                        1. Estructura sCabecera y operadores asociados                       */

struct sCabecera {
   char Cad[TAM_CABECERA];
   unsigned int Pos;
   unsigned int Num_Lineas;
   bool Var;

   // Operadores necesarios para crear una lista ordenada sin repeticiones.
   bool operator < ( sCabecera &B ){
       return ( strcmp( Cad, B.Cad ) < 0 );
   }
   bool operator != ( sCabecera &B ){
       return ( strcmp ( Cad, B.Cad ) != 0 );
   }
};

ostream& operator << ( ostream &Salida, sCabecera X ){
   Salida << X.Cad << "    Pos( " << X.Pos << ")" << endl;
   return Salida;
}



/*                             2 Clase cLD y operadores asociados                              */

class cLD {
   private:
       cLista_Ordenada<sCabecera> *Lista;
       ifstream *Archivo;
       char *NA;
   public:
       // 2.1. Constructores y destructores
       cLD() throw( bad_alloc );
       cLD( char Nombre_Archivo[] ) throw( bad_alloc );
       ~cLD();

       // 2.2. Inicialización.
       bool Asociar( char Nombre_Archivo [] ) throw( bad_alloc );

       // 2.3. Funciones principales
       bool Generar_Archivo( char Nombre_Archivo[] ) throw( bad_alloc, eEscritura );
       void Mostrar( char Cabecera[], ... )
                           throw( bad_alloc, eEscritura, eLectura, eArchivo_No_Abierto );
};



/*                             3. Funciones externas utilizadas                                */

void Cambiar_Extension( char Nombre_Archivo[], char *Extension );
char *Extension( char Nombre_Archivo[] );



/*                              Definiciones de clases y funciones                             */
/***********************************************************************************************/

[...]

/*                                   2.3. Funciones principales                                */

bool cLD::Generar_Archivo( char Nombre_Archivo[] ) throw( bad_alloc, eEscritura ) {
   /*
       Esta función se encarga de tomar un archivo de origen y transformarlo en un archivo .ld
       listo para ser usado. El proceso se divide en 2 partes:

           1. Crear una lista con todas las cabeceras del archivo de origen, ordenadas de
              menor a mayor.
           2. Recorrer la lista de cabeceras y escribir cada cabecera con su texto asociado
              en el archivo .ld
   */

   unsigned int i;
   ifstream A_Origen( Nombre_Archivo, ios::binary );
   ofstream A_Destino;
   char Linea_Actual[TAM_LINEA];
   sCabecera Cabecera_Actual;
   char *Texto;
   int Num_Cabeceras;

   /*
       Max_Tam y Tam_Actual se usan para ir calculando el tamaño del mayor texto encontrado.
       Esta información se usará cuando se invoque a la función "Mostrar".
   */
   int Max_Tam = 0;
   int Tam_Actual = 0;


   Cabecera_Actual.Cad[0] = 0;

   delete NA;
   try{
       NA = new char [ strlen( Nombre_Archivo )];
       strcpy( NA, Nombre_Archivo );
       Cambiar_Extension( NA, "ld" );
   }catch( bad_alloc& ){
       throw;
   }


   A_Destino.open( NA, ios::binary );

   if( A_Origen.is_open() ){
       if( A_Destino.is_open() ){

           /*
               Parte 1 : Creación de la lista de cabeceras

               Por la forma en que está estructurado el siguiente código, siempre se inserta
               una primera cabecera (sin uso) en la lista. Dicha cabecera se desecha una vez
               la lista se ha completado.
           */

           try{
               Lista = new cLista_Ordenada<sCabecera>;
           }catch( bad_alloc& ){
               throw;
           }

           while( !A_Origen.eof() ){
               A_Origen.getline( Linea_Actual, TAM_LINEA );
               // Comprobar si se trata de una cabecera:
               if( Linea_Actual[0] == '<' ){
                   // Inserta la cabecera anterior.
                   try{
                       Lista->Insertar( Cabecera_Actual );
                   }catch( bad_alloc& ){
                       delete Lista;
                       throw;
                   }

                   // Obtiene la cabecera
                   for( i=1; ( i<TAM_CABECERA-1 && Linea_Actual[i] != '>' && Linea_Actual[i] != '\000' ); ++i ){
                       if( Linea_Actual[i] >= 'a' && Linea_Actual[i] <= 'z' ){
                           Cabecera_Actual.Cad[i-1] = Linea_Actual[i]-32;
                       }else{
                           Cabecera_Actual.Cad[i-1] = Linea_Actual[i];
                       }
                   }
                   Tam_Actual = 0;
                   Cabecera_Actual.Cad[i-1] = '\000';
                   Cabecera_Actual.Pos = A_Origen.tellg();
                   Cabecera_Actual.Num_Lineas = 0;
                   Cabecera_Actual.Var = false;
               }else{
                   Tam_Actual += strlen( Linea_Actual );
                   Cabecera_Actual.Num_Lineas++;

                   if( strchr( Linea_Actual, '\\' ) ){
                       Cabecera_Actual.Var = true;
                   }
               }

               if( Cabecera_Actual.Cad[0] && Tam_Actual > Max_Tam ){
                   Max_Tam = Tam_Actual;
               }

           }


           // Inserta la última cabecera encontrada en el archivo.
           if( Lista->Tamanno() ){
               /*
                   Si el archivo tiene cabeceras, la última de ellas no se inserta en el código
                   anterior, por lo que se inserta aquí.
               */
               Lista->Extraer(); // Desecha la primera cabecera.
               if( Cabecera_Actual.Cad[0] != 0 ){
                   Lista->Insertar( Cabecera_Actual );
               }
           }


           try{
               Texto = new char [Max_Tam+1];
           }catch( bad_alloc& ){
               throw;
           }

           Num_Cabeceras = Lista->Tamanno();


           /*
               Al comienzo del archivo se escriben dos enteros sin signo, uno para indicar el
               número de cabeceras presente en el archivo, y otra para indicar el tamaño del
               mayor texto guardado en dicho archivo.
           */
           A_Destino.write( reinterpret_cast<char *>( &Num_Cabeceras ), sizeof( unsigned int ) );
           if( !A_Destino.good() ){
               delete Lista;
               A_Origen.close();
               A_Destino.close();
               throw eEscritura();
           }
           A_Destino.write( reinterpret_cast<char *>( &Max_Tam ), sizeof( unsigned int ) );
           if( !A_Destino.good() ){
               delete Lista;
               A_Origen.close();
               A_Destino.close();
               throw eEscritura();
           }

           while( Lista->Tamanno() ){
               /*
                   Se va extrayendo las cabeceras una a una de la lista y se van escribiendo
                   en el archivo (Sólo el texto de la propia cabecera).
               */
               Cabecera_Actual = Lista->Extraer();
               A_Origen.clear();
               A_Origen.seekg( Cabecera_Actual.Pos );

               A_Destino.write( Cabecera_Actual.Cad, TAM_CABECERA );
               if( !A_Destino.good() ){
                   delete Lista;
                   A_Origen.close();
                   A_Destino.close();
                   throw eEscritura();
               }

               /*
                   Dependiendo de si en el texto actual se mostrarán o no las variables pasadas
                   como parámetros a la función Mostrar, se escribirá un 1 o un 0
                   respectivamente, después de la cabecera.
               */
               if( Cabecera_Actual.Var ){
                   A_Destino.write( " 1 ", 3 );
               }else{
                   A_Destino.write( " 0 ", 3 );
               }
               if( !A_Destino.good() ){
                   delete Lista;
                   A_Origen.close();
                   A_Destino.close();
                   throw eEscritura();
               }

               /*
                   A continuación se escribe el texto asociado a la cabecera actual y se
                   inserta un salto de línea.
               */
               Texto[0] = 0;
               for( i=0; i<Cabecera_Actual.Num_Lineas; ++i ){
                   A_Origen.getline( Linea_Actual, TAM_LINEA );
                   if( strlen(Linea_Actual) > 1 ){
                       strcat( Texto, Linea_Actual );
                   }
               }

               A_Destino.write( Texto, Max_Tam );
               A_Destino.put( '\n' );
               if( !A_Destino.good() ){
                   /*
                       En caso de un error de escritura se vacía la lista de cabeceras, se cierran
                       los archivos y se lanza la excepción correspondiente.
                   */
                   delete Lista;
                   A_Origen.close();
                   A_Destino.clear();
                   A_Destino.close();
                   throw eEscritura();
               }

           }

           A_Origen.close();
           A_Destino.close();

           delete Texto;
           return true;
       }
       A_Origen.close();
       return false;
   }
   return false;
}


void cLD::Mostrar( char Cabecera[], ... )
                               throw( bad_alloc, eEscritura, eLectura, eArchivo_No_Abierto ) {
   unsigned int Ini = 0;
   unsigned int Fin;
   int Comp = 1;
   int Mitad;
   char *Texto = NULL;
   char Cabecera_Archivo[TAM_CABECERA];
   int Max_Tam;
   int Pos;
   char Variables;
   va_list Lista;

   char *s_arg;
   int i_arg;
   double d_arg;


   Archivo->open( NA );
   if( Archivo->is_open() ){
       /*
           Lee los dos enteros sin signo, el que indica el número de cabeceras se guarda en la
           variable "Fin" y el que indica el tamaño del mayor texto guardado en el archivo se
           guarda en "Max_Tam".
       */
       Archivo->read( reinterpret_cast<char *>( &Fin ), sizeof( unsigned int ) );
       Archivo->read( reinterpret_cast<char *>( &Max_Tam ), sizeof( unsigned int ) );

       if( !Archivo->good() ){
           Archivo->clear();
           Archivo->close();
       }


       while( Fin > Ini ){

           /*
               Se realiza una búsqueda dicotómica de la cabecera solicitada. El resultado de la
               comparación entre dicha cabecera y la actual se guarda en la variable Comp.
           */
           Archivo->clear();
           Mitad = (Ini+Fin)/2;
           Pos = Mitad*(Max_Tam+TAM_CABECERA+4)+2*sizeof(unsigned int);
           Archivo->seekg( Pos );

           Archivo->getline( Cabecera_Archivo, TAM_CABECERA );

           Comp = strcmp( Cabecera, Cabecera_Archivo );
           if( Comp > 0 ){
               Ini = Mitad+1;
           }else if( Comp < 0 ){
               Fin = Mitad;
           }else{
               Ini = Fin;
           }

       }

       if( Comp == 0 ){
           // Cabecera encontrada.
           Texto = new char [Max_Tam];

           /*
               Se lee el caracter que indica si el texto asociado a la cabecera buscada
               debe mostrar las posibles variables pasadas como parámetros.
           */
           Archivo->clear();
           Archivo->seekg( Pos+TAM_CABECERA+1 );
           Archivo->get( Variables );

           /*
               Se lee el texto asociado.
           */
           Archivo->clear();
           Archivo->seekg( Pos+TAM_CABECERA+3 );
           Archivo->getline( Texto, Max_Tam );
           Archivo->clear();


           if( Variables == '0' ){
               /*
                   Muestra el texto sin variables.
               */
               cout.clear();
               cout << Texto;
           }else{
               /*
                   Va mostradno el texto caracter a caracter con variables. Para ello se usa
                   una lista para albergar la lista variable de posibles parámetros.
               */
               va_start( Lista, Cabecera );
               for( int i=0; Texto[i]!=0; ++i ){
                   if( Texto[i] != '\\' ){
                       cout << Texto[i];
                   }else{
                       if( ( i+1 < Max_Tam ) ){
                           switch ( Texto[i+1] ) {
                               case 'i':
                                   i_arg = va_arg( Lista, int );
                                   cout << i_arg;
                               break;
                               case 's':
                                   s_arg = va_arg( Lista, char* );
                                   cout << s_arg;
                               break;
                               case 'd' | 'f':
                                   d_arg = va_arg( Lista, double );
                                   cout << d_arg;
                               break;
                               case 'c':
                                   i_arg = va_arg( Lista, int );
                                   cout << (char)(i_arg);
                               break;
                               default:
                                   cout << endl;
                               break;
                           };
                           i++;
                       }
                   }
               }
               va_end( Lista );


           }
           delete Texto;
       }else{
           cout << "[" << Cabecera << "]" << endl;
       }

       Archivo->clear();
       Archivo->close();
   }else{
       throw eArchivo_No_Abierto();
   }


}
[...]



He probado a usar el método "clear" sobre cout y cin, también el método "ignore" por si acaso, pero sigue igual. ¿Alguna solución? ^^U

Por cierto, hace bastante tiempo cree una función sencillisima para limpiar el buffer de entrada, pero ya no estoy seguro de si es lo correcto (aunque al usarlo no me da problemas). ¿El siguiente código es correcto?


inline void Limpiar_Buffer(){
      cin.clear();
      cin.seekg( 0, ios::end );
      cin.clear();
}


Muchas gracias.  ;)

#4

Buenas amigos. Estoy desarrollando una plantilla para crear fracciones de cualquier tipo.  Al tratar de implementar un método para eventualmente simplificar dichas fracciones concluí que lo mejor sería disponer de un puntero a dicha función cuyos parámetros fueran el numerador y el denominador y que el programador que usara dicha plantilla le pasara dicha función. También debía tratarse de un puntero / función estática, para evitar tener varias fracciones del mismo tipo pero simplificadas de modo diferente. Después de consultar en varias páginas web y mediante el arcaico pero efectivo método de prueba-error  0:-) lo implementé de la siguiente forma.

cFraccion.cpp

template <class A>
class cFraccion {
    private:
        A Num, Den, Comun;
        static void (* Simplificar)( A& Num, A& Den );

    public:

        ...

};

...

// Función creada por mí para simplificar la fracción en el caso de que contenga números enteros.
inline void Simp( int &Num, int &Den ) ;


Prueba.cpp

#include"cFraccion.cpp"

void Simp( float &a, float &b ){
    a -= 1;  // Simplemente puse esto para comprobar que invocaba a la función correcta. ;-)
}

void Simp( char &a, char &b ){ // (1)
};

template <class A>
void (*cFraccion<A>::Simplificar)( A& Num, A& Den ) = Simp; // (2)

int main(){

    cFraccion<int> A ( 4, 2 );
    cFraccion<float> B ( 2.1, 1 );
    cFraccion<char> C ( 'a', 'b' );

    cout << A << endl
         << B << endl
         << C << endl;
}


El programa compila perfectamente, pero le veo un par de limitaciones:
En (1): Si alguien no desea tener un método para simplificar las fracciones, debe crear una función que no haga nada. Cosa que no veo "elegante".
En (2): Tal como declaro y defino el puntero estático, la función para simplificar tiene que tener siempre el mismo nombre "Simp". Esto en realidad no me "molesta", pero puede que haya una forma que de más "libertad".

Luego la pregunta es: ¿Hay una forma mejor de implementarlo?

¡Gracias!  ;)

P.D. "Por si colaba", probé con


template <class A>
void (*cFraccion<int>::Simplificar)( int& Num, int& Den ) = Simplicar_Enteros; // Renombrando la función obviamente.


pero me lanza un error: "internal compiler error: in output_constant, at varasm.c: 3866

#5
Off-topic / Jizz in my pants
12 de Marzo de 2009, 01:03:27 AM

http://www.youtube.com/watch?v=-f5sBePuBfQ

No tiene más.  :P Un tío bastante precoz, ¿no creen?  :.. xD

P.D. El video tiene subtitulos en español para los que los necesiten como yo  ^_^', se activan dándole al botón de la esquina inferior derecha del video y otra vez al botón que se despliega.
#6
General Programadores / Matriz invalida (C++)
22 de Febrero de 2009, 04:47:21 PM
Buenas, estoy creando un programa en C++ para Windows, bajo el compilador MinGW y la IDE Code::Blocks. Para dicho programa estoy creando una clase cMatriz que por ahora tiene la siguiente pinta:


class cMatriz {
    private:
        int **M;
        int m, n;

        int Fila_Menor, Peso_Menor;
        int Mayor_num_Cifras;

        bool Matriz_Nula;
    public:
        // 1. Inicialización y destrucción.
        cMatriz( int i, int j );
        cMatriz( int i, int j, int min, int max );
        ~cMatriz();

        // 3. Operadores binarios
        cMatriz operator + ( cMatriz &B );

        // 4. Funciones gráficas.
        bool Nula(){ return Matriz_Nula; };
        int operator () ( int i, int j);
        friend ostream& operator << (ostream &Salida, cMatriz &Matriz);
};


Pero me acabo de dar cuenta de que, si quiero tener en cuenta todos los casos a la hora de inicializar una matriz, tendré que decidir que hacer si yo, o alguien que use la libreria intenta crear  una matriz con dimensiones invalidas (negativas o a cero). Por lo que se me plantearon 3 vías a desarrollar en el constructor, en el caso de que las dimensiones no sean validas:

a) Hacer un "delete this": Esta opción está casi descatarda, pues buscándola en google he leido que está desaconsejada por su comportamiento indefinido en el caso de que la uses en un objeto en vez de sobre un puntero a un objeto.

b) Lanzar una excepción: El Dios Google me ayuda de nuevo y me dirije a la siguiente página ( http://www.parashift.com/c++-faq-lite/exceptions.html ), donde leo lo siguiente:

Citar
[17.2] How can I handle a constructor that fails?

Throw an exception.

Constructors don't have a return type, so it's not possible to use return codes. The best way to signal constructor failure is therefore to throw an exception. If you don't have the option of using exceptions, the "least bad" work-around is to put the object into a "zombie" state by setting an internal status bit so the object acts sort of like it's dead even though it is technically still alive.

Siguiendo esta vía modifico el código del constructor así:


cMatriz::cMatriz( int i, int j ) : m(i), n(j), Fila_Menor(0), Peso_Menor(0), Mayor_num_Cifras(1), Matriz_Nula(true) {
    if( (m > 0) && (n > 0) ){
       // Inicializaciones oportunas de la matriz.
    }else{ // Matriz invalida.
        throw E_Matrices( E_RANGO_INVALIDO );
    }
}


Pero el compilador me lanza un warning: "control reaches end of non-void function". El cual no logro entender, pues se supone que el constructor no devulve ningún tipo, ¿no?  ???

c) Crear una variable booleana del tipo "Matriz_Valida" y usarla como bandera para saber si una matriz se creó correctamente y puede ser usada o no.

La 3ª opción me parece la más fácil, pero no se si es la más "moral" xD, o si hay alguna opción mejor o algún detalle que estoy pasando por alto.

Muchas gracias  ;)
#7
General Programadores / Usar funciones sin incluir la libreria
23 de Diciembre de 2007, 03:08:46 PM
(C++)

Hola, quería preguntar acerca de un problema que tengo usando cualquier editor y que parece más cosa de mi ordenador.

Resulta que puedo usar funciones de cualquier libreria ANSI, menos iostream, sin tener que incluirla en mi programa y funciona perfectamente.

Se que no es por alguna opcion de configuración del editor por que he probado varios ( Dev-C++, Code::Blocks, Borland C++ 5.5 y djgpp2 ), y sigue ocurriendo lo mismo (Bueno, puede ser que haya mucha casualidad xD)

Gracias ;)
#8
Guión y Diseño / Lo habías visto antes?
20 de Agosto de 2007, 02:46:32 PM
Hace tiempo tenía planteado escribir una historia con la esperanza de usarlo alguna vez en un juego (voy poco a poco, primero los juegos en ms-dos :P) de la que publiqué los 2 primeros capítulos en una página de relatos.

4º poder, cap. 1
http://relatoscortos.com/ver.php?ID=10848&cat=craneo

4º poder, cap. 2
http://relatoscortos.com/ver.php?ID=11006&cat=craneo


Argumento (Para el que no quiera leerse los dos capítulos :P )

CitarAño 2025. El mundo ha entrado en lo que parece ser la Guerra Fría del nuevo siglo. Todo pais del primer mundo está destinando casi en su totalidad su economía al presupuesto militar y de espionaje internacional, lo que se deja entrever en la apariencia de pobreza y abandono que esperimentan muchas de las antiguas grandes metrópolis del pasado. Se estima que como mínimo, cada país de mínima importancia táctica alberga a más de una decena de espias, denominados por la opinión pública como "los embajadores", por provenir y "representar" cada uno a un país distinto. Los Estados Unidos de América, la mayor potencia mundial del pasado ha entrado en una profunda depresión económica, debido a los numerosos conflictos protagonizados por el pais en los útimos años. Los Norteamericanos se encuentran ahora sumidos en una guerra civil en la que las matanzas no hacen más que sucederse a gran velocidad y varias grupos prugnan por llegar al poder. Grandes  sectores de la población intentan huir hacia Canadá o Méjico. La  (----------), la más prestigiosa cadena de televisión en todo el mundo, publicó los rumores de que Gran Bretaña, convertida ahora en una gran potencia de vital importancia en el mercado de armamento, planea invadir EEUU aprovechando sus conflictos internos, y así devolver lo que el gobierno ingles, (supuestamente) define como un "territorio netamente inglés" a sus antiguos dueños. Un agente español infiltrado alertó al gobierno del enorme despliegue naval que se estaba produciendo en Inglaterra. Los gobiernos español y portugues han mostrado su descontento ante esta evidencia de futuro ataque, alegando que ello desestabilizaria por completo, y aún más de lo que está, el equilibrio que no hace mucho se disfrutaba entre todos los paises del primer mundo. Otros paises como Alemania, Francia o Bélgica han mostrado su acuerdo, mientrás dos grandes potencias, Rusia y Japón han continuado sus relaciones de amistad y comercio con Inglaterra, incluso apoyándola en el supuesto de que sus intenciones para con EE.UU sean reales.

Mi pregunta es... ¿os suena de verla antes o algún argumento parecido? Suena estúpido, pero antes, cuando solía escribir relatos más a menudo, al escribir mucho más de lo que leía muchas historias mías resultaban ser mucho menos originales de lo que creía en un principio. ^^U Y ahora, que de vez en cuando voy poniendo en orden toda la historia en general y la de los personajes, no quiero que vuelva a pasar lo mismo. :P ;)

Y ya de paso opináis si os gusta la historia, o si debería jubilarme a mis 17 años. xD

P.D. Estuve buscando, y lo más parecido que encontré es un proyecto de información desde varios puntos de vista, de un grupo de estudiantes chilenos de periodismo, que se hacen llamar también "cuarto poder" :P,.Ppero si es solo el nombre puedo cambiarlo.  :roll: :P
#9
General Programadores / Problema con cin.getline();
21 de Julio de 2007, 11:28:32 PM
Buenas, estaba haciendo el tipico programa de la agenda en C++ usando listas y me da problemas con la funcion cin.getline();, mas concretamente con lo que viene despues de ella. :S

Al poner en la agenda que pidiera el telefono (al introducir un nuevo contacto) lo hacia con cin.getline(Nuevo_Contacto->Telefono, 10); y me lo cogia bien el problema es al poner despues algun cin.get(); o limpiar el buffer, el programa se queda atascado y no se por que. Para simplificarlo y ver que solo era un problema en esa parte y no tenia nada que ver con el resto del programa hize uno muy sencillo, este.


#include<iostream>
using namespace std;

char Telefono[10];
char ch;

int main(){
   cin.getline(Telefono, 10);
   cout << Telefono << endl;
 
   while( (ch=cin.get())!='\n'); // Limpiar el buffer;
}



Y el programa sigue atascandose justo despues de mostrar el telefono, a la hora de limpiar el buffer, la cosa es que si lo quito y pongo cin.get() (Para poder ver el programa sin que se cierre) se lo salta, y si lo pongo con lo de limpiar el buffer antes o despues del cin.getline(); se cuelga.

Lenguage C++ y compilador Dev-C++


Gracias  :wink:
#10
No se si ya lo habrán preguntado o en google se encontraba rápido (Yo no tuve mucha suerte buscando  :oops: ), pero quería preguntar cual es la diferencia entre las siguientes carreras.

Ingenieria técnica de informática de gestión.

Ingenieria técnica de informática de sistemas.

Ingenieria informática.


Se que las ténicas son de 3 años y son algo más específicas que la última, de 5 años, que es algo más general, pero de ahí no paso.

También de las diferencias entre las dos primeras del tipo, que es lo que enseñan y para los puestos de trabajo para los que sales dispuestos en cada una.


Perdón si estoy pidiendo mucho, si me vais a contestar lo mismo que a los que quieren hacer un MMORPG poner como mucho un [CENSURED] al principio, más que nada para avisar de lo que me viene encima. xD

:roll:  :wink:
#11
Off-topic / Momentazos OWNED
05 de Marzo de 2007, 11:44:31 AM
Bueno, sin rodeos, he creado un foro cuyo propósito es entre todo el que quiera participar hacer la mayor colección en español de momentazos OWNED.

http://owned.creatuforo.com/

Y I want you for... hacer ese "proyecto" si se le puede llamar así, realidad. xD

Y si, tengo mucho tiempo libre.  :roll:  :P
#12
General / Programación vs Diseño
03 de Marzo de 2007, 02:16:57 PM
No se por donde empezar asi que voy a hacerlo tirándome mierda y tierra encima para que ni uno confie en mi en el futuro. Soy impulsivo a más no poder.  :(  :lol:

Hace tiempo quize hacer una aventura gráfica con un amigo, la cúal empezó mi círculo vicioso. Se suponía que yo iba a dedicarme a su "programación" con el AGS y él con los gráficos. La aventura en sí no era muy compleja, pero era larga y a la mínima que hubo contratiempos la motivación iba recayendo (Como suele pasar en los primeros proyectos, al menos me alegro de no haber querido hacer un MMORPG  :roll: ).

Y cuando digo que ese proyecto empezó mi circulo vicioso es que a partir de ahí, proyecto que he empezado, proyecto que no he terminado. Siempre que empezaba uno nuevo, al mínimo que había problemas se perdía la motivación.  :(

El problema, o la pregunta que me surgió, despues de tantos proyectos inacabados y a día de hoy era el típico "Programación o Diseño". Por que he llegado a un punto en que ambos caminos me gustan (Me gustaba pensar y darle vueltas a los problemas y ver como resolverlos con bucles while, for... y al mismo tiempo me gustaba intentar que la idea gráfica que tenía del juego plasmarla sobre un papel).

No se,  :? quizás es que me gusta ambas partes, pero lo curioso es que me cuesta imaginarme en ambas partes trabajando en el futuro a nivel profesional.

Se me olvidó decirlo, tengo casi 17 años y aún me siento a tiempo de elegir, pero aunque cada vez soy más conciente de mi problema de elección, (Hola, soy Moisés y tengo un problema) soy conciente de que de seguir así puede que en el futuro esté en la carrera de informática y me acabe arrempintiendo por estar en alguna de diseño, y viceversa.

-----

Para ser alguien a quien no le gusta los blogs después me gusta contar largas historias sobre mi "y mis desdichas".  :roll:  :wink: xD. Gracias si habeis sido capaces de leer hasta aquí y por fin os pregunto. ¿Qué puedo hacer para quitarme tanto cacao e impulsividad de la cabeza? ¿Como puedo saber lo que quiero verme haciendo en el futuro?.


De nuevo, gracias. ;)
#13
Off-topic / El mayor de los peligros.
11 de Enero de 2007, 12:04:52 AM
Hace tiempo escribí esto en la sección críticas de relatoscortos.com .


CitarEnhorabuena, hemos creado nuestro propio Frankestein. Así es, pues el mayor peligro al que nos enfrentamos hoy día es producto de nuestra invención. Con él nos hemos procurado un hogar, con él nos alimentamos cada día, con él establecemos un hipotético "orden" en nuestra sociedad. Amigos, hablo del dinero. Un incendio puede pillar desprevenida a una familia y desgraciadamente arrebatarle la vida, una enfermedad puede extenderse y para cuando llegue la vacuna, haberse llevado a cientos, miles o incluso millones de personas. Pero ahora coger una moneda, ponerla sobre la mesa y recapacitar sobre ella. Es por ella y no por otra cosa que ahora mismo millones de niños no tienen con que comer. Es por ella y no por otra cosa, que una persona se ve obligada a robar, o incluso a matar, por su propio interés. Por unas monedas es por lo que alguien se ve obligado a traficar con drogas, extendiendo ese peligro en nuestra sociedad. No os voy a mentir, yo soy de los "ilusos" que aún creen en una humanidad unida por sus mismas creencias y valores, pues es el dinero y no otra cosa la que crea el máximo abismo que podamos imaginar. ¿Ricos y pobres?, ¿opulencia y pobreza?, ¿vida y muerte? Todo ello nos distingue, y el dinero es el brazo ejecutor. Lo hemos adoptado como forma de orden, como forma de ponernos a cada uno en su lugar. Pero, ¿hay algo de justo en que, por la influencia del dinero, los políticos proclamen guerras en las que mueren miles de soldados que nisiquiera comparten aquello por lo que luchan?. ¿Merecen estar ahí?. ¿Tiene algo de justo, que sea el dinero y no otro el que decida quien merece vivir y quien morir en agonía? ¿Tiene algo de justo, que sea el dinero y no otro, el que nos separa y nos frena como especie? ¿El que nos gobierna desde su guarida de tela y belcro, indomable, creado por nosotros y sometidos a él? Y he aquí su mayor baza, nuestro desconocimiento de él, de nuestro enemigo. Después de todo, no hay mucha gente que piense en el dinero como el mayor de los peligros, hay quien al leer esto se reirá y no lo tendrá en cuenta, sencillamente por que no piense que está sometido a unos papelitos de colores. Simplemente pensar que por su influencia, miles de personas "no merecedoras" están muriendo de hambre en el mundo, miles de personas se odian entre sí por asuntos de dinero, cientos de políticos y millones de personas anteponen el dinero a sus valores. Y de seguir así, que no sea de extrañar que aquello que hemos creado, sea aquello que nos destruya.


Me gustaría saber que opinan.  :wink:



Ya postee este tema en otro foro y nadie respondió, aunque no sabría decir exactamente por qué. Por favor, si os parece infantil, o algo idiota, comentarlo, no me voy a enfadar mucho.  :wink: :P
#14
Programación gráfica / ¿Es buen momento?
13 de Agosto de 2006, 04:30:30 PM
Buenas, soy un programador medio novato que no hace mucho empezó con C y C++ a ver si realmente programar es lo que quiero hacer (Aún tengo 16). He hecho algunos programas pequeños para el msdos, pero que realmente se un poco de todo y nada entero (No recuerdo bien la expresión xDD).

El caso es que tengo mis dudas, por que lo que me parece más suculento son los propios programas en modo ventana con sus gráficos y menus, pero no se si debería terminar el curso de C++ de conclase que estaba haciendo y ya después empezar con alguna libreria gráfica o empezar a aprender de los dos poco a poco. ¿Ustedes que harían?

He mirado varias librerias, como la OpenGL, pero o no encuentro las librerias para desarrollar los programas o las encuentro pero me dan problemas del compilador tipo "función no definida". :( xD

Bueno, la pregunta es más o menos sencilla, ¿Termino el curso y luego a los gráficos, o voy poco a poco con ambos? ¿Qué libreria me puede servir para hacer programas sencillos en modo ventana y multiplataforma?
#15
Proyectos / Grupo de Desarrollo
11 de Junio de 2006, 04:44:31 PM
Supongo que es aquí donde debo poner el mensaje, puesto que es un proyecto en si.  :roll:

Bueno, pues por donde empiezo, estoy a punto de terminar mi primer juego en fenix que puede denominarse como tal y ya tengo en proyecto otro mejor y espero, más entretenido. El caso es que realmente quiero ponerle empeño a este  y necesito ayuda de uno o dos grafistas, ya que se me da mejor la programación y más o menos el diseño.

Os pongo el argumento del juego.

===

El acensorista (Nombre provisional):

Juan ha entrado a trabajar de ascensorista  en un importante rascacielos. Nunca había pensado que su trabajo pudiera ser tan emocionante, ya que se enfrentará a peligros tales como parejas en conflicto, averías inoportunas, golpes de calor, desprendimientos, montones de ejecutivos sudosos, etc. Tu misión como su... ángel de la guarda, consiste en que sobreviva a esa emoción y que no muera o sea despedido en el intento.

===

El tipo de juego sería basicamente una serie de minijuegos que se eligen al azar cada vez que alguien desee subirse a tu ascensor. ;)

El juego está en una fase aún muy temprana de preproducción, estoy ideando las pruebas (Por ahora llevo 6), y con los diagramas de flujo.

No busco grandes genios del arte, solo que tengan un nivel aceptable y si se encargan de los personajes que sepan animarlos.

;)

===

Aqui tienen la demo del juego que hize, que aunque me haga ganar muchos enemigos ahi lo dejo.  xD

( http://fenixworld.se32.com/e107_plugins//depot/files/fw196.come_v0.9.rar )





Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.