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 - eferion

#301
no estás enviando nada bajo la variable "contenido"... ¿no será que te está creando el archivo pero lo deja vacío?
#302
Cita de: ivancea96 en 22 Julio 2014, 10:44 AM
Dado que el método imprime es privado, creo que sería más conveniente hacer una función en vez de una clase, ya que la clase se quedará en memoria sin hacer nada.

Si la idea es permitir la creación de una escena en la que se van insertando elementos, lo suyo sería que el método "imprime" sea propio del objeto... así cada objeto de la escena sabe cómo ha de pintarse... claro que en tal caso el método debería ser público y únicamente debería ser llamado por un objeto tipo "escena".

Lo que está claro es que no tiene ningún sentido que el método "imprime" sea privado... una clase que únicamente tiene un constructor y un destructor... salvo excepciones contadas, no sirve absolutamente para nada.
#303
Nota incial: No estaría de más que usas comas, puntos, acentos y demás signos ortográficos.

Borland C++ Builder hace uso de la librería propia de Borland, llamada OWL, para representar entornos gráficos de usuario. Si pasas a usar Visual Studio entonces ésta librería ya no está disponible. No obstante, puedes crear entornos gráficos con otras tantas librerías similares:


  • MFC (Microsoft Foundation Class): Es la librería propia de Microsoft. Visual Studio la incorpora en su instalador.
  • API de Windows: Al final todas las librerías de entornos gráficos pasan por el mismo sitio... la API de Windows. Esta librería es de bajo nivel, lo que implica que te permite hacer de todo... el precio a pagar es que su programación es bastante engorrosa.
  • Qt: Inicialmente desarrollado por Trolltech, ha pertenecido a Nokia y actualmente es propiedad de Digia. Es una librería completísima con muchas opciones... y además multiplataforma.
  • wxWidgets: Otra librería multiplataforma. No puedo decir mucho de ella porque aún no he tenido que usarla, aunque nunca está de más saber que hay alternativas.
  • GTK - GTK+: Librería multiplataforma originaria de entornos linux. Es muy usada, sobretodo en Linux.
  • Otras alternativas que puedes encontrar buscando en Internet.

Un saludo.
#304
Estás programando en C++... no uses includes de C (los que acaban en .h). La librería de C++ dispone de herramientas más que suficientes como para no tener que depender de la librería de C.

Por ejemplo, para manejar cadenas de caracteres en C++ lo suyo es usar la clase "string". Es mucho más segura y sencilla de manejar que los arreglos de C.

Otro ejemplo podría ser usar el contenedor "vector" en vez de memoria dinámica a pelo...

Además, tu código tiene algunos errores:

Código (cpp) [Seleccionar]

while(pal<c){
cin.getline(p[pal], 12);
strlwr(p[pal]);  //  pasa pal a minusculas para luego comparar con 'mar'
pal++; // <<<<<<-------- AQUI!!!!!
if(strcmp(menor,p[pal])>0){
strcpy(menor,p[pal]);
}
}


Si incrementas "pal" antes de hacer la comparación... estás comparando menor con una cadena no definida!!!!

#305
Necesitas una estructura que te permita almacenar el estado y/o la posición de los barcos:


enum pos
{
 Ninguna,
 Horizontal,
 Vertical
};

struct coord
{
 int x;
 int y;
};

struct barco
{
 int longitud;
 struct coord coordenadas;
 enum posicion pos;
 int estado;
};


Con esto ya puedes "modelar" cada uno de los barcos. Lo ideal sería tener una instrucción que permitiese crear los barcos. Algo del tipo:


struct barco NuevoBarco( int longitud )
{
 struct barco to_return;
 to_return->longitud = longitud;
 to_return->coordenadas.x = -1; // Para indicar que no esta posicionado
 to_return->coordenadas.y = -1; // Para indicar que no esta posicionado
 to_return->pos = Ninguna;
 to_return->estado = longitud;
 return to_return;
}


En este caso, "estado" almacena la "vida" del barco... si la vida llega a 0, el barco se considera hundido.

Como puedes ver, no uso memoria dinámica para los barcos... no es necesaria.

Una vez tienes la flota creada, lo suyo es posicionarla. Por la cantidad de barcos que hay no se me ocurre una combinación (tampoco voy a buscarla) en la que no se puedan colocar todos los barcos... yo, en primer lugar, crearía los barcos del más grande al más pequeño y, después, intentaría posicionarlos en ese orden.

Una forma de posicionar los barcos pudiera ser: En un bucle, elegir al azar un par de coordenadas  (x,y) y una posición (vertical u horizontal), después compruebas si el barco "entra" en esa posición... y repites el bucle hasta dar con una posición "válida".

Ahora toca inicializar el tablero para borrar la partida anterior si la hubiese.

Una vez has realizado estos pasos el programa está listo para iniciar la partida.

Cada vez que introduces unas coordenadas de disparo puedes hacer los siguientes chequeos:

* Si es una casilla que ya ha sido atacada, se piden nuevas coordenadas
* Se recorre el array de barcos y se comprueba si algún barco se encuentra en la coordenada seleccionada... si es así, actualizas el estado del barco para anotar un "toque". Llegados a este punto, si la vida de 3 barcos es 0, el jugador gana la partida. Si no hay barcos en la coordenada marcada... indicas "agua".

A continuación el prototipo de una función que determine si un barco ha resultado "tocado".


int BarcoTocado( struct barco* barco, struct coord coordDisparo )
{
 if ( barco->pos == Horizontal )
 {
   struct coord coordBarco = barco->coord;
   int i = barco->longitud;
   while ( i > 0 )
   {
     if (coordBarco == coordDisparo )
       return 1;

     coordBarco.x++;
     i--;
   }    
 }
 else
 {
   // ...
 }

 return 0;
}


Creo que con estas guías debería ser sencillo completar el programa.
#306
Cita de: avesudra en 21 Julio 2014, 16:09 PM
... por tanto digamos que el true en C es el número 1 y el false el 0.

Pequeño inciso al respecto: false es 0, cualquier otro valor será identificado como true


int main( )
{
  if ( 0 )
    printf( "Este mensaje no sale nunca\n" );

  if ( 5 )
    printf( "Este, en cambio, sale siempre\n" );

  if ( -4 )
    printf( "Este otro tambien sale siempre\n" );
}
#307
Y qué clase estás usando para generar el bmp??
#308
"cuenta % 2" significa "cuenta MOD 2"... es decir, devuelve el módulo 2 del valor de "cuenta" o, dicho de otra forma, el resto de dividir "cuenta" entre 2. De esta forma sólo se pueden obtener dos resultados: 0 si "cuenta" es par y 1 si "cuenta" es impar.

Por tanto, si "cuenta" es par se imprime "+++++", mientras que si "cuenta" es impar, se imprime "****".
#309
tu necesitas:

* putenv: en Linux
* _putenv: en Windows enlace

Al hacer "system" se abre y se cierra una conexión de consola, al cerrarse dicha sesión se pierden los valores temporales, por eso no te funciona.

#310
Programación C/C++ / Re: Temporizadores
18 Julio 2014, 12:49 PM
No es un mecanismo excesivamente depurado pero sirve para la ocasión:

Lo primero que necesitamos es una clase que nos permita "controlar" la entrada del teclado.

Para nuestra desgracia, el estándar de C++ no ayuda, ya que los mecanismos de entrada no van a devolver ningún dato hasta que el usuario presione la tecla "enter". Por este motivo nos tenemos que pegar con mecanismos menos portables... para la ocasión he usado la tan odiada "conio". Si alguien se lo quiere currar más está en su perfecto derecho.

El método run de la clase es bastante simple... cuando se presiona una tecla, activa un flag que indica la intención del usuario de introducir un número... cuando se introduce un carácter se actualiza el número introducido (esta versión no admite backspace)... cuando se introduce un enter se almacena el número y se sale de la función.

Código (cpp) [Seleccionar]

class DataManager
{
 public:

   DataManager( ) = default;

   DataManager( const DataManager& ) = delete;

   ~DataManager( ) = default;

   void Run( )
   {
     int temp_number = 0;

     while ( true )
     {
       char c = getch( );
       _withData = true;

       if ( c != '\n' && c != '\r' )
       {
         std::cout << c;
         temp_number *= 10;
         temp_number += c - '0';
       }
       else
       {
         std::cout << std::endl;
         _number = temp_number;
         break;
       }
     }
   }

   bool WithData( ) const
   { return _withData; }

   int Number( ) const
   { return _number; }

   const DataManager& operator=( const DataManager& ) = delete;

 private:

   bool _withData = false;
   int _number = 0;
};


Después necesitamos una clase para llevar de forma sencilla el conteo del tiempo... algo del tipo:

Código (cpp) [Seleccionar]

class Timer
{
 public:
   using milliseconds = std::chrono::milliseconds;

   Timer( )
   {
     Reset( );
   }

   Timer( const Timer& ) = delete;

   ~Timer( ) = default;

   void Reset( )
   {
     _start = std::chrono::high_resolution_clock::now( );
   }

   milliseconds Elapsed( ) const
   {
     return std::chrono::duration_cast< milliseconds >( std::chrono::high_resolution_clock::now( ) - _start );
   }

   const Timer& operator=( const Timer& ) = delete;

 private:
   std::chrono::high_resolution_clock::time_point _start;
};


Cuando se crea la clase se registra el tiempo y llamando a "Elapsed" se devuelve el número de milisegundos desde ese instante. Reset vuelve a inicializar la clase.

Con estos ingredientes ya tenemos casi todo el trabajo echo... solo nos falta mezclarlos convenientemente en el main:

Código (cpp) [Seleccionar]

int main( )
{
 std::cout << "Introduce un numero." << std::endl;
 std::cout << "Tienes 5 segundos para empezar" << std::endl;

 DataManager manager;

 std::thread thread{ [](DataManager* mgr){ mgr->Run( ); }, &manager };

 Timer timer;
 while ( timer.Elapsed( ) < std::chrono::seconds{ 5 } )
 {
   if ( manager.WithData( ) )
     break;
 }

 if ( !manager.WithData( ) )
   thread.detach( );
 else
   thread.join( );

 if ( manager.WithData( ) )
   std::cout << "Has introducido el numero: " << manager.Number( ) << std::endl;
 else
   std::cout << "No has introducido ningun numero." << std::endl;
}


Para controlar la entrada del teclado se crea un hilo. Después se inicializa el temporizador y se mantiene una espera activa de 5 segundos. La idea del temporizador en vez de un sleep es para que la aplicación pueda responder instantáneamente si el usuario introduce el número antes de 5 segundos.

Pasado el tiempo de espera activa se comprueba si el usuario ha hecho al menos el amago de introducir un número... si es así entonces espera pacientemente a que el usuario termine de introducir el número... en caso contrario finaliza el hilo y muestra el mensaje correspondiente.

Como he comentado antes, es algo muy mejorable. El ejemplo lo he realizado a petición de vangodp y sirve solo con fines ilustrativos.

PD.: utiliza funciones propias de C++11, ojo con los compiladores no compatibles.