lunes, 4 de abril de 2011

Ejercicio. Implementar el juego del tres en raya (también llamado Tic Tac Toe o "de la vieja")


Programa en C# el juego del tres en raya. Inicialmente vamos a hacerlo para dos jugadores que manejan el ratón, la versión más simple. Ten en cuenta las siguientes consideraciones:

  • Crea una aplicación Windows en Sharp Develop y emplea componentes botón (Button) para representar cada celda del juego.
  • Las celdas tendrán un tamaño de 75x75 pixels.
  • Inicialmente el color de fondo de las celdas será negro.
  • No repitas el código para atender el evento de clic en cada celda. Trata simplemente de recoger una referencia al objeto botón que produjo el evento para manipularlos todos de forma genérica. Esto es, en cada manejador del clic aparecerá: celda =(Button)sender; siendo celda un atributo miembro del formulario de la clase Button.
  • Para poner X o O se cargará la imagen respectiva en el botón. Para cargar una imagen en un botón modifica su atributo Image como en este ejemplo: celda.Image=Image.FromFile("tres_en_raya_O.jpg");

  • Hacer clic sobre una celda en la que ya se ha jugado no debe tener efecto (puedes avisar al jugador mostrando un error en una etiqueta)
  • El juego debe detenerse cuando alguien haya ganado y debe mostrar en una etiqueta quién es el ganador.
  • Debe ser posible reiniciar el juego, una vez acabado o en medio de una partida, mediante un botón de Reset.
  • Debe ser posible elegir el turno inicial.
Una vez que funcione, trata de añadir manejadores de eventos para las teclas, de tal forma que cada jugador pueda jugar indistintamente con el ratón o con el teclado. Para ello puedes suponer la configuración

qwe
asd
zxc

haciendo corresponder a cada celda la letra que ocupa su misma posición. Para recordar cómo manejar eventos de teclado revisa el ejemplo del juego del Pong


Finalmente, habilita una opción para jugar contra la máquina. Para ello, en el turno de la máquina debes simular cierta "inteligencia" que sea capaz de tomar buenas decisiones. Lo ideal sería utilizar el algoritmo del minimax. Haz clic en este enlace y vete a la página 13 del documento para comprobar en qué consiste. Además de una clara explicación de su mecanismo dispones del pseudocódigo para implementarlo recursivamente. Simplemente, trata de adaptarlo a la sintaxis de C#.

Solución con minimax sin heurística: descárgalo aquí


sábado, 2 de abril de 2011

Ejercicio. Extender la aplicación de dibujo

Modifica el código de ejemplo del post anterior para que en el cuadro de lectura de datos de "Figura" se nos pregunte por las coordenadas X e Y de un punto origen y las coordenadas X e Y de un punto destino para dibujar una línea recta.


Haz clic en la imagen para descargar el proyecto con la solución


Ejemplo funcional de aplicación para dibujar gráficos


Haz clic en la imagen para descargar la aplicación de ejemplo que te servirá de base para tus prácticas

viernes, 1 de abril de 2011

Ejemplos. Gráficos

Se puede usar gráficos para mejorar la interface de una aplicación, crear gráficos, reportes y editar imágenes.

Lección 1 - Dibujando gráficos

System.Drawing permite crear gráficos o modificar imágenes. Cambiar de tamaño una imagen, crear círculos, líneas u otras formas, hacer zoom a imágenes, adherir copyright a logos o textos, etc.

Clases:
Bitmap Encapsula un mapa de bits de GDI+, formado por los datos de píxel de una imagen de gráficos y sus atributos. Un objeto Bitmap es utilizado para trabajar con imágenes definidas por datos de píxel.
Brush Las clases derivadas de esta clase base abstracta definen objetos utilizados para rellenar el interior de formas gráficas, como rectángulos, elipses, gráficos circulares, polígonos y rutas.
Brushes Pinceles de todos los colores estándar. No se puede heredar esta clase.
ColorConverter Convierte colores de un tipo de datos a otro. Se tiene acceso a esta clase mediante TypeDescriptor.
ColorTranslator Convierte colores a y de estructuras Color GDI+. No se puede heredar esta clase.
Font Define un formato concreto para el texto, incluidos el nombre de fuente, el tamaño y los atributos de estilo. No se puede heredar esta clase.
FontConverter Convierte objetos Font de un tipo de datos en otro. Se tiene acceso a la clase FontConverter mediante el objeto TypeDescriptor.
FontFamily Define un grupo de tipos de letra que tienen un diseño básico parecido y algunas diferencias de estilo. No se puede heredar esta clase.
Graphics Encapsula una superficie de dibujo GDI+. No se puede heredar esta clase.
Icon Representa un icono de Windows, que es una pequeña imagen de mapa de bits utilizada para representar un objeto. Los iconos se pueden considerar como mapas de bits transparentes, aunque su tamaño lo determina el sistema.
IconConverter Convierte objetos Icon de un tipo de datos en otro. Se tiene acceso a esta clase mediante el objeto TypeDescriptor.
Image Clase base abstracta que proporciona funcionalidad para las clases descendentes Bitmap y Metafile.
ImageAnimator Da animación a una imagen que tiene marcos basados en tiempo.
ImageConverter ImageConverter es una clase que se puede utilizar para convertir objetos Image de un tipo de datos a otro. Se tiene acceso a esta clase mediante el objeto TypeDescriptor.
ImageFormatConverter ImageFormatConverter es una clase que se puede utilizar para convertir colores de un tipo de datos a otro. Se tiene acceso a esta clase mediante el objeto TypeDescriptor.
Pen Define un objeto utilizado para dibujar líneas y curvas. No se puede heredar esta clase.
Pens Lápices de todos los colores estándar. No se puede heredar esta clase.
PointConverter Convierte objetos Point de un tipo de datos en otro. Se tiene acceso a esta clase mediante el objeto TypeDescriptor.
RectangleConverter Convierte rectángulos de un tipo en otro tipo. Se tiene acceso a esta clase mediante TypeDescriptor.
Region Describe el interior de una forma gráfica formada por rectángulos y rutas. No se puede heredar esta clase.
SizeConverter SizeConverter es una clase que se utiliza para convertir un tipo de datos en otro. Se tiene acceso a esta clase mediante el objeto TypeDescriptor.
SolidBrush Define un pincel de un solo color. Los pinceles se utilizan para rellenar formas de gráficos, por ejemplo rectángulos, elipses, gráficos circulares y rutas. No se puede heredar esta clase.
StringFormat Encapsula información de diseño del texto (como interlineado y alineación), manipulaciones de presentación (como inserción de puntos suspensivos y sustitución de dígitos nacional) y características de OpenType. No se puede heredar esta clase.
SystemBrushes Cada una de las propiedades de la clase SystemBrushes es un objeto SolidBrush que es el color de un elemento de presentación de Windows.
SystemColors Cada una de las propiedades de la clase SystemColors es una estructura Color que es el color de un elemento de presentación de Windows.
SystemIcons Cada una de las propiedades de la clase SystemIcons es un objeto Icon de los iconos de todo del sistema de Windows. No se puede heredar esta clase.
SystemPens Cada una de las propiedades de la clase SystemPens es un objeto Pen que es el color de un elemento de presentación de Windows y es un ancho de 1.
TextureBrush Cada una de las propiedades de la clase TextureBrush es un objeto Brush que utiliza una imagen para rellenar el interior de una forma. No se puede heredar esta clase.
ToolboxBitmapAttribute Se puede aplicar un objeto. ToolboxBitmapAttribute a un control de manera que los contenedores, como el Diseñador de formularios de Microsoft Visual Studio, puedan recuperar un icono que represente el control. El mapa de bits del icono puede encontrarse en un archivo por sí solo o incrustado en el ensamblado que contiene el control.
El tamaño del mapa de bits que se incrusta en el ensamblado del control (o que se almacena en un archivo independiente) debe ser de 16 por 16. El método GetImage de un objeto ToolboxBitmapAttribute puede devolver la imagen pequeña de 16 por 16 o una imagen grande de 32 por 32 creada mediante un ajuste de escala de la imagen pequeña.

Como especificar el tamaño y ubicación de un control.
El uso más común de System.Drawing es especificar la ubicación de algún control, cuando se está creando de manera dinámica (por código).
Para realizarlo se crea un punto al que se le pasa dos parámetros (distancia desde arriba, distancia desde el lado izquierdo) para setear la propiedad Location del control.
Ejemplo
clip_image001
Una forma alternativa se puede setear directamente las propiedades left y top del control.
clip_image002
También es posible especificar el tamaño:
clip_image003
Como especificar el color de los controles
Para modificar los colores de un control, se puede utilizar la estructura Color de la siguiente forma:
clip_image004
Si es que se necesita especificar un color personalizado, se puede utilizar el método Color.FromArgb():
clip_image005
Como dibujar líneas y formas
Para dibujar en un formulario o en un control, se deben de seguir los siguientes pasos:
1. Crea un objeto Graphics llamando al método system.Windows.Forms.Control.CreateGraphics
2. Crear un objeto Pen
3. Llamar al miembro de Graphics para dibujar en el cotrol, usando el Pen.
Una vez que se ha creado el objeto graphics, se puede utilizar muchos métodos para mejorarlo como
Clear Borra la superficie de dibujo y la rellena con el color de fondo especificado.
DrawEllipse Dibuja una elipse definida por un rectángulo delimitador especificado por un par de coordenadas, un valor de alto y un valor de ancho.
DrawIcon
Dibuja la imagen representada por el Icon especificado en las coordenadas
Señaladas.
DrawIconUnstretched
Dibuja la imagen representada por el Icon especificado sin transformar a escala la imagen.
DrawImage Dibuja la Image especificada en la ubicación que se indique y con el tamaño original.
DrawLine Dibuja una línea que conecta los dos puntos especificados por los pares de coordenadas.
DrawLines Dibuja una serie de segmentos de línea que conectan una matriz de estructuras Point.
DrawPath Dibuja un GraphicsPath.
DrawPie Dibuja una forma circular definida por una elipse determinada por un par de coordenadas, unos valores de ancho y alto y dos líneas radiales.
DrawPolygon Dibuja un polígono definido por una matriz de estructuras Point.
DrawRectangle Dibuja un rectángulo especificado por un par de coordenadas, un valor de ancho y un valor de alto.
Drawrectangles Dibuja una serie de rectángulos especificados por las estructuras Rectangle.
DrawString Dibuja la cadena de texto especificada en la ubicación especificada y con los objetos Brush y Font especificados.
Para especificar cualquiera de esos métodos se debe proveer una instancia de la clase Pen. En el constructor de Pen (lapiz), se especifican el color y width en pixeles:
clip_image006
Métodos como Graphics.DrawLines, Graphics.DrawPolygon, Graphics.DrawRectangles, aceptan arreglos de puntos como parámetros, para crear figuras más complejas.


Como personalizar Pens?
Además de controlar el color y el tamaño del pen (lapiz), que se especifican en el contructor, también se puede controlar el patrón y su endcap. Endcap es el final de una línea, pueden ser utilizados para crear flechas.
Para crear un lapiz que dibuje líneas punteadas, se debería de setear la propiedad de Pen.DashStyle a uno de los siguientes valores:
  • · DashStyle.Dash (guion)
  • · DashStyle.DashDot (guion punto)
  • · DashStyle.DashDotDot (guion punto punto)
  • · DashStyle.Dot (punto)
  • · DashStyle.Solid. (solido)
Ejemplo
clip_image007
Tambien es posible utilizar Pen.DashOffset y Pen.DashPattern para definir patrones dash(guion).
Para crear flechas, uno debe de modificar las propiedade Pen.StartCap y Pen.EndCap, utilizando el enumerador LineCap, que tiene valores como:
  • · LineCap.ArrowAnchor
  • · LineCap.DiamonAnchor
  • · LineCap.SquareAnchor
  • · LineCap.Triangle
  • · LineCap.Flat
  • · LineCap.Round
  • · LineCap.RoundAnchor
  • · LineCap.Square
Ejemplo:
clip_image008

Como llenar formas?
La mayoría de los métodos de la clase grafics tiene también un método llamado fill que dibuja una forma (shape) y la rellena. Estos métodos requieren una instancia de la clase Brush, la cual es abstracta, entonces se debe de instanciar una clase hija:

System.Drawing.Drawing2D.HatchBrush define un rectangular brush con un estilo hatch
System.Drawig.Drawing2D.LinearGradientBrush encapsula un brush con un gradiente lineal.
System.Drawing.Drawing2D.PathGradientBrush igual que el anterior, solo que provee un llenado más complejo
System.Drawing.SolidBrush Define un Brush de un color simple.
System.Drawing.TextureBrush define un Brush desde una imagen
Ejemplo:
clip_image009


Lección 2 – trabajando con imágenes

System.Drawing.Image es una clase abstracta que permite crear, cargar, modificar y grabar imágenes, como BMP, jpg o tif.
La clase Image es abstracta, por lo tanto se debe de crear una instancia usando Image.FromFile, el cual recibe como parámetro un path a la imagen, y Image.FromStream, que recibe un System.IO.Stream como parámetro.
También se pueden utilizar dos clases que heredan de la clase Image:
System.Drawing.Bitmap (para imágenes) y System.Drawing.Imaging.Metafile (para imágenes animadas).
Bitmap es la clase mas usada comúnmente para trabajar con imágenes. Los diferentes constructores de Bitmap, permiten crear un Bitmap a partir de una Imagen, archivo o stream, o sino crear un bitmap en blanco con un height (alto) y width(ancho) especificado. Bitmap contiene 2 metodos importantes que la clase Image carece:
  • GetPixel, el cual devuelve un objeto Color, con los colores de ese pixel.
  • SetPixel, setea el color de un pixel.

Como mostrar imágenes?
Para mostrar una imagen guardada en el disco, se debe utilizar Image.FromFile, crear un control PictureBox y usar la imagen para definir PictureBox.Background:
Por ejemplo, para mostrar una image:
clip_image010
Para colocar una imagen como el fondo de un form:
clip_image011

Como crear y guardas imagines?
Para crear una imagen nueva, se debe generar una intancia de la clase Bitmap (uno de los constructores que no requiere una imagen existente, con el método Bitmap.SetPixel o editar una existente usando Graphics.FromImage).
Para grabar una imagen, el Bitmap usa su método Bitmap.Save, ( que recibe como primer parámetro el nombre del archivo y como segundo el formato en que se desea almacenar la imagen).
Ejemplo:
clip_image013

Como usar Iconos?
Los iconos son bitmaps transparentes, de un tamaño especifico, para expresar el estado en Windows. Una forma simple de agregar iconos a un form es con los métodos Graphics.DrawIcon o Graphics.DrawIconUnstretched:
clip_image014
O
clip_image015
Se puede editar un Icono, llamando al método Icon.ToBitmap para crear un bitmap que puede ser editado.

Lección 3 – Formateando texto


Como adherir texto a gráficos?
Para agregar texto a una imagen, debemos:
1. Crear un objeto graphics
2. Crear un objeto Font
3. crear un objeto Brush (opcional)
4. Utilizar el método Graphics.DrawString y especificar la ubicación del texto.


Como crear un objeto Font?
La clase fonts tiene 13 sobrecargas de su contructor, el más simple es pasarle la familia de la fuente(string) ej: “arial”, el tamaño (float/int)y el estilo (fontStyle).
Ejemplo:
clip_image016
O pasándole un FontFamily
clip_image017
Y si necesitamos leer el tipo de fuente desde un string, se puede usar la clase FontConverter (no es muy recomendada porque puede generar errores)
clip_image018


Como escribir texto?
Después de crear un objeto font, se debe crear un brush para definir cómo se va a rellenar el texto. Para agregar el texto a una imagen se llama a Graphics.DrawString:
clip_image019


Como controlar el formateo de texto?
.Net framework brinda control sobre la alineación y dirección del texto usando la clase StringFormat.
Los miembros más importantes de StringFormat son:
image
Ejemplo de utilización de StringFormat:

clip_image020

jueves, 31 de marzo de 2011

Ejercicio. Servicio web que calcula la letra del DNI


Crea un servicio web y una interfaz que lo use en la que, introduciendo el DNI de una persona, obtenemos su letra correspondiente.

NOTA: Puedes consultar el algoritmo necesario y servirte del código de este link

Ejercicio. Consultar información de códigos IANA


Utiliza el siguiente servicio web, http://xmethods.com/ve2/ViewListing.po;jsessionid=eNKpjiPDB3WDG5g4ePRdh4uL?key=467143, para crear una interfaz web en la que dado el dominio primario de internet de un país (código IANA) nos muestre su nombre, latitud y longitud.

Ejercicio. Habilitar acceso por login.


A la aplicación web del último ejemplo posteado ("Consulta de notas de un alumno") vamos a incluirle un control de acceso de manera que sólo el usuario que nosotros registremos pueda utilizarla. Sigue los pasos:

Primero vamos a crear el formulario para loguearnos:
  1. Abre la solución de consulta de notas de un alumno.
  2. En el explorador de soluciones haz clic con el botón derecho del ratón sobre la raíz del árbol de exploración que representa el proyecto y selecciona la opción "Agregar nuevo elemento"
  3. En el cuadro de diálogo selecciona "Web Forms" y ponle como nombre "Login.aspx". Recuerda marcar C# como lenguaje de nuestro nuevo Web Form.
  4. Accede a la vista diseño de Login.aspx e inserta un objeto "Login". Lo encontrarás en el cuadro de herramientas, en el subgrupo "Inicio de sesión"
Ahora, para proteger el conjunto de nuestra aplicación la meteremos en una subcarpeta dentro del sitio:
  1. En el explorador de soluciones haz clic con el botón derecho del ratón sobre la raíz del árbol de exploración que representa el proyecto y selecciona la opción "Nueva carpeta". Ponle de nombre "Aplicacion".
  2. Arrastra los archivos que forman parte de la aplicación a la nueva subcarpeta, esto es, "ConsultarNotas.aspx" y "ResultadoForm.aspx". No obstante, no arrastres el archivo "web.config"
Nos queda crear un usuario y darle los permisos apropiados:

  1. Vuelve a la vista diseño de Login.aspx, selecciona el control Login y haz clic en la fecha de la parte superior derecha para abrir sus opciones. Selecciona "Administrar sitio web"
  2. Se abrirá una ventana de configuración en el navegador.
  3. En la pestaña "Página principal" haz clic en "Seguridad".
  4. Ahora, haz clic en "Utilice el Asistente para la configuración de seguridad para configurar la seguridad paso a paso" y se iniciará un asistente de configuración.
  5. El paso 1 es la bienvenida. Simplemente haz clic en "Siguiente"
  6. En el paso 2, "Seleccionar método de acceso", marca la opción "Desde Internet". Haz clic en "Siguiente"
  7. Ignora los pasos 3 y 4 pulsando en "Siguiente"
  8. En el paso 5, "Agregar nuevos usuarios", te aparecerá un formulario para crear un nuevo usuario. Rellena todos los campos y haz clic en "Siguiente"
  9. El paso 6 te permite añadir reglas de acceso. Tenemos que centrarnos en la subcarpeta que queremos proteger, esto es, la subcarpeta "Aplicacion". Así que selecciónala en el árbol de la izquierda expandiendo primero el nodo principal (clic en el símbolo [+]).
  10. Debes añadir dos reglas: la primera que deniegue el permiso a los usuarios anónimos y la segunda que permita el acceso al usuario que creaste en el paso 5. No olvides pulsar el botón "Agregar esta regla" una vez configuradas las opciones para que quede guardada.
  11. Al hacer clic en "Siguiente" habrás terminado la configuración.
Finalmente, añadimos unos pequeños ajustes al archivo "web.config". En realidad, ahora tendrás dos "web.config". Si haces clic con el botón derecho en la carpeta "Aplicación" en el explorador de soluciones y seleccionas la opción "Actualizar carpeta" verás que el asistente te ha añadido un archivo "web.config" en la subcarpeta. Si lo abres verás las reglas de acceso definidas:

Aclarado esto, vamos a abrir el otro "web.config", el que está en la raíz del sitio web y busca la etiqueta . Como puedes observar, está cerrada, no se ha incluido nada en ella. Simplemente ábrela y añade las siguientes etiquetas para indicar la página de login a la que debe redirigirnos la aplicación en caso de que intentemos acceder a un recurso protegido sin habernos logueado así como la página por defecto a la que se redirigirá el flujo una vez que el login ha tenido éxito.



Ya puedes ejecutar la aplicación y comprobar que funciona. Es importante que limpies las cookies del navegador entre prueba y prueba porque puede suceder que pienses que la aplicación te está dejando acceder directamente a la página protegida sin haber hecho login cuando quizás no haya expirado el tiempo máximo de login de un acceso correcto anterior.

Debes verificar que:

  1. Si escribes la URL de la página "ConsultarNotas.aspx" en el navegador, te redirige a la página de login.
  2. Si ingresas correctamente el usuario y la contraseña te redirige a la aplicación para consultar las notas.
  3. Puedes seguir accediendo a "ConsultarNotas.aspx" aunque cierres la pestaña del navegador y vuelvas a entrar, pero siempre dentro del límite de tiempo establecido en el archivo de configuración.