Aprende programación






30 sept. 2009

Experimento práctico - Dos cumpleaños en un mismo día


Ayer estube viendo el capítulo de redes y en uno de los comentarios del experto lanza una pregunta. ¿Cuantas personas tienen que haber para que haya un 50% de probabilidad en la que dos personas cumplan los años el mismo día?

http://www.smartplanet.es/redesblog/?p=506

El experto comento que la gente suele decir mucho pero que con 23 personas es suficiente. Esto me extrañó mucho por lo que quise comprobarlo por mi cuenta mediante un algoritmo.

Para ello reiterando la misma operacion de 1 a 30 personas y para cada caso crear números al azar entre 365 y utilizando un HashSet para comprobar si se repite sería suficiente. En menos de 30 líneas se puede comprobar. Dejo aquí el código:

import java.util.HashSet;

public class Main {

   public static void main(String arg[]){
      for (int personas=1;personas<=30;personas++){
      long nRepetidos=0;
      for (int n=0;n<1000;n++){
         HashSet ht=new HashSet();
         boolean bRep=false;
         for (int o=0;o<personas && !bRep;o++){
         int a=(int)((Math.random())*365);
         if (ht.contains(a)){
             bRep=true;
         }else{
             ht.add(a);
             }
         }
         if (bRep)
             nRepetidos++;
         }
         System.out.println("Personas:" + personas + " " + (nRepetidos/10) + "%" );
     }
   }
}



Tras ejecutar este algoritmo el resultado que dió es...
Personas:1 0%
Personas:2 0%
Personas:3 0%
Personas:4 2%
Personas:5 3%
Personas:6 3%
Personas:7 4%
Personas:8 8%
Personas:9 7%
Personas:10 12%
Personas:11 13%
Personas:12 19%
Personas:13 20%
Personas:14 22%
Personas:15 25%
Personas:16 27%
Personas:17 33%
Personas:18 33%
Personas:19 39%
Personas:20 40%
Personas:21 44%
Personas:22 49%
Personas:23 50%
Personas:24 55%
Personas:25 55%
Personas:26 60%
Personas:27 61%
Personas:28 64%
Personas:29 67%
Personas:30 70%

Por lo que en conclusión, el experto estaba en lo cierto. Nunca te acostarás sin saber algo más.



28 sept. 2009

Juego retro en QBasic - Pentris (Tetris de cinco cuadros)


En este post voy a publicar otro juego que hice junto con un amigo cuando era más chaval. En esta ocasión el juego se llama Pentris. Su nombre viene de Tetris pero con fichas de cinco cuadros. Utilizando cinco cuadros aparecen muchas más figuras posibles que el clásico Tetris en el que tiene unicamente 7 figuras diferentes. Las teclas para el control de las figuras son 4,8,6, 2 y Space.

Como es un juego muy antiguo, si lo ejecutais directamente vereis que va muy rápido. Para conseguir que vaya más despacio utilizaremos un emulador de MSDos antiguo. Hay que seguir los siguientes pasos:

1-Descargar e instalar DOSBox.
2-En la opción del menu nueva, ir a DOSBox->Configuración->Editar configuracion.
3-Cambiar la linea cycles=auto por cycles=max. (A mí con esto me va más o menos a la misma velocidad del 486 de 66Mhz).
4-Ejecutar DOSBox en el menú.
5-Escribir "mount c rutadeldirectoriodelPentris"
6-Escribir "c:" y finalmente ejecutar el bat "Pentris"
Y con esto ya estaría.

Una vez más el código fuente está en un fichero .bas. Pero no seais muy críticos al leerlo (fué hace mucho). Que los disfruteis.

24 sept. 2009

Screencast Solo Programadores 146 - Introducción MyMobileWeb


Vamos en este caso con un Screecast un poco distinto a lo habitual. Hace unos años hice un curso de MyMobileWeb en las instalaciones de Telefónica. Este framework era una aplicación orientada a desarrollo web para móviles que se gestaba dentro de la iniciativa Morfeo llevada por Telefónica. Una vez finalizado el curso, pensé que sería buena idea hacer una introducción de como funciona y enseñar algunas demos con las que venian.

Por todo ello, el Screencast se divide en dos partes. En la primera se indica como hay que plantear un proyecto con este framework de manera teórica y en la segunda se muestran las demos que incluyen para ver los componentes.

Actualmente, desconozco el estado del framework. Creo que se quedó en la versión tres. Sin embargo, ahora hay mucha más competencia en este campo y los móviles han mejorado enormemente sus posibilidades por lo que quizá se haya quedado desfasado. (Aunque tampoco lo sé seguro)


21 sept. 2009

JavaHispano Podcast - 056 - Introducción a ZK (Entrevista a Marioko)


Publicado un nuevo número del podcast de javaHispano. En esta ocasión entrevistaremos a Marioko que nos explicará su experiencia con ZK para desarrollo de aplicaciones web RIAA. Durante el podcast explicará algunos componentes y productos, integración con otros frameworks, ajax, realización de informes y, finalmente, hablaremos de la documentación disponible para iniciarse.

Pulsar aquí para ir a la noticia

19 sept. 2009

14 sept. 2009

Screencast Solo Programadores 145 - Bolera en perspectiva con Java


¡Vamos con otro Screencast!. En esta ocasión vamos a programar un videojuego hecho con Java con una proyección de un dibujo en perspectiva. El lenguaje utilizado en esta ocasión es Java con el IDE Netbeans. El juego estará diseñado en coordenadas (x,0,z) ya que y=0 siempre. Al dibujar realizaremos una proyección para que tenga un efecto de profundidas. Adicionalmente, en la parte izquierda de la pantalla volvemos a ver el mismo contenido a vista de pájaro.

Como cosas interesantes de este desarrollo, destacar la caida y rodaje de los bolos cuando se golpean unos con los otros y las líneas rectas de la pista que le dan un aspecto a madera. Decir que no hemos utilizado ninguna herramienta de 3D para dibujar los bolos. Estos se dibujan utilizando una iteración y calculando senos y cosenos. También es interesante el modo de crear degradados bastante artísticos utilizando iteraciones y cambiando progresivamente de color.

El juego consiste el lanzar los bolos pulsando el espacio cuando la trayectoria indicada con la recta roja es la idonea. Esta línea roja se mueve periódicamente de izquierda a derecha y rotando el ángulo de la trayectoria. Existe también una barra de fuerza que incrementará y decrementará periodicamente. El objetivo es darle al botón en el momento exacto (posición, ángulo, fuerza) para tirar los más bolos posibles.

Espero os guste el screencast.

12 sept. 2009

Experimento práctico - Buscando en un directorio con Java


Estaba revisando el Analytics de javaHispano y curiosamente, y no sé por qué, habia un texto desde google que tenia muchas entradas en el que ponia "java buscando en un directorio". Si se busca en Google por ese texto hace referencia a un link de una pregunta en el foro que pretendía esto y muy bién contestada por Rugi.

Por ello, he pensando en ampliar dicha información y preparar un buscador de ficheros utilizando Netbeans 6.7.1 que permite navegar por los directorios y ejecutar un fichero haciendo doble click sobre este. Adicionalmente se puede escribir un texto y buscar en el directorio activo y directorio que cuelgan de este los ficheros que tengan ese texto. Del mismo modo, haciendo doble click sobre los ficheros se pueden ejecutar con el programa predeterminado según su extensión.

Lectura de ficheros de un directorio
Para la lectura de ficheros de un directorio hemos utilizado la clase File. Esta clase permite a través del método listFiles() devolver todos los elementos que existen en la ruta configurada en el File donde se ejecuta. Después para separar los directorios de los ficheros preguntamos a cada unos de los elementos si es un directorio con la función isDirectory(). También para cada elemento hemos utilizado las funciones getName() para ver el nombre del fichero o directorio y getAbsoluteFile() para conocer la ruta. Y en principio no hay mucho más (No es muy complicado).

Buscar por los directorios.
El algoritmo de busqueda también es sencillo. Hemos utilizado un algoritmo recursivo en el que se envia un directorio y obtiene todos los elementos de ese directorio. A continuación recorre los elementos y si encuentra otro directorio ejecuta la llamada a si mismo enviando el nuevo directorio. En caso de ser un fichero se comprueba que el nombre contenga el texto que hemos introducido con la función indexOf. Esta función devuelve la posición donde se encuentra o -1 si no encuentra el texto. Antes de comprobar, convertimos estos textos a mayúsculas para que no sea sensitivo a mayúsculas/minúsculas.

Ejecutandolo con un hilo.
Algo que aborrecí cuando hacia procesos largos y que ejecutaban muchas operaciones en aplicaciones de escritorio era que me dijesen:
- "Oye! Mira a ver que la aplicación se ha colgado."
Tenia que contestar:
- "No se ha colgado. Aún esta haciendo la operación".
Sin embargo, si hacian click por la ventana a veces se quedaba en blanco y volvian a insistir:
- "Que no! Que no! Que se ha quedado colgado. Mira todo en blanco".

En realidad si que estaba ejecutandose las operaciones. La razón de que se quedase la pantalla en blanco es que si se realizan las operaciones con el hilo principal hasta que no se finaliza el proceso no hace otra cosa. Esto incluye repintar la pantalla. Por ello, si en algún momento teneis que programar un proceso que va a costar mucho, es preferible lo hagais en un hilo y a poder ser hagais alguna barra de progresión o alguna animación. Así el usuario se siente más seguro de que está funcionando (aunque sea mentira). En esta aplicación podreis ver que la clase que contiene la busqueda es implements de Runnable y, al iniciar la búsqueda, el algoritmo recursivo se invoca desde el método run(). Otra cosa que puede ser interesante es ir mostrando los resultados o una barra de progresión mientras se realiza la búsqueda. Esto lo hemos programado utilizando el interface Observer de manera que cada vez que encuentra un fichero se ejecuta el método update del Frame y actualiza la lista.

Ejecutar un fichero externo:
Algunas veces, es de nuestro interes lanzar una aplicación externa. Para ello podemos utilizar Runtime.getRuntime().exec. Sin embargo, esto solo sirve para ficheros .exe (en el caso de Windows) pero no sirve para el resto de ficheros (.bmp, .jpg, .mp3, etc). Pero ¿como podemos saber si la aplicación por defecto de cada una de las extensiones?. La respuesta es, "No te preocupes, no hace falta saberlo". Existe un .exe que se encarga de esto llamado rundll32. Si invocas el método .exe de este modo, entiendiendo que sRuta es la ruta del fichero, verás que se abre con el programa predeterminado en el sistema operativo. Comentar que esto solo funcionará bajo Windows
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + sRuta);

Un poco de Swing.
Y finalmente, aunque no voy a explicar nada en este post, si estais interesados en el Swing le podeis dar un vistazo a como hacer para que algo se ejecuta cuando se hace doble click getClickCount(), la clase DefaultListModel, y poco más. La parte gráfica no tiene mucho que podamos destacar.

Pues nada, espero que os sirva de utilidad:

10 sept. 2009

Screencast Solo Programadores 144 - El juego Pong3D con Java3D


A continuación podeis descargar otro screencast en el que vamos a programar un juego basado en el clásico juego Pong. La novedad de este juego es que estará desarrollado con Java3D y la perspectiva de visualización será en primera persona. Además, de la perspectiva 3D, la cámara está situada en la raqueta por lo que cuando mueves la raqueta realmente ves como se mueve el campo entero.

Por último, para poner la guinda, comprobar como la pelota radia una luz verde que ilumina el campo reflejandose en las paredes. Conseguir esto parece fácil: "solo hay que poner una luz verde donde está la pelota". Pero al realizar pruebas, existe una pega. Una superficie solo puede ser de un color al ser iluminada por lo que si creamos una pared gigante utilizando unicamente un rectangulo no veremos como la pelota ilumina unicamente la parte más cercana a esta. Para solventar ese problema en vez de crear un rectangulo por cada pared hemos creado que una pared se componga de pequeños segmentos más pequeños para así que la luz pueda iluminar un espacio de la sala sin que ilumine el otro extremo (al ser el mismo polígono).

Espero que os guste el video.

8 sept. 2009

JavaHispano Podcast - 054 - Noticias Septiembre 2009 (a)


Iniciamos nueva temporada en los podcast de javaHispano una vez pasado el periodo vacacional. Volvemos con las pilas cargadas y con ilusión para este nuevo inicio. Seguiremos con la dinámica de animar a participar a multitud de personas ya que todo el mundo tiene algo que aportar y con la mentalidad de que ninguno de nosotros somos unos cracks pero unidos creamos una sinergia y programa muy rico en opiniones, conocimientos y puntos de vista. También seguiremos entrevistando a personas que tienen menos que ver con la comunidad y con ello enriquecer de conocimiento distinto con perfiles diferentes. Finalmente me gustaría comentar tendremos más personas habituales en el equipo y vamos a intentar crear nuevas secciones aún más atrevidas y arriesgadas para darle al podcast un toque diferente (pero de momento no digo nada que aún está cocinandose la sección).

Por último, quiero invitar a las personas a seguir el podcast durante esta nueva temporada que estoy seguro que estará llena de noticias porque en tiempos de crisis hay muchos cambios y oportunidades (como la compra Oracle-SUN).

Pues nada, aquí teneis este primer número de la temporada...

7 sept. 2009

Screencast Solo Programadores 143 - Algoritmo minimax. Inteligencia artificial para jugar al tres en raya.


En el siguiente screencast vamos a programar un juego del tres en raya y lo realizaremos con una web JSP. Durante el podcast explicaremos como instalar las herramientas necesarias e inicialmente realizaremos un diseño sencillo.

Sin embargo, a medida que vayamos avanzando vamos a programar que podamos jugar contra la máquina utilizando un algoritmo que se emplea en Inteligencia Artificial llamado Minimax. Este algoritmo se parece bastante a los algoritmos de busqueda con heuristica ya que su representación es igualmente en forma de árbol pero con una particularidad. Al ser un juego con adversario la maquina no se puede saber que movimientos va a realizar el jugador ya que aún no has movido. Sin embargo, lo que si se puede hacer es limitar las opciones de victoria. Por ello, en el caso del algoritmo minimax evalua la heuristica del tablero según quien mueve la ficha y asimilando también los movimientos del contrario y busca el mejor valor en su turno (la máxima heurística) y el peor movimiento del contrincario (la minima heurística). De ahí que se llame minimax, de mínimo y máximo. Al pretender recorrer un árbol también hemos utilizado recursividad, al igual que hicimos con la resolución del Sudoku (aunque un árbol también es posible recorrerlo de forma iterativa).

Pues nada, espero que os guste el screencast y aprendais un algoritmo más que se imparte en la asignatura de inteligencia artificial.

5 sept. 2009

Java 3D - Moverse por una casa usando los cursores


A continuación os dejo público una aplicación que hice para otro artículo de la revista "Solo Programadores" programada con Java3D. Esta aplicación consiste en una casa diseñada en una matriz y el usuario es capaz de moverse por esta. Curiosamente este artículo también apareció en portada de la revista lo cual me gustó. Aunque quizá el título que eligieron "Realidad virtual" se salga un poco del objetivo, que era aprender Java3D.


Java3D es un entorno bastante curioso. Consiste en generar un arbol de objetos de manera que cada nodo puede tener unas propiedades de rotación, traslado, escalado o cualquier matriz de transformación que le queramos aplicar. Cuando se aplica una matriz de rotación sobre un nodo todos los objetos que descienden de ese nodo quedan rotados con los mismos grados. Desde el punto de vista real, tiene bastante lógica. Cuando un personaje rota un brazo todo el brazo queda rotado. Pero si a su vez rotamos la muñeca está tendrá aplicada dos rotaciones el correspondiente al brazo y el concreto de la muñeca. En este caso el brazo estaría por encima de la muñeca dentro del diseño del árbol.

Desde el punto de vista del diseño, la casa está compuesta por paredes, puertas, camas y mesas. No es que sea mucho, pero está bién para ser un ejemplo. Claramente no se puede traspasar las paredes, camas y mesas. En el caso de las puertas hay un efecto muy curioso que consiste en que se abra la puerta automaticamente cuando te acercas. Finalmente, podreis ver en un pequeño plano 2D el mapa desde la parte superior para saber exactamente donde estais en cada momento.

Para ejecutarlo disponeis de un fichero Casa3D.bat que os permitirá lanzar la aplicación con el classpath conectado a los ficheros .jar.

2 sept. 2009

Experimento práctico - Resolver un Sudoku en 10 minutos con Java


La semana pasada compré una revista y en esta encontré un concurso que consistía en rellenar un Sudoku hexadecimal (16x16) y enviar el resultado para participar. Con los Sudokus normales (0-9 digitos) suelo tardar 1 o 2 horas en resolverlo o incluso dejarlo sin acabar por lo que no puedo imaginarme cuanto tardaría con este. Sin embargo, la idea de participar en el concurso me pareció atractiva. Así que la solución que opte es hacer un programa que me lo resolviese :). Pues bién, implementar el algoritmo puede costar unos 10 minutos. (He aquí una prueba de eficiencia que demuestra que hay que intentar automatizar todo lo posible en cualquier proyecto de software y evitar hacer las cosas manualmente.)

Algoritmos de búsqueda
Resolver este tipo de problemas mediante un algoritmo es relativamente fácil ya que se puede utilizar multitud de algoritmos de inteligencia artificial como los de busqueda o backtracking. Al hablar de inteligencia artificial parece que estamos hablando de algo complejo por la fama que se le ha dado en el cine. Sin embargo, si no hablo de inteligencia artificial y digo que es hacer que el ordenador pruebe cosas hasta que sale ya parece algo más fácil. Y de hecho tiene más de artificial que de inteligencia :).

La problemática de este tipo de soluciones es la velocidad en resolución en ciertos casos. Al intentar probar todas las posibles combinaciones hay que tener mucho cuidado de que el algoritmo no intente realizar operaciones redundantes o de una gran cantidad de combinaciones para así llegar antes al resultado. Una forma de representar todas las combinaciones es con un árbol o un grafo. En este se dibujar un posible estado (posición del tablero) y una flecha por cada movimiento que se puede realizar de manera que si estás en un estado (nodo) y realizas un movimiento (flecha) llegas a otro estado (nodo). Lo interesante es recorrer ese nodo de manera adecuada y eficiente.


La representación del tablero y variables de optimización
En el caso del Sudoku hexadecimal, hemos representado el tablero en un array de 16x16 y para optimizar hemos creado tres matrices de booleanos de 16x16. Estas matrices sirven para marcar si en una misma fila, columna o recuadro ya hemos puesto ese número y así evitar pasar por estados imposibles del tablero y así ser más eficiente en la busqueda. De esta manera cuando ponemos un número en el tablero, marcamos la correspondiente fila, columna y cuadro para que no lo intente poner en un futuro. Si con ese número no ha funcionado y vamos a probar con otro, liberamos las casillas antes marcadas.

Algoritmos recursivos
Desde el punto de vista de algorítmica, hemos implementado un algoritmo recursivo. Yo personalmente no soy un fan de los algoritmos recursivos, pero tampoco les tengo manía. Tiene sus cosas buenas y malas. Recuerdo que cuando daba clases, la gente entiendía antes un algoritmo no recursivo que un algoritmo recursivo. En un algoritmo no recursivo se vé cuando algo se repite ya que lo estás indicando explícitamente. Un algoritmo recursivo hay que darse cuenta que has hecho una llamada a tí mismo (o de manera indirecta) para darte cuenta que eso se repite. Sin embargo, una vez comprendidos te das cuenta que para recorridos de árboles y gráfos se realizan con menos código.

Pues nada, os dejo el programa para que os lo descargueis. Tiene una matriz Sudoku inicial con valores 0-15 e indicando con -1 las casillas a recorrer. Tras ejecutar el algoritmo recursivo de resolución de Sudokus mostrará la solución. El algoritmo muestra todas las soluciones posibles. En el caso de la revista claramente solo hay una posible solución.

Finalmente un reto fácil para que participeis.
Si os apetece, os puedo proponer un reto de nivel fácil. ¿Como se hace un Sudoku? ¿Quien decide que letras se ponen? Pues bién, no hay un señor que se dedique a poner letras al azar y que salga lo que salga. Para que un Sudoku tenga una única posible solución solo se puede hacer a través de un algoritmo. Hacerlo a ojo sería muy dificil. La propuesta que os hago esta vez para que implementeis es crear un generador de Sudokus hexadecimales que genere el tablero totalmente al azar (tanto de números como de casillas libres) y que al resolverlo solo haya una solución posible (y cada Sudoku tiene combinatoria diferente, no vale utilizar un mismo Sudoku alternando los números o rotarlos 90º). El primero que me lo envié lo publicaremos aquí ... y se me ocurre que se puede preparar una especie de muro o zona con las personas o nicks que primero envían cada reto :)

Aquí podeis descargar el código fuente.

ACTUALIZACION: Sobre el reto, se me olvidaba comentar ... a
demás, se le debe quitar los todos los recuadros posibles (no vale dejar vacio solo un recuadro).