viernes, 16 de diciembre de 2011

Arbol binario en C++

El semestre pasado me tope con este concepto, si han buscado un poco sabran que un arbol binario es una estructura de datos util cuando se trata de hacer modelos de procesos en donde se quiere tomar desiciones en uno de los dos sentidos en cara parte del proceso.

Los arboles binarios sirven para realizar bases de datos donde la búsqueda y almacenamiento sean optimos, debido a que en un arbol los datos no se almacenan de forma lineal como una pila o una cola, donde los datos que entran solo se pueden leer en respectivo orden de entrada. Entre otras aplicaciones de los arboles binarios encontramos la encriptación de archivos o la creación de compiladores.

A continuación algunos de los procesos básicos utilizando arboles binarios (al final pueden descargar el código completo)

Nota: los métodos y procedimientos para un árbol binario deben ser recursivos.

Clase para el nodo de información: 
#include <stdlib.h>

class Nodo
{
    public:
        int info;
        Nodo *Llink; //enlace izquierdo
        Nodo *Rlink; //enlace derecho   
        Nodo(int);
        ~Nodo();
};

Nodo::Nodo(int info)
{
    this->info = info;
    Llink = NULL;
    Rlink = NULL;    
}

Nodo::~Nodo()
{ }

Clase para el árbol binario:
#include "nodo.h"
#include <iostream>

using namespace std;

class Arbin
{
    private:
        Nodo *raiz;
        Nodo *Insertar(Nodo*,Nodo*);
        Nodo *Borrar(Nodo*, int);
        int  getInfo_der(Nodo*);
        void preOrden(Nodo*);
        void inOrden(Nodo*);
        void postOrden(Nodo*);
    public:
        Arbin();
        void Crear(Nodo*);
        void Recorridos(int);
        void Eliminar(int);
        ~Arbin();
}; 

Algunos métodos básicos:
Inserción 
Nodo* Arbin::Insertar(Nodo *p, Nodo *q){
    if(p == NULL){
        p = q;
    }
    else{
        if(q->info < p->info){
            p->Llink = Insertar(p->Llink,q);
        }
        else{
            p->Rlink = Insertar(p->Rlink,q);
        }
    }
    
    return p;
}

Recorridos
void Arbin::preOrden(Nodo *p){
    if(p != NULL){
        cout << p->info << ", ";
        preOrden(p->Llink);
        preOrden(p->Rlink);
    }
}

void Arbin::inOrden(Nodo *p){
    if(p != NULL){        
        inOrden(p->Llink);
        cout << p->info << ", ";
        inOrden(p->Rlink);
    }
}

void Arbin::postOrden(Nodo *p){
    if(p != NULL){
        cout << p->info << ", ";
        postOrden(p->Llink);
        postOrden(p->Rlink);
    }
}

Estos solo son algunos métodos, pero pueden descargar el ejemplo completo AQUÍAQUÍ.

Debo agradecer mi profesor de estructura de información, Ricardo Contreras por compartir muchos de estos algoritmos que han sido mejorados por el a lo largo de su experiencia como docente.

miércoles, 14 de diciembre de 2011

Animación hecha con Pygame

Esta vez les presento un segundo ejemplo en python usando la librería gráfica Pygame, esta mas organizado que los anteriores y al final podrán encontrar los links para descargarlo completo.
Este ejemplo a diferencia de los anteriores usa sprites animados, dando la sensación de que el personaje camina; cabe aclarar que es un ejemplo muy sencillo ya que el usuario no interactúa es una simple animación, sin embargo es muy fácil hacer que el personaje se mueva con el teclado si se implementa las instrucciones del teclado del ejemplo anterior.

Se divide en dos archivos: sujetos.py y juego.py


sujetos.py

import pygame

class sujeto(pygame.sprite.Sprite):
    """De esta clase heredan los objetos vivientes"""    
    def __init__(self, imagenes):        
        self.imagenes = imagenes        
        self.frame = 0   
        self.indicador = 30     
        self.rect = self.imagenes[self.frame].get_rect()
        self.rect.top = 300
        self.rect.left = 40        
    def move(self, vx,vy):
        self.rect.move_ip(vx,vy)
    def update(self, superficie):
        superficie.blit(self.imagenes[self.frame],self.rect)   
    def nextFrame(self):  
        self.frame = self.indicador % len(self.imagenes) #controla los indices de las imagenes
        self.indicador+=1   #sigue a la imagen siguiente
    def setNewSprites(self,imagenes):
        self.imagenes = imagenes    
        
class Player(sujeto):
    """Clase del heroe"""
    def __init__(self, imagenes):        
        sujeto.__init__(self,imagenes)        
    def getLife():
        return self.life

juego.py

import pygame
import sujetos
import os

# Constantes
ANCHO = 640
ALTO = 480

# Inicializaciones y variables globales
pygame.init()
screen = pygame.display.set_mode((ANCHO,ALTO))
pygame.display.set_caption("SponjeBob Attack")
reloj = pygame.time.Clock()

# Carga las imagenes
def load_img(nombre, directorio):
    ruta = os.path.join(directorio,nombre)
    try:
        image = pygame.image.load(ruta)
    except:
        print "Error! no se puede cargar la imagen"
    return image.convert_alpha()       

imagenesPlayerDer = [load_img("walkr1.png","Res"),load_img("walkr2.png","Res"),
                     load_img("walkr3.png","Res"),load_img("walkr4.png","Res"),
                     load_img("walkr5.png","Res"),load_img("walkr6.png","Res"),]    
imagenesPlayerIzq = [load_img("walkl1.png","Res"),load_img("walkl2.png","Res"),
                     load_img("walkl3.png","Res"),load_img("walkl4.png","Res"),
                     load_img("walkl5.png","Res"),load_img("walkl6.png","Res"),]
imagenFondo = load_img("fondo.png","Res")
                     
# Pinta las imagenes en la pantalla                     
def paint(player):
    screen.blit(imagenFondo,[0,0])
    player.update(screen)
    pygame.display.update()
    player.nextFrame()

def main():   
        
    spritesRight = True
                            
    player = sujetos.Player(imagenesPlayerDer)    
    exit = False   
    vx = 15
    
    while exit != True:     # Bucle principal
        paint(player)        
        player.move(vx,0)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:                
                exit = True                
        # control de los limites   
        if player.rect.left >= ANCHO or player.rect.left <= 0:
            vx=-vx
            if spritesRight == True:  #si mira hacia la derecha
                player.setNewSprites(imagenesPlayerIzq)
                spritesRight = False
            else: #si mira hacia la izquierda
                player.setNewSprites(imagenesPlayerDer)
                spritesRight = True     
        reloj.tick(12)
    pygame.quit()

# INICIO
if __name__ == '__main__':
    main()



Pueden descargar el código completo con las imagenes aquí o aquí. Esos son módulos base para el juego que publicare próximamente, hasta entonces.

viernes, 9 de diciembre de 2011

Mover un Sprite en Python con Pygame

En esta ocasión vamos a modificar nuestro ejemplo anterior para mejorar el movimiento con el teclado, y mover la imagen como un sprite y no como una simple imagen, mas adelante mencionare las ventajas de esto.

import pygame

negro = (0,0,0)
blanco = (255,255,255) 
arriba,abajo,izq,der = False, False, False, False
exit = False 
speed = 10
vx,vy = 0,0  

class Balon(pygame.sprite.Sprite):
    def __init__(self,imagen):
        self.imagen = imagen
        self.rect=self.imagen.get_rect()
        self.rect.top = 300
        self.rect.left = 320
    def move(self,vx,vy):
        self.rect.move_ip(vx,vy)
    def update(self,superficie):
        superficie.blit(self.imagen,self.rect)

def check_keys(event):
    global vx
    global vy
    global abajo
    global arriba
    global izq
    global der
    global exit
    if event.type == pygame.QUIT:
        exit = True                
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_UP:
            arriba = True
            vy-= speed
        if event.key == pygame.K_DOWN:
            abajo = True
            vy+= speed
        if event.key == pygame.K_RIGHT:
            der = True
            vx+= speed
        if event.key == pygame.K_LEFT:
            izq = True
            vx-= speed
    if event.type == pygame.KEYUP:
        if event.key == pygame.K_UP:
            arriba = False
            if abajo == True: vy+=speed
            else: vy=0
        if event.key == pygame.K_DOWN:
            abajo = False
            if arriba == True: vy-=speed
            else: vy=0
        if event.key == pygame.K_RIGHT:
            der = False
            if izq == True: vx-=speed
            else: vx=0
        if event.key == pygame.K_LEFT:
            izq = False
            if der == True: vx+=speed
            else: vx=0
def main():    
    pygame.init()
    screen = pygame.display.set_mode((640,480))    
    reloj = pygame.time.Clock()
    pygame.display.set_caption("Ejemplo")
    imgBalon = pygame.image.load("balon.png").convert_alpha()
    fondo = pygame.image.load("fondo.png").convert_alpha()
    balon = Balon(imgBalon)    
    
    while exit!= True:
        for event in pygame.event.get():
             check_keys(event)                      
        screen.blit(fondo,(0,0))
        balon.move(vx,vy)
        balon.update(screen)
        pygame.display.update() 
        reloj.tick(20)       
    pygame.quit()
    
main()


El código se ordeno en varias funciones, se le coloco un titulo a la ventana, se creo una clase especifica para crear el sprite y se agrego una imagen de fondo, en lugar de color sólido. La ventaja de manejar sprites, es que tenemos el rectángulo de la imagen lo que facilita mas adelante la detección de colisiones, y ademas, el movimiento se hace mas sencillo moviendo el rectángulo con move_ip().

Fuentes: ChelinTutorials, Pygame Doc

Mover una imagen con mouse o teclado - Python (Pygame)

Desde hace poco empece con mis estudios en python, y debo decir que es un lenguaje muy cómodo de manejar y fácil de aprender, navegando por ahí encontré un conjunto de módulos python para la creación de videojuegos en 2D que me llamo mucho la atención y empece a investigar. Pygame funciona como interfaz de las bibliotecas SDL, y está orientado al manejo de sprites; realmente se pueden desarrollar videojuegos rápidamente con Pygame así que decidí hacer algunos post sobre ello.

Lo primero es instalar Pygame, en la pagina oficial http://pygame.org/download.shtml descarga la version para tu sistema operativo, si tienes un SO basado en Unix que no aparece en la lista, descarga el source e instalalo manualmente como se muestra continuación:
Abre una terminal como root y ubícate en el directorio donde descargaste pygame y luego ejecuta los siguientes comandos:
# tar -xzvf pygame-1.9.1release.tar.gz
# cd pygame-1.9.1release
# ./configure
# make
# make install

o en debian/ubuntu pueden usar : $ sudo apt-get install python-pygame 

Teniendo Pygame instalado, comencemos con un ejemplo sencillo donde subimos una imagen y la movemos con el teclado:

import pygame

def main():
    pygame.init() #carga los modulos de pygame
    screen = pygame.display.set_mode([640,480])
    imagen = pygame.image.load("balon.png")
    x,y = 0,0 #coordenadas de la imagen
    vx, vy = 0,0 #velocidad en x - y
    arriba, abajo, izq, der = False, False, False, False
    exit = False
    reloj = pygame.time.Clock()
    azul = (0,0,255)


    while exit!= True:  #ciclo principal
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    arriba = True
                    vy=-10
                if event.key == pygame.K_DOWN:
                    abajo = True
                    vy=10
                if event.key == pygame.K_RIGHT:
                    der = True
                    vx=10
                if event.key == pygame.K_LEFT:
                    izq = True
                    vx=-10
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    arriba = False
                    vy=0
                if event.key == pygame.K_DOWN:
                    abajo = False
                    vy=0
                if event.key == pygame.K_RIGHT:
                    der = False
                    vx=0
                if event.key == pygame.K_LEFT:
                    izq = False
                    vx=0               
        x+=vx
        y+=vy            
        screen.fill(azul)
        screen.blit(imagen,(x,y))        
        pygame.display.update() 
        reloj.tick(20)       
    pygame.quit()
   
main()  

Explicare un poco el cogido: pygame trabaja con superficies, es decir, con capas donde pintaremos nuestros gráficos, entonces es necesario crear la superficie principal (la ventana) con el método set_mode(resolucion) que recibe como parámetro una lista con la resolución deseada.

De la misma manera, el metodo load(archivoDeImagen) nos devuelve una superficie a partir de un archivo que se pasa como parametro, esta superficie es la imagen balón que mas moveremos con el teclado y el mouse.
La variable "azul" define un color RGB que usaremos para pintar el fondo de dicho color con el método fill(color). La variable "reloj" es un objeto especial en pygame que nos ayuda a fijar un delay en la ejecución del juego, con el método tick(FPS) asignamos los fotogramas por segundo que deseamos.

por ultimo, el método blit(imagen,coordenadas) pinta sobre la superficie, otra superficie las coordenadas deseadas, en este caso en la pantalla(screen) pinta la imagen del balón en las coordenadas x-y.

El resto del código son instrucciones que modificar la posición de la imagen en los ejes dependiendo de los eventos presentados, estos eventos se recorren con la instrucción for event in pygame.event.get(): y verifica que tipo de evento ocurrió para luego aplicar la lógica de los movimientos y el evento de tipo pygame.QUIT indica que el usuario ha hecho click en la "x" para salir.



Si quisiéramos mover la imagen con el mouse es mas sencillo, solo deben borrar (o comentar) las lineas del control del teclado (lineas 16-46), los booleanos (linea 9) y el dibujado (linea 48) y agregar esta linea después de pintar el fondo:
screen.blit(imagen,pygame.mouse.get_pos())

Por último, los invito a repasar la documentación de Pygame que esta muy interesante clickAca.

Fuentes: Wikipedia, ChelinTutorials

martes, 6 de diciembre de 2011

Manejo de ficheros en Python

Un ejemplo sencillo sobre ficheros en Python


import os
productos = []

class producto:
    """ Clase para cada producto """
    ID = 0
    nombre = ""
    cantidad = 0
    def __init__(self, ID, nombre, cantidad ):
        self.ID = ID
        self.nombre = nombre
        self.cantidad = cantidad

def registrarProducto():
    os.system('clear')
    print "="*80,"\t\tREGISTRAR PRODUCTO\n","="*80
    p = producto(long(raw_input("ID: ")),raw_input("Nombre:"),
                  int(raw_input("Cantidad: ")))
    productos.append(p)
    try:
        fichero = open("archivo.txt", "a") #abre un fichero existente
    except:
        fichero = open("archivo.txt","w") #se crea el fichero si no existe   
    fichero.write(str(p.ID)+","+p.nombre+","+ str(p.cantidad)+"\n")   
    fichero.close()
   
def verProductos():
    os.system('clear')
    print "="*80,"\t\tLISTA DE PRODUCTOS\n","="*80
    print "ID/Nombre/cantidad\n"
    try:
        fichero = open("archivo.txt","r")
        for linea in fichero:
            print linea.strip()    
        fichero.close()
    except:
        print "El fichero no existe, porfavor creelo"  

def printMenu():   
    print "="*80,"\t\tMENU\n","="*80   
    print "Escoja una opcion: "   
    print "\t1.Registrar un producto"
    print "\t2.Ver lista de productos"
    print "\t3.salir"   
    return raw_input("OPCION: ") 
        
def menu():
    opcion = 0
    while opcion != '3' :       
        opcion = printMenu()               
        if opcion == '1':
            registrarProducto()
        elif opcion == '2':
            verProductos()
menu()
exit()

sábado, 10 de septiembre de 2011

Figlet - Generador de codigo ASCII en consola

"FIGlet es una aplicación informática que genera banners de texto, en varias tipografías, formadas por letras compuestas por conglomerados de caracteres ASCII más pequeños." Wikipedia.


Instalamos esta aplicacion en Debian ( y derivados ) de forma habitual:


Como root:
# apt-get install figlet


y para probarlo ejecutamos: 
# figlet loQueQuieresVer


Ejemplo:

viernes, 9 de septiembre de 2011

Generar el triangulo de Pascal en C

El siguiente código muestra como generar el triangulo de pascal, el truco para imprimirlo es usar " %3".


#include "stdio.h"

int main(int argc, char *argv[]){

   int pasc[11];
   int n=11;
   int x, i, j;

   x=0;

   //valida el numero de lineas
   for (i=1; i<=n ; i++)
   {
         //Construimos el triangulo de pascal
         for (j=x; j>=0; j--)
         {
             if(j==x || j==0)
             {
                  pasc[j] = 1;
             }
             else
             {
                  pasc[j] = pasc[j] + pasc[j-1];
             }
         }

        x++;
        printf("\n");
        //Truco para imprimir el triangulo
        for (j=1; j<=n-i; j++)
             printf("   ");

        for(j=0; j<x; j++)
        {
             printf("%3d   ", pasc[j]);
        }
   }
return 0;
}
El resultado:

lunes, 15 de agosto de 2011

Generar números aleatorios en C

Usando la función rand() para obtener números aleatorios, la primera vez que lo ejecutas esta bien, pero lo ejecutas nuevamente te mostrara la misma serie de números generados anteriormente. Para solucionar esto usaremos la función srand() para cambiar la variable (semilla) en la que se basa rand() para generar los números aleatorios.
Para obtener números aleatorios eficazmente necesitamos una semilla que varia de un instante a otro, por eso usaremos el comando en ensamblador rdtsc, nos retornará el numero de ciclos del procesador desde el inicio.Esta solución funciona únicamente con procesadores x86.


El siguiente código genera 10 números aleatorios:

#include "stdio.h"
#include "stdlib.h"
#include "stdint.h"

__inline__ uint64_t rdtsc();

int main(int argc, char *argv[]) {

    int i;    
    srand(rdtsc());
    for(i=0; i<10; i++)
    {
         printf("%d\n", (int)(16.0 * (rand() / (RAND_MAX + 1.0))));
    }

  return 0;
}
__inline__ uint64_t rdtsc()
{ 
    uint32_t lo, hi;
    __asm__ __volatile__ ("xorl %%eax,%%eax \n cpuid" ::: "%rax", "%rbx", "%rcx", "%rdx");
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    
   return (uint64_t)hi << 32 | lo;
}
Referencia: http://en.wikipedia.org/wiki/Time_Stamp_Counter#C.2B.2B

domingo, 14 de agosto de 2011

Instalando Allegro en Debian 6

Allegro es una biblioteca libre y de código abierto para la programación de videojuegos desarrollada en lenguaje C. La biblioteca cuenta con funciones para gráficos, manipulación de imágenes, texto, sonidos, dispositivos de entrada (teclado, ratón y mandos de juego) y temporizadores, así como rutinas para aritmética de punto fijo y acceso al sistema de archivos.


Para instalar esta libreria en Debian 6 (también aplica para derivados) sigue los siguientes pasos:


1.)Abre el gestor de paquetes Synaptic:


2.) Selecciona e instala los paquetes, escribe “liballegro” sin comillas y selecciona todos los paquetes y luego dale al botón "Aplicar" para que comience  la instalación.




3.)Probando, para cerciorarnos si todo funciona bien compilaremos el siguiente código:

#include "allegro.h"

int main(){
    //iniciamos Allegro
    allegro_init();

    //cargamos el teclado
    install_keyboard();

    //iniciamos modo grafico en ventana con resolución de 640x480
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);

    //imprimimos un mensaje en pantalla
    textout_ex( screen, font, "PINGUINAZOS! presiona una tecla para salir", 5, 5, makecol( 255, 0, 0), -1);
    //esperamos a que se presione una tecla.
    readkey();
    
    return 0;
}
//indica que el programa de Allegro termino, es necesario ponerlo despues del main.
END_OF_MAIN();


Para compilarlo debemos agregar la sentencia `allegro-config --static` como parámetro al compilar, seria algo como esto:


# g++ AllegroDemo.cpp -o allegro `allegro-config --static`
# ./allegro


y este seria el resultado:



Si no tienes Debian u otra distro basada en debian, por ejemplo Fedora o SUSE, puedes usar el gestor de paquetes YUM (en fedora) o YasT (en SUSE) y buscar los paquetes mostrados anteriormente. Si este no es tu caso y tienes alguna otra distro, en el siguiente link encontrarás con un PDF con información acerca de la instalación de Allegro descargando el .tar.gz y compilandolo manualmente.

Estructura de Datos - Agenda con listas ligadas C/C++

En este ejemplo se muestra el manejo de memoria dinámica en C/C++ con listas simples. Dentro del código podemos observar los procesos básicos de la estructura de datos: creación, eliminación, impresión y búsqueda.

En el compilador g++ en GNU/linux nos dice que el uso de la función gets() para leer cadenas de texto es peligroso, por lo tanto las cadenas las tomamos con scanf("%*c%[^\n]", nodo->cadena) que seria equivalente.(leer directamente una cadena con %s con scanf solo nos guarda la cadena hasta que encuentre un espacio, por eso usamos "%*c%[^\n]" , para indicar que guarde hasta que el usuario teclee un Enter.


#include "stdio.h"
#include "stdlib.h"
#include "string.h"

struct agenda
{
      int tel;
      char nombre[30];
      struct agenda *siguiente;
}*inicio = NULL, *nodo = NULL;

void menu();
void agregar_contacto();
void eliminar_contacto();
int listar();
void mostrar_lista();

int main(int argc, char *argv[]){
      
      int opcion = 0;
      
      do
      {    
          menu();  
          fflush(stdin);                     
          scanf("%d", &opcion);         
          
          switch(opcion)
          {
             case 1:
                   agregar_contacto();
                   break;
             case 2:
                   eliminar_contacto();
                   break;
             case 3:
                   mostrar_lista();
                   break;   
             case 4:
                   exit(0); 
                   break;         
             default:
                   printf("\n\a  Error! Opcion invalida...\n\n"); 
                   break;                 
          }  
      
      }while(opcion != 4);
       
      return EXIT_SUCCESS;
}

void menu()
{      
      printf("Seleccione una opcion: \n");
      printf("\t1.Agregar contacto\n");
      printf("\t2.Eliminar contacto\n");
      printf("\t3.Mostrar lista de contactos\n");
      printf("\t4.Salir\n");
      printf("OPCION: ");      
}

void agregar_contacto()
{     
      fflush(stdin);
      struct agenda *aux = NULL;
      nodo = (struct agenda*)malloc(sizeof(struct agenda));
          
      printf("\tNombre: ");      
      scanf("%*c%[^\n]",nodo-> nombre);
      printf("\tTelefono: ");
      if(scanf("%d", &nodo->tel) != 1)
      {
            printf("\n\tError! numero de telefono  \n\n");
            free(nodo);            
            return;   
      }    
      
      if(inicio == NULL)
      {
            inicio=nodo;
            nodo->siguiente = NULL;
      }
      else
      {
            aux = inicio;
            while(aux->siguiente != NULL)
            {
                  aux = aux->siguiente;
            }
            aux->siguiente = nodo;
            nodo->siguiente = NULL;
      }      
      
      return;
}

void eliminar_contacto()
{     
      if(inicio == NULL)
      {
            printf("\nUsted no ha agregado ningun contacto\n\n"); 
            return;          
      }
      
      fflush(stdin);      
      
      struct agenda *aux;      
      int maximo = 0, objetivo = 0, contador = 0;
      bool flag = false;
       
      printf("Ingrese el numero de contacto que desea eliminar: \n");
      maximo = listar();
      
      printf("\n\tELIMINAR: ");
      if(scanf("%d", &objetivo) != 1 || objetivo > maximo || objetivo < 1)
      {
            printf("\n\tError! ha ingresado una opcion invalida \n\n");
            return;
      } 
           
      nodo = inicio;      
      while(!flag)
      {
            contador++;
            if(contador == objetivo ) flag = true;
            else nodo=nodo->siguiente;            
      }      
      
      /* proceso de eliminacion */
       
      if(nodo == inicio)  //si es el primero
      {
            inicio = nodo->siguiente;
            free(nodo);
      }
      else
      {
            aux = inicio;
            while(aux->siguiente != nodo)
            {
                  aux = aux->siguiente;
            }
            aux->siguiente = nodo->siguiente;
            free(nodo);
      }
    
    
}

int listar()
{
      struct agenda *aux = NULL;
      int contador = 0;
            
      for(aux=inicio;aux!=NULL;aux=aux->siguiente)
      {           
            contador++;      
            printf("\t %d.%s \n", contador, aux->nombre);                    
      }
      
      return contador;   
}
void mostrar_lista()
{
      if(inicio == NULL)
      {
            printf("\nUsted no ha agregado ningun contacto\n\n"); 
            return;          
      }
      
      fflush(stdout);
      struct agenda *aux = NULL;
            
      for(aux=inicio;aux!=NULL;aux=aux->siguiente)
      {                 
            printf("-> Nombre: %s\n",aux->nombre);           
            printf("   Telefono: %d\n\n", aux->tel);
            
      }      
}

Como invertir un numero en C

Como el titulo lo indica, como invertimos un numero en C, sin usar arrays:


#include  "stdio.h"
#include  "stdlib.h"

int main(int argc, char *argv[]) 
{ 
      long numero; 
      int digito; 

      printf( " Ingrese numero: " ); 
      scanf( "%ld", &numero ); 

      printf( " Su numeral invertido es: " ); 

      while( numero > 0 ) 
      { 
            digito = numero % 10; 
            numero /= 10; 
            printf( "%d", digito ); 
      } 

      return 0; 
} 
La salida es:

sábado, 13 de agosto de 2011

Interfaz gráfica usando GTK

¿Y como hago la interfaz gráfica?, es tal vez es unas de las primeras preguntas que nos hacemos al migrar a linux, desde windows creábamos ventanas de diferentes maneras, ya sea con wxDevC++, Borland C++ Builder, usando APIs de Windows, etc... En GNU/Linux encontramos también diferentes formas de crear una aplicación con interfaz gráfica de usuario, en esta ocasión mostrare como hacerlo con la biblioteca GTK ("GIMP Tool Kit"), con esta biblioteca se desarrollan en su mayoría aplicaciones para los entornos gráficos GNOME, XFCE y ROX aunque también se puede usar en el escritorio de Windows, MacOS y otros.

Lo primero que debemos hacer es instalar la librería GTK, tecleamos en la terminal como superusario:

En Debian y derivados:
# apt-get install libgtk2.0-dev


En Fedora:
# yum -y install libgtk2.0-dev


Instalado esto, podemos empezar nuestra primera aplicación GTK, les muestro este sencillo ejemplo:
#include "gtk/gtk.h"

void hello( GtkWidget *widget, gpointer data);
int contador_click = 0;

int main(int argc, char *argv[])
{ 
      //Creamos los widget a utilizar, una ventana principal y un boton
      GtkWidget* ventana;
      GtkWidget* boton;
   
      gtk_init(&argc, &argv);//llamada a todas las aplicaciones GTK
   
      //Creamos una nueva ventana y un boton con una etiqueta
      ventana=gtk_window_new(GTK_WINDOW_TOPLEVEL);
      boton = gtk_button_new_with_label ("Imprimir");
   
      //Asignamos el alto de la ventana
      gtk_container_set_border_width (GTK_CONTAINER (ventana), 50);

      /* definimos los eventos. Para la ventana, hacemos que cierre 
       * correctamente al presional el boton de salida "x". Para el boton 
       * hacemos una llamada a la funcion "hola" cuando se le de click*/     
     
      g_signal_connect (boton, "clicked",G_CALLBACK (hello), NULL);
      g_signal_connect(ventana, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
   
      //agregamos el boton a la ventana
      gtk_container_add (GTK_CONTAINER (ventana), boton);
   
      //mostramos los widget
      gtk_widget_show (boton);
      gtk_widget_show(ventana);
   
      gtk_main(); //Controla la salida y espera por un evento a ocurrir
   
      return 0;
}

/* Esta funcion imprime un mensaje en la terminal cada vez que el usuario
 * hace click en el boton */
void hello( GtkWidget *widget, gpointer data)
{
     contador_click++;
     g_print ("Hola Mundo Cruel %d \n", contador_click);
}


Y este es el resultado:



Al compilar manualmente en la terminal deben agregar la librería gtk de la siguiente manera:
g++ interfazGTK.cpp -o pinguinazos `pkg-config --libs gtk+-2.0` `pkg-config --cflags gtk+-2.0`

O puede usar una IDE y adjuntar esos parámetros al proyecto.( ej: Geany, Anjunta).

viernes, 12 de agosto de 2011

Usando Ncurses - Funcion getch y move

Este es mi primera entrada en el blog, no sabia que publicar así que he decidido empezar precisamente por el inicio de mis experiencias al migrar a GNU/Linux. Cuando estaba en segundo semestre en la universidad, en las clases de lenguajes de programación compilábamos código en C bajo dev c++, y unas de las primeros ejercicios que realizó nuestra clase fue un programa que mostraba el código ASCII de cada tecla. Cuando intentaba compilar el código en casa, (bajo Fedora 12 en ese tiempo) me mostraba un error debido a que la función getch() no es ANSI C, ya que pertenece a la biblioteca conio.h creada por Borland que no existe en GNU/linux.
Navegando en internet me encontré con ncurses y resolví mi inquietud de la siguiente manera:

#include "ncurses.h"

int main(int argc, char *argv[]){

      initscr();     
      int t;   
   
      while((t=getch())!=27)
      {
            move(5,0);     
            printw("Codigo ASCII: %d  Caracter: %c \n", t, t);
            move(0,0);
            printw("Presiona ESC para terminar... "); 
       }     
     
      endwin();
      return 0;
}
Al usar ncurses cambiamos un poco la forma de leer datos por el teclado e imprimir por pantalla, en lugar de usar printf y scanf, se usará printw y scanfw que funcionan exactamente de la misma manera.
También hay que tener en cuenta que al usar ncurses, debemos usar la función initscr() para iniciar la pantalla y endwin() para terminar; el getch() funciona exactamente igual que el de conio.h. Por otro lado, también observamos la función move(), con ella podemos posicionar el cursor donde queramos enviándole las coordenadas, seria el equivalente a gotoxy() (también de conio.h).
Y por ultimo no se les olvide al compilar agregar el argumento de la libreria ncurses, quedando de esta manera:
g++ ejemplo.cpp -o demo -lncurses