Mostrando entradas con la etiqueta C#. Mostrar todas las entradas
Mostrando entradas con la etiqueta C#. Mostrar todas las entradas

viernes, 10 de abril de 2015

C#. Tipos de datos

En C# los tipos de datos se pueden agrupar en dos tipos: tipos por valor y tipos por referencia.
Los tipos por valor son int, float, double, struct, enum, etc.
Los tipos por referencia son las clases, interfaces, delegados, arrays, etc.

A los tipos por valor no se les puede asignar el valor null. Sin embargo, estos tipos se pueden convertir en tipos anulables, que pueden representar todos los valores del tipo original y el valor null. Para convertir un tipo por valor en anulable sólo hay que añadir el símbolo ? después del tipo.

int? opcion = null;
...
if (opcion != null) Console.WriteLine("La opcion elegida es: {0}", opcion);
else Console.WriteLine("No se ha elegido una opcion");


El código anterior se puede simplificar considerablemente utilizando el operador ??. En el siguiente ejemplo a la cadena se le asigna el valor anterior al operador ?? si la variable opcion no tiene valor nulo, en caso contrario, se le asigna el valor que hay después de dicho operador.

String respuesta = "La opción elegida es: " + opcion.Value.toString() ?? "No se ha elegido una opción";
Console.WriteLine(respuesta);

lunes, 12 de noviembre de 2012

Hangman

Otro juego muy conocido por todos es  "El ahorcado". El juego consiste en tratar de averiguar una palabra desconocida escogiendo letras que se cree que forman parte de la misma hasta conseguir adivinarla, o hasta que se agota el número de errores que se pueden cometer. En este punto, el dibujo que se podrá ver será un muñeco completo colgando de la horca.
En esta entrada del blog voy a mostrar el código de una pequeña aplicación que he creado recreando este juego. Espero que sirva a alguién para aprender algo. A continuación os muestro el código y también un par de imágenes del resultado final.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Collections;

namespace Hangman01
{
    public partial class Form1 : Form
    {
        enum HangmanParts { None, Head, Trunk, RightArm, LeftArm,
                            RightLeg, LeftLeg };
        //, RightEye, LeftEye, Nose, Mouth
        String palabraGenerada;
        String palabraIntroducida;
        HangmanParts estadoHangman = 0;
        int errores;
        int letrasAcertadas = 0;
        bool juegoFinalizado;

        public Form1()
        {
            InitializeComponent();
            palabraGenerada = "";
            juegoFinalizado = false;
            chkMostrarSolucion.Checked = false;
            txtSolucion.Visible = false;
        }


        //Este método nos permite saber si una determinada letra de la palabra
        //generada por el juego todavía no ha sido visualizada al menos en una
        //de las casillas.
        private bool letraPendienteAdivinar(String letra)
        {
            int pendientes = 0;

            for (int i = 0; i < palabraGenerada.Length; i++)
            {
                if ((((Label)pnlLetras.Controls["lblLetra" + i]).Text.CompareTo("_") == 0) &&
                    palabraGenerada[i].ToString().CompareTo(letra) == 0)
                {
                    pendientes++;
                }
            }
            if (pendientes > 0)
                return true;
            else
                return false;
        }

        //Este método se ejecuta cuando el jugador introduce una palabra para
        //comprobar directamente si es la palabra buscada. Cada letra que
        //no coincida con la palabra generada se considerará un fallo y se
        //actualizará el estado de acuerdo a ello.
        private void btnComprobar_Click(object sender, EventArgs e)
        {
            if (juegoFinalizado == false)
            {
                btnComprobar.Enabled = false;
                //Comparar la palabra generada aleatoriamente con la introducida
                //por el jugador. Para cada letra que coincida en la posición
                //correcta se asignará en el control label correspondiente en pnlLetras
                errores = 0;
                letrasAcertadas = 0;
                palabraIntroducida = txtPalabra.Text;

                if (palabraIntroducida.Length == palabraGenerada.Length)
                {
                    for (int i = 0; i < palabraIntroducida.Length; i++)
                    {
                        if (palabraIntroducida[i].ToString().ToUpper().CompareTo(palabraGenerada[i].ToString()) == 0)
                        {
                            letrasAcertadas++;
                            ((Label)pnlLetras.Controls["lblLetra" + i]).Text = palabraGenerada[i].ToString();
                           
                            //---->>>> <<<<----
                            //Si la letra actual no coincide con ninguna de la palabra generada
                            //que no se haya introducido correctamente
                            if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                marcarBotonLetra(palabraGenerada[i].ToString(), true);
                        }
                        else
                        {
                            errores++;
                            //actualizar gráfico
                            dibujarHangman(++estadoHangman);
                            if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                marcarBotonLetra(palabraIntroducida[i].ToString(), false);
                        }
                        //Si se agotan las oportunidades disponibles se mostrará un mensaje
                        //indicando que el juego ha finalizado y el jugador ha perdido
                        if (errores > (int)HangmanParts.LeftLeg)
                        {
                            lblMensaje.Text = "El juego ha finalizado. PALABRA INCORRECTA!";
                            juegoFinalizado = true;
                            break;
                        }
                    }
                }
                if (palabraIntroducida.Length > palabraGenerada.Length)
                {
                    for (int i = 0; i < palabraIntroducida.Length; i++)
                    {
                        if (i < palabraGenerada.Length)
                        {
                            if (palabraIntroducida[i].ToString().ToUpper().CompareTo(palabraGenerada[i].ToString()) == 0)
                            {
                                letrasAcertadas++;
                                ((Label)pnlLetras.Controls["lblLetra" + i]).Text = palabraGenerada[i].ToString();
                                if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                    marcarBotonLetra(palabraIntroducida[i].ToString().ToUpper(), true);
                            }
                            else
                            {
                                errores++;
                                //actualizar gráfico
                                dibujarHangman(++estadoHangman);
                                if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                    marcarBotonLetra(palabraIntroducida[i].ToString().ToUpper(), false);
                            }
                        }
                        else
                        {
                            errores++;
                            dibujarHangman(++estadoHangman);
                            if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                marcarBotonLetra(palabraIntroducida[i].ToString(), false);
                        }
                        //Si se agotan las oportunidades disponibles se mostrará un
                        //mensaje indicando que el juego ha finalizado y el jugador ha perdido
                        if (errores > (int)HangmanParts.LeftLeg)
                        {
                            lblMensaje.Text = "El juego ha finalizado. PALABRA INCORRECTA!";
                            juegoFinalizado = true;
                            break;
                        }
                    }
                }

                if (palabraGenerada.Length > palabraIntroducida.Length)
                {
                    for (int i = 0; i < palabraGenerada.Length; i++)
                    {
                        if (i < palabraIntroducida.Length)
                        {
                            if (palabraIntroducida[i].ToString().ToUpper().CompareTo(palabraGenerada[i].ToString()) == 0)
                            {
                                letrasAcertadas++;
                                ((Label)pnlLetras.Controls["lblLetra" + i]).Text = palabraGenerada[i].ToString();
                                if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                    marcarBotonLetra(palabraGenerada[i].ToString(), true);
                            }
                            else
                            {
                                errores++;
                                //actualizar gráfico
                                dibujarHangman(++estadoHangman);
                                if (!letraPendienteAdivinar(palabraIntroducida[i].ToString().ToUpper()))
                                    marcarBotonLetra(palabraGenerada[i].ToString(), false);
                            }
                        }
                        else
                        {
                            errores++;
                            dibujarHangman(++estadoHangman);
                            if (!letraPendienteAdivinar(palabraGenerada[i].ToString().ToUpper()))
                                marcarBotonLetra(palabraGenerada[i].ToString(), false);
                        }
                        //Si se agotan las oportunidades disponibles se mostrará un mensaje
                        //indicando que el juego ha finalizado y el jugador ha perdido
                        if (errores > (int)HangmanParts.LeftLeg)
                        {
                            lblMensaje.Text = "El juego ha finalizado. PALABRA INCORRECTA!";
                            juegoFinalizado = true;
                            break;
                        }

                    }
                }


                if ((juegoFinalizado == false) && (letrasAcertadas == palabraGenerada.Length))
                {
                    lblMensaje.Text = "PALABRA CORRECTA!!!";
                    juegoFinalizado = true;
                }
            }
            else
            {
                MessageBox.Show("El juego ha finalizado. Pulse Nuevo para empezar otra vez",
                           "Juego finalizado", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        //Este método se ocupa de deshabilitar los botones correspondientes a
        //las letras que ya han sido pulsadas diferenciando visualmente entre
        //las que corresponden a aciertos y las que corresponden a fallos.
        private void marcarBotonLetra(String letra, bool acertada)
        {
            foreach (Control ctrl in pnlBotones.Controls)
            {
                Button btn = (Button)ctrl;
                if (btn.Text.CompareTo(letra.ToUpper()) == 0)
                {
                    if (acertada == true)
                        btn.Enabled = false;
                    else
                    {
                        btn.Enabled = false;
                        btn.BackColor = Color.Orchid;
                        //dibujarFondoBoton(btn);
                    }
                }
            }
        }

        private void dibujarFondoBoton(Button btn)
        {
            Graphics g = btn.CreateGraphics();

            Pen p = new Pen(Color.Red, 2.5f);
            g.DrawLine(p, 0, 0, btn.Width, btn.Height);
            g.DrawLine(p, 0, btn.Height, btn.Width, 0);
        }

        //Habilita los botones correspondientes a las letras, para mostrarlos en
        //su estado inicial
        private void desmarcarBotonesLetras()
        {
            foreach (Control ctrl in pnlBotones.Controls)
            {
                Button btn = (Button)ctrl;
                btn.ForeColor = Color.FromKnownColor(KnownColor.ControlText);
                btn.BackColor = Color.FromKnownColor(KnownColor.Control);
                btn.Enabled = true;
            }
        }

        //Inicializa el contenido de las etiquetas correspondientes a cada una
        //de las letras de la palabra generada por el juego. El contenido inicial
        //de cada etiqueta es el carácter "_"
        private void limpiarEtiquetasLetras()
        {
            foreach (Control ctrl in pnlLetras.Controls)
            {
                Label lbl = (Label)ctrl;
                lbl.Text = "_";
                lbl.BackColor = Color.FromKnownColor(KnownColor.Control);
            }
        }

        //Acciones a realizar cuanod se pulsa alguno de los botones correspondientes
        //a las letras del alfabeto. Cada uno de estos botones permite que el jugador
        //seleccione cual es la letra que quiere seleccionar a continuación para
        //adivinar la palabra.
        private void btnLetra_Click(object sender, EventArgs e)
        {
            if (juegoFinalizado == false)
            {
                int coincidencias = 0;

                //Obtenemos la letra correspondiente al botón pulsado
                String letra = ((Button)sender).Text;
                String lblLetra = "lblLetra";
                //Comparar cada una de las letras de la palabra generada
                //con la letra pulsada. Para cada una que coincida, mostrar
                //la letra en cuestión como el texto del control label que
                //corresponde en pnlLetras
                for (int i = 0; i < palabraGenerada.Length; i++)
                {
                    if ((palabraGenerada[i].ToString().ToUpper().CompareTo(letra) == 0)
                       && (((Label)pnlLetras.Controls[lblLetra + i]).Text.CompareTo("_") == 0))
                    {
                        ((Label)pnlLetras.Controls[lblLetra + i]).Text = letra;
                        letrasAcertadas++;
                        coincidencias++;
                        marcarBotonLetra(letra, true);
                        if (letrasAcertadas == palabraGenerada.Length)
                        {
                            //Palabra acertada, juego terminado
                            lblMensaje.Text = "El juego ha finalizado. PALABRA CORRECTA!!!";
                            juegoFinalizado = true;
                            return;
                        }
                    }
                }
                if (coincidencias == 0)
                {
                    errores++;
                    dibujarHangman(++estadoHangman);
                    marcarBotonLetra(letra, false);
                    //Si se agotan las posibilidades, mostramos un mensaje
                    //indicando que el juego ha terminado.
                    if (errores >= (int)HangmanParts.LeftLeg)
                    {
                        lblMensaje.Text = "El juego ha finalizado. PALABRA INCORRECTA!";
                        juegoFinalizado = true;
                    }
                }
            }
            else
            {
                MessageBox.Show("El juego ha finalizado. Pulse Nuevo para empezar otra vez",
                    "Juego finalizado", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        //Inicialización del juego. Se inicializan la variables necesarias para
        //establecer el estado inicial del juego.
        private void btnNuevo_Click(object sender, EventArgs e)
        {
            letrasAcertadas = 0;
            errores = 0;
            estadoHangman = 0;
            juegoFinalizado = false;
            btnComprobar.Enabled = true;

            //Borramos limpiamos todos los controles label de pnlLetras
            limpiarEtiquetasLetras();
            //Inicializamos el estado de los botones correspondientes a las letras
            desmarcarBotonesLetras();
            //Limpiamos el contenido de pnlGrafico y dibujamos la parte inicial (la horca)
            dibujarHangman(HangmanParts.None);
            //Generamos aleatoriamente una nueva palabra
            palabraGenerada = generarPalabra().ToUpper();

            txtSolucion.Text = palabraGenerada;
            //Creamos y mostramos un control de tipo Label para cada letra
            //de la palabra generada
            crearEtiquetasPalabra(palabraGenerada.Length);
            //Eliminamos el mensaje anterior (si lo hay)
            limpiarMensaje();
        }
       
        //Este método permite dibujar el muñeco ahorcado que indica el número de
        //errores cometidos por el jugador y el número de errores que todavía puede
        //cometer antes de perder la partida. El método se ocupa de dibujar en el
        //un panel del formulario las partes del muñeco de acuerdo con el estado
        //del juego que recibe como parámetro.
        private void dibujarHangman(HangmanParts estado)
        {
            Graphics g = pnlGrafico.CreateGraphics();
            Pen pHorca = new Pen(Color.Black, 4.5f);
            Pen pCuerda = new Pen(Color.Black, 2.5f);
            Pen pMan = new Pen(Color.Brown, 2f);
            Pen pManFino = new Pen(Color.Brown, 1.5f);

            //Limpiamos el panel para redibujar el ahorcado
            g.Clear(Color.FromKnownColor(KnownColor.ScrollBar));
            //Dibujamos la horca
            g.DrawLine(pHorca, (pnlGrafico.Width / 2)-10, pnlGrafico.Height - 35,
                        (pnlGrafico.Width / 2) + 80, pnlGrafico.Height - 35);
            g.DrawLine(pHorca, (pnlGrafico.Width / 2) + 45, pnlGrafico.Height - 35,
                        (pnlGrafico.Width / 2) + 45, pnlGrafico.Height - 185);
            g.DrawLine(pHorca, (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 183,
                        (pnlGrafico.Width / 2) + 45, pnlGrafico.Height - 183);
            g.DrawLine(pCuerda, (pnlGrafico.Width / 2) + 6, pnlGrafico.Height - 183,
                        (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 160);

            if (estado >= HangmanParts.LeftLeg) {
                //Dibujamos la pierna izda
                g.DrawLine(pMan, (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 80,
                                  (pnlGrafico.Width / 2) - 8, pnlGrafico.Height - 70);
            }

            if (estado >= HangmanParts.RightLeg) {
                //Dibujamos la pierna derecha
                g.DrawLine(pMan, (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 80,
                           (pnlGrafico.Width / 2) + 18, pnlGrafico.Height - 70);
            }

            if (estado >= HangmanParts.LeftArm)
            {
                //Dibujamos el brazo izquierdo
                g.DrawLine(pMan, (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 120,
                           (pnlGrafico.Width / 2) - 8, pnlGrafico.Height - 105);
            }

            if (estado >= HangmanParts.RightArm)
            {
                //Dibujamos el brazo derecho
                g.DrawLine(pMan, (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 120,
                           (pnlGrafico.Width / 2) + 18, pnlGrafico.Height - 105);
            }

            if (estado >= HangmanParts.Trunk)
            {
                //Dibujamos el tronco
                g.DrawLine(pMan, (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 130,
                           (pnlGrafico.Width / 2) + 5, pnlGrafico.Height - 80);
            }

            //if (estado >= HangmanParts.Mouth)
            //{
            //    //Dibujamos la boca
            //    Point pto1 = new Point((pnlGrafico.Width / 2), pnlGrafico.Height - 137);
            //    Point pto2 = new Point((pnlGrafico.Width / 2) + 4, pnlGrafico.Height - 135);
            //    Point pto3 = new Point((pnlGrafico.Width / 2) + 8, pnlGrafico.Height - 137);
            //    Point[] ptosBoca = new Point[] { pto1, pto2, pto3 };
            //    g.DrawCurve(pManFino, ptosBoca);
            //}

            //if (estado >= HangmanParts.Nose)
            //{
            //    //Dibujamos la nariz
            //    g.DrawEllipse(pMan, (pnlGrafico.Width / 2) + 3, pnlGrafico.Height - 146, 2, 5);
            //}
            //if (estado >= HangmanParts.LeftEye)
            //{
            //    //Dibujamos el ojo izdo
            //    g.DrawEllipse(pMan, (pnlGrafico.Width / 2) + 7, pnlGrafico.Height - 152, 8, 4);
            //}

            //if (estado >= HangmanParts.RightEye)
            //{
            //    //Dibujamos el ojo derecho
            //    g.DrawEllipse(pMan, (pnlGrafico.Width / 2) - 6, pnlGrafico.Height - 152, 8, 4);
            //}

            if (estado >= HangmanParts.Head)
            {
                //Dibujamos la boca
                Point pto1 = new Point((pnlGrafico.Width / 2), pnlGrafico.Height - 137);
                Point pto2 = new Point((pnlGrafico.Width / 2) + 4, pnlGrafico.Height - 135);
                Point pto3 = new Point((pnlGrafico.Width / 2) + 8, pnlGrafico.Height - 137);
                Point[] ptosBoca = new Point[] { pto1, pto2, pto3 };
                g.DrawCurve(pManFino, ptosBoca);
                //Dibujamos la nariz
                g.DrawEllipse(pMan, (pnlGrafico.Width / 2) + 3, pnlGrafico.Height - 146, 2, 5);
                //Dibujamos el ojo izdo
                g.DrawEllipse(pMan, (pnlGrafico.Width / 2) + 7, pnlGrafico.Height - 152, 8, 4);
                //Dibujamos el ojo derecho
                g.DrawEllipse(pMan, (pnlGrafico.Width / 2) - 6, pnlGrafico.Height - 152, 8, 4);

                //Dibujamos la cabeza
                g.DrawEllipse(pMan, new Rectangle((pnlGrafico.Width / 2) - 10,
                              pnlGrafico.Height - 160, 30, 30));
            }      
        }

        //Acciones iniciales que se realizan cuando se inicia la aplicación. Poner
        //el juego en el estado inicial.
        private void Form1_Shown(object sender, EventArgs e)
        {
            //Generamos aleatoriamente una nueva palabra
            palabraGenerada = generarPalabra().ToUpper();
            txtSolucion.Text = palabraGenerada;

            //Creamos y mostramos un control de tipo Label para cada letra de la
            //palabra generada
            crearEtiquetasPalabra(palabraGenerada.Length);

            //Dibujamos la parte inicial del gráfico (la horca)
            dibujarHangman(HangmanParts.None);

        }

        //Este método se ocupa de generar las etiquetas que albergan cada una de
        //las letras que componen la palabra generada. Cuando se generan las
        //etiquetas su contenido será el carácter "_" y según avance el juego y según
        //vaya acertando letras el jugador, el contenido de dichas etiquetas irá
        //cambiando a las letras que se corresponden con las letras de la palabra
        //generada en cada momento.
        private void crearEtiquetasPalabra(int longitudPalabra)
        {
            pnlLetras.Controls.Clear();
            txtPalabra.Text = "";

            for (int i = 0; i < longitudPalabra; i++)
            {
                Label lbl = new Label();
                lbl.Name = "lblLetra" + i.ToString();
                lbl.Text = "_";
                //lbl.Text = palabra[i].ToString().ToUpper();
                lbl.Font = new Font(FontFamily.GenericSansSerif, 14f, FontStyle.Bold);
                lbl.Location = new Point(3 + (27 * i), 10);
                lbl.Size = new Size(21, 25);
                lbl.TextAlign = ContentAlignment.MiddleCenter;
                lbl.BackColor = Color.FromKnownColor(KnownColor.ActiveCaption);
                pnlLetras.Controls.Add(lbl);
            }
        }

        //Método que se encarga de obtener de forma aleatoria una palabra de una
        //conjunto de ellas (un fichero de texto es la opción más razonable). De
        //momento, se utiliza un array de cadenas con algunas palabras para realizar
        //las pruebas iniciales.
        private String generarPalabra()
        {
            ArrayList listaPalabras = new ArrayList();
            String linea;
            OpenFileDialog ofd = new OpenFileDialog();
            Random rnd = new Random();

            //String[] palabras = new String[] {"murciélago", "palabra", "elefante" };

            StreamReader sr = new StreamReader(File.OpenRead("listaPalabras.txt"));
            while ((linea = sr.ReadLine()) != null)
            {
                listaPalabras.Add(linea);
            }
            return listaPalabras[rnd.Next(listaPalabras.Count)].ToString();
            //return palabras[rnd.Next(palabras.Length)];
        }

        private void limpiarMensaje()
        {
            lblMensaje.Text = "";
        }

        private void chkMostrarSolucion_CheckedChanged(object sender, EventArgs e)
        {
            if (chkMostrarSolucion.Checked == true)
            {
                txtSolucion.Visible = true;
            }
            else
            {
                txtSolucion.Visible = false;
            }
        }
    }
}


miércoles, 21 de diciembre de 2011

15-Puzzle

Hace unos días empecé a aprender a programar aplicaciones para Android. El primer ejercicio interesante que aparece es crear un juego N-puzzle. Mientras adquiero los conocimientos necesarios en Android para poder llevarlo a cabo y me deshago de la gripe que padezco, he decidido hacerlo en .NET. Es una versión bastante simple (hay que añadir la posiblidad de seleccionar el nivel de dificultad y alguna otra mejora) pero ayuda a practicar algunos conceptos interesantes. El resultado os lo muestro a continuación con el código y las imágenes.




using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace nPuzzle01
{
    public partial class Form1 : Form
    {
        private int indiceHueco = 16;

        public Form1()
        {
            InitializeComponent();
        }

        private void btn_Click(object sender, EventArgs e)
        {
            Button btn;
            String nombre = "";
            int indice = 0;
            int numero = 0;

            //Si el botón no es el hueco
            btn = (Button)sender;
            if ((btn.Tag!=null) && (btn.Tag.ToString() != ""))
            {
                //Comprobamos si el hueco es uno de los botones adyacentes
                nombre = btn.Name;
                indice = Convert.ToInt32(nombre.Substring(nombre.IndexOf('n') + 1));
                numero = Convert.ToInt32(btn.Tag);
           

                if (indice - 1 == indiceHueco)
                {
                    //Cambiamos los contenidos de los botones
                    nombre = "btn" + (indice - 1).ToString();
                    ((Button)pnl.Controls[nombre]).Tag = btn.Tag;
                    ((Button)pnl.Controls[nombre]).BackgroundImage = btn.BackgroundImage;
                    btn.BackgroundImage = null;
                    btn.BackColor = Color.LightGray;
                    indiceHueco = Convert.ToInt32(btn.Name.Substring(nombre.IndexOf('n') + 1));
                    btn.Tag = "";
                }

                if (indice + 1 == indiceHueco)
                {
                    //Cambiamos los contenidos de los botones
                    nombre = "btn" + (indice + 1).ToString();
                    ((Button)pnl.Controls[nombre]).Tag = btn.Tag;
                    ((Button)pnl.Controls[nombre]).BackgroundImage = btn.BackgroundImage;
                    btn.BackgroundImage = null;
                    btn.BackColor = Color.LightGray;
                    indiceHueco = Convert.ToInt32(btn.Name.Substring(nombre.IndexOf('n') + 1));
                    btn.Tag = "";
                }

                if (indice - 4 == indiceHueco)
                {
                    //Cambiamos los contenidos de los botones
                    nombre = "btn" + (indice - 4).ToString();
                    ((Button)pnl.Controls[nombre]).Tag = btn.Tag;
                    ((Button)pnl.Controls[nombre]).BackgroundImage = btn.BackgroundImage;
                    btn.BackgroundImage = null;
                    btn.BackColor = Color.LightGray;
                    indiceHueco = Convert.ToInt32(btn.Name.Substring(nombre.IndexOf('n') + 1));
                    btn.Tag = "";
                }

                if (indice + 4 == indiceHueco)
                {
                    //Cambiamos los contenidos de los botones
                    nombre = "btn" + (indice + 4).ToString();
                    ((Button)pnl.Controls[nombre]).Tag = btn.Tag;
                    ((Button)pnl.Controls[nombre]).BackgroundImage = btn.BackgroundImage;
                    btn.BackgroundImage = null;
                    btn.BackColor = Color.LightGray;
                    indiceHueco = Convert.ToInt32(btn.Name.Substring(nombre.IndexOf('n') + 1));
                    btn.Tag = "";
                }

            }
        }

        private void btnSeleccionar_Click(object sender, EventArgs e)
        {
            Image img;
            OpenFileDialog ofd;
            string ruta = "";
            string nombre = "";

            ofd = new OpenFileDialog();
            if (ofd.ShowDialog()== DialogResult.OK) {
                ruta = ofd.FileName;
                img = Bitmap.FromFile(ruta);

                Bitmap bmp = new Bitmap(300, 300);

                Graphics g = Graphics.FromImage(bmp);
                g.DrawImage(img, 0, 0, 300, 300);

                Bitmap bmp1, img1;

                for (int i = 1; i <= 4; i++)
                {
                    for (int j = 1; j <= 4; j++)
                    {
                        if (!(i == 1 && j == 1))
                        {
                            bmp1 = CropImage(bmp, new Rectangle((((j - 1) * bmp.Width) / 4),
                                (((i - 1) * bmp.Height) / 4), bmp.Width / 4, bmp.Height / 4));
                            img1 = new Bitmap(bmp.Width / 4, bmp.Height / 4);
                            Graphics g21 = Graphics.FromImage(img1);
                            g21.DrawImage(bmp1, 0, 0);
                            nombre = "btn" + (((4-i) * 4) + (5-j)).ToString();
                            ((Button)pnl.Controls[nombre]).BackgroundImage = img1;
                        }
                    }
                }

                //Cargamos el previo de la imagen
                pbPrevio.BackgroundImage = bmp;
                pbPrevio.BackgroundImageLayout = ImageLayout.Stretch;
            }
        }

        public Bitmap CropImage(Bitmap origen, Rectangle seccion)
        {
            //Un bitmap vacío para almacenar la imagen recortada
            Bitmap bmp = new Bitmap(seccion.Width, seccion.Height);
            Graphics g = Graphics.FromImage(bmp);

            //Dibuja el área dada (seccion) de la imagen original
            //en la posición (0,0) del bitmap vacío (bmp)
            g.DrawImage(origen, 0, 0, seccion, GraphicsUnit.Pixel);

            return bmp;
        }
    }
}



martes, 27 de septiembre de 2011

Juego serpiente

He estado repasando temas relacionados con los gráficos en la plataforma .NET y para probar algunas cosas se me ha ocurrido programar un juego al que jugaba cuando empecé a meterme en el mundo de la informática. El juego en cuestión es el de la serpiente (yo lo conocí como Nibbles). La idea es bastante sencilla: se trata de mover por la pantalla un elemento gráfico simulando una serpiente que debe pasar por encima de ciertos puntos donde se encuentra su alimento preferido. Cada vez que un alimento es engullido la serpiente aumenta su tamaño y aparece otro alimento en la pantalla. La serpiente no puede salirse de la pantalla ni chocar consigo misma.
Yo he utilizado C# para programarlo, aunque es muy parecido en Visual Basic o Visual C++. A continuación os muestro el código y también un par de imágenes de su ejecución.

using System;
using System.Timers;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace nibblesCS01
{
    public partial class fNibbles : Form
    {
        List<Punto> path;
        private const int DESPLAZAMIENTO = 5;
        private const int ANCHO_SERPIENTE = 6;
        private const int ANCHO_INICIAL = 180;
        private const int INCREMENTO_ANCHO = 20;
        private const int ALIMENTOS_NECESARIOS = 12;
        private int INTERVALO_TEMPORIZADOR = 100;

        private List<Alimento> alimentos;
        int alimentosComidos;

        public fNibbles()
        {
            InitializeComponent();
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            const int WM_KEYDOWN = 0x100;
            const int WM_SYSKEYDOWN = 0x104;
            Punto pto = new Punto();

            if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
            {
                switch (keyData)
                {
                    case Keys.Right:
                        if (path[path.Count - 1].d != 0)
                        {
                            pto.d = 0;
                            pto.x = path[path.Count - 1].x;
                            pto.y = path[path.Count - 1].y;
                            path[path.Count - 1].d = 0;
                            path.Add(pto);
                        }
                        break;
                    case Keys.Left:
                        if (path[path.Count - 1].d != 1)
                        {
                            pto.d = 1;
                            pto.x = path[path.Count - 1].x;
                            pto.y = path[path.Count - 1].y;
                            path[path.Count - 1].d = 1;
                            path.Add(pto);
                        }
                        break;
                    case Keys.Up:
                        if (path[path.Count - 1].d != 2)
                        {
                            pto.d = 2;
                            pto.x = path[path.Count - 1].x;
                            pto.y = path[path.Count - 1].y;
                            path[path.Count - 1].d = 2;
                            path.Add(pto);
                        }
                        break;
                    case Keys.Down:
                        if (path[path.Count - 1].d != 3)
                        {
                            pto.d = 3;
                            pto.x = path[path.Count - 1].x;
                            pto.y = path[path.Count - 1].y;
                            path[path.Count - 1].d = 3;
                            path.Add(pto);
                        }
                        break;

                    //Datos depuración
                    //case Keys.Enter:
                    //    for (int i = 0; i < path.Count; i++)
                    //    {
                    //        lbl.Text += "(" + path[i].x + "," + path[i].y + "," + path[i].d +") ";
                    //    }
                    //    lbl.Text += " -- ";
                    //    break;

                    //Opción pausar el juego
                    case Keys.P:
                        tTemp.Enabled = !tTemp.Enabled;
                        break;
                }
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void fNibbles_Load(object sender, EventArgs e)
        {
            int xAlimento, yAlimento;

            alimentosComidos = 0;

            alimentos = new List<Alimento>();
            //Inicializar la serpiente
            path = new List<Punto>();
            Punto pto = new Punto(0, 200, 0);
            path.Add(pto);
            pto = new Punto(ANCHO_INICIAL, 200, 0);
            path.Add(pto);

            Random r = new Random(DateTime.Now.Millisecond);
            xAlimento = r.Next((this.Width - 5) / DESPLAZAMIENTO) * DESPLAZAMIENTO;
            yAlimento = r.Next((this.Height - 30) / DESPLAZAMIENTO) * DESPLAZAMIENTO;
            Alimento ptoAlimento = new Alimento(xAlimento, yAlimento, Color.Blue);
            alimentos.Add(ptoAlimento);

            lblAlimentosRestantes.Text = ALIMENTOS_NECESARIOS.ToString();

            //Datos depuración
            //lbl.Text = "[" + ptoAlimento.x + "," + ptoAlimento.y + "] ";

            //Inicializar el temporizador
            tTemp.Tick += new System.EventHandler(OnTimerEvent);
            tTemp.Interval = INTERVALO_TEMPORIZADOR;
            tTemp.Enabled = true;
        }

        //Calcula la longitud de la serpiente en función de los puntos que componen su silueta actual
        private int longitudSerpiente()
        {
            int longitud;

            longitud = 0;
            for (int i = 1; i < path.Count; i++)
            {
                if (path[i - 1].x == path[i].x)
                {
                    longitud += Math.Abs(path[i].y - path[i - 1].y);
                }
                else
                {
                    longitud += Math.Abs(path[i].x - path[i-1].x);
                }
            }
            return longitud;
        }

        //Muestra un punto en la pantalla por cada objeto de tipo alimento guardado en la lista
        //de alimentos
        public void MostrarAlimentos()
        {
            Graphics g = this.CreateGraphics();

            foreach (Alimento al in alimentos)
            {
                g.FillEllipse(Brushes.Blue, al.x - 4, al.y - 4, 8, 8);
            }
        }

        //Manejador del evento correspondiente al vencimiento del temporizador
        //Desplaza la serpiente una posición y la redibuja
        public void OnTimerEvent(object source, EventArgs e)
        {
            //Desplazar la serpiente una posición
            if (DesplazarSerpiente())
            {
                //Limpiar la pantalla y redibujar la serpiente
                MostrarSerpiente();
                MostrarAlimentos();
            }
        }

        //Dependiendo de la dirección del último punto añadido a la ruta, modificar el
        //valor de dicho punto. El primer punto de la ruta debe chequearse para ver si
        //coincide con el valor del segundo, y si es así, eliminar el primero de la ruta
        private bool DesplazarSerpiente()
        {
            Punto pto0 = new Punto();
            Punto pto1 = new Punto();
            Punto ultimoPto = new Punto();
            bool noDesplazarCola;
            int xAlimento, yAlimento;

            pto0 = path[0];
            pto1 = path[1];
            ultimoPto = path[path.Count - 1];
            noDesplazarCola = false;

            //Desplazamos la cabeza de la serpiente en la dirección que corresponda
            switch (ultimoPto.d)
            {
                case 0:  //dcha
                    ultimoPto.x += DESPLAZAMIENTO;
                    break;
                case 1:  //izda
                    ultimoPto.x -= DESPLAZAMIENTO;
                    break;
                case 2:  //arriba
                    ultimoPto.y -= DESPLAZAMIENTO;
                    break;
                case 3:  //abajo
                    ultimoPto.y += DESPLAZAMIENTO;
                    break;
            }
            //Comprobamos si la serpiente se sale de los márgenes o se muerde a sí misma
            if (path[path.Count - 1].x > this.Width - 5 || path[path.Count - 1].y > this.Height - 55 || path[path.Count - 1].x < 0 || path[path.Count - 1].y < 0 ||
                SerpienteSeMuerde())
            {
                tTemp.Enabled = false;
                //this.Refresh();
                MostrarMensaje("GAME OVER!!!", 240, 150, Brushes.DarkRed);
                //MessageBox.Show("GAME OVER");
                return false;
            }

            //Comprobamos si la serpiente se come un alimento
            if (alimentos.Count > 0)
            {
                if (path[path.Count - 1].x == alimentos[0].x && path[path.Count - 1].y == alimentos[0].y)
                {
                    //Come un alimento
                    alimentosComidos++;
                    //Actualizamos el contador de alimentos restantes
                    lblAlimentosRestantes.Text = (ALIMENTOS_NECESARIOS - alimentosComidos).ToString();

                    if (alimentosComidos == ALIMENTOS_NECESARIOS)
                    {
                        tTemp.Enabled = false;
                        MostrarMensaje("CONGRATULATIONS! YOU PASSED THIS LEVEL.", 100, 150, Brushes.DarkGreen);
                        return false;
                    }
                    else
                    {
                        alimentos.RemoveAt(0);
                        noDesplazarCola = true;
                        //Colocamos otro alimento en la pantalla
                        Random r = new Random(DateTime.Now.Millisecond);
                        xAlimento = r.Next((this.Width - 5) / DESPLAZAMIENTO) * DESPLAZAMIENTO;
                        yAlimento = r.Next((this.Height - 55) / DESPLAZAMIENTO) * DESPLAZAMIENTO;
                        Alimento ptoAlimento = new Alimento(xAlimento, yAlimento, Color.Blue);
                        alimentos.Add(ptoAlimento);

                        //Datos depuración
                        //lbl.Text += "*" + path[0].x + "," + path[0].y + "* ";
                        //lbl.Text = "[" + ptoAlimento.x + "," + ptoAlimento.y + "] ";

                    }
                }
            }

            if (noDesplazarCola == false)
            {
                //Desplazamos la cola de la serpiente en la dirección que indica el último punto
                switch (pto0.d)
                {
                    case 0:  //derecha
                        if ((pto0.x + DESPLAZAMIENTO == pto1.x) && (pto0.y == pto1.y))
                        {
                            path.RemoveAt(0);
                        }
                        else
                        {
                            path[0].x += DESPLAZAMIENTO;
                        }
                        break;

                    case 1:  //izda
                        if ((pto0.x - DESPLAZAMIENTO == pto1.x) && (pto0.y == pto1.y))
                        {
                            path.RemoveAt(0);
                        }
                        else
                        {
                            path[0].x -= DESPLAZAMIENTO;
                        }
                        break;

                    case 2:  //arriba
                        if ((pto0.y - DESPLAZAMIENTO == pto1.y) && (pto0.x == pto1.x))
                        {
                            path.RemoveAt(0);
                        }
                        else
                        {
                            path[0].y -= DESPLAZAMIENTO;
                        }
                        break;

                    case 3:  //abajo
                        if ((pto0.y + DESPLAZAMIENTO == pto1.y) && (pto0.x == pto1.x))
                        {
                            path.RemoveAt(0);
                        }
                        else
                        {
                            path[0].y += DESPLAZAMIENTO;
                        }
                        break;
                }
            }
            return true;
        }

        //Comprobamos si la cabeza de la serpiente se cruza con el resto del cuerpo en algún punto
        public bool SerpienteSeMuerde()
        {
            for (int i = 0; i < path.Count - 2; i++)
            {
                if (((path[i].x == path[path.Count - 1].x) && (path[path.Count - 1].y >= path[i].y) && (path[path.Count - 1].y <= path[i+1].y))||
                    ((path[i].x == path[path.Count - 1].x) && (path[path.Count - 1].y <= path[i].y) && (path[path.Count - 1].y >= path[i + 1].y)))
                {
                    return true;
                }
                if (((path[i].y == path[path.Count - 1].y) && (path[path.Count - 1].x >= path[i].x) && (path[path.Count - 1].x <= path[i+1].x)) ||
                    ((path[i].y == path[path.Count - 1].y) && (path[path.Count - 1].x <= path[i].x) && (path[path.Count - 1].x >= path[i + 1].x)))
                {
                    return true;
                }
                if ((path[path.Count - 1].x == path[i].x) && (path[path.Count - 1].y == path[i].y))
                    return true;
            }
            return false;
        }

        //Dibujar líneas punto a punto entre cada dos puntos contiguos almacenados en
        //la ruta
        public void MostrarSerpiente()
        {
            Graphics g = this.CreateGraphics();
            Pen p = new Pen(Brushes.BurlyWood, ANCHO_SERPIENTE);

            this.Refresh();
            if (path.Count > 1)
            {
                for (int i = 1; i < path.Count; i++)
                {
                    g.DrawLine(p, path[i - 1].x, path[i - 1].y, path[i].x, path[i].y);
                }
            }

            //Datos para depuración
            //lbl1.Text = "Xn=" + path[path.Count - 1].x;
            //lbl2.Text = "Yn=" + path[path.Count - 1].y;
            //lbl3.Text = "Xn_1=" + path[path.Count - 2].x;
            //lbl4.Text = "Yn_1=" + path[path.Count - 2].y;
            //lblLong.Text = longitudSerpiente().ToString();

        }

        private void fNibbles_KeyDown(object sender, KeyEventArgs e)
        {
            //SE PODRÍA UTILIZAR ESTE EVENTO EN LUGAR DE SOBREESCRIBIR EL MÉTODO ProcessCmdKey DEL
            //FORMULARIO. AQUÍ NO SE UTILIZA ESTA OPCIÓN.

        //    //Comprobamos si se trata de una flecha
        //    if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down) ||
        //        (e.KeyCode == Keys.Left) || (e.KeyCode == Keys.Right))
        //    {
        //        if (e.KeyCode == Keys.Right)
        //            path[path.Count - 1].d = 0;
        //        if (e.KeyCode == Keys.Left)
        //            path[path.Count - 1].d = 1;
        //        if (e.KeyCode == Keys.Up)
        //            path[path.Count - 1].d = 2;
        //        if (e.KeyCode == Keys.Down)
        //            path[path.Count - 1].d = 3;

        //    }

        }

        private void MostrarMensaje(String mensaje, int x, int y, Brush b)
        {
            Graphics g = this.CreateGraphics();
            Font f = new Font("Arial", 14, FontStyle.Bold);

            this.Refresh();
            g.DrawString(mensaje, f, b , x, y);
        }
    }

 
    //Clase que ayuda a definir la longitud y forma de la serpiente para
    //su impresión en la pantalla

    class Punto
    {
        public int x;
        public int y;
        public int d;  //0(dcha), 1(arriba), 2(abajo), 3(izda)

        public Punto() { }
        public Punto(int _x, int _y, int _d)
        {
            x = _x;
            y = _y;
            d = _d;
        }
    }


    //Esta clase define los alimentos que la serpiente debe ir "comiendo"
    //para avanzar en el juego. En esta versión la propiedad c(color) no
    //se utiliza.

    class Alimento
    {
        public int x;
        public int y;
        public Color c;

        public Alimento() { }
        public Alimento(int _x, int _y, Color _c)
        {
            x = _x;
            y = _y;
            c = _c;
        }
    }

}

martes, 12 de julio de 2011

Almacenar datos en ficheros (I)


Hemos empezado a ver distintos modos de almacenar nuestra información utilizando sistemas informáticos. Durante los primeros intentos de crear bases de datos se utilizaban ficheros de texto. Dos de las técnicas utilizadas eran: asignar una longitud fija a cada campo almacenado, o separar los valores de los distintos campos por comas.
He decidido crear una pequeña aplicación en .NET con un formulario para recoger una serie de datos y, posteriormente, guardar dichos datos utilizando el formato seleccionado. Los ficheros generados se pueden importar para utilizarlos en otras aplicaciones destinadas al manejo y almacenamiento de datos (por ejemplo, sistemas gestores de bases de datos y hojas de cálculo).
La siguiente versión de la aplicación permitirá guardar, consultar y modificar los datos almacenados.
En la imagen siguiente se puede ver el formulario para introducir los datos.

A continuación se pueden ver los resultados obtenidos tras guardar los datos en los distintos formatos definidos (longitud de campos fija y valores separados por comas).


Finalmente, adjunto el código que permite realizar las operaciones requeridas para realizar la tarea que pretendemos.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

/* Método que se ejecuta al pulsar el botón Guardar datos */
private void btnGuardarDatos_Click(object sender, EventArgs e)
{
string cadena = "";
string nombre, apellidos, edad, localidad, codPostal, dni, apodo, fechaNac;
string telefono, numHijos, fumador, estatura, tallaZapato, peso, sueldo;
string lateralidad, comentarios;
string path = "";
FileStream fs = null;

/* Longitud fija de los campos */
if (cboFormato.Text.CompareTo("Longitud fija") == 0)
{
path = "FixedLength.txt";
nombre = txtNombre.Text.PadRight(15);
apellidos = txtApellidos.Text.PadRight(20);
edad = txtEdad.Text.PadRight(3);
localidad = txtLocalidad.Text.PadRight(20);
codPostal = txtCodPostal.Text.PadRight(5);
dni = txtDNI.Text.PadRight(9);
apodo = txtApodo.Text.PadRight(10);
fechaNac = txtFechaNac.Text.PadRight(8);
telefono = txtTelefono.Text.PadRight(9);
numHijos = txtNumHijos.Text.PadRight(2);
fumador = chkFumador.Checked == true ? "1" : "0";
fumador = fumador.PadRight(1);
estatura = txtEstatura.Text.PadRight(4);
tallaZapato = txtTallaZapato.Text.PadRight(2);
peso = txtPeso.Text.PadRight(5);
sueldo = txtSueldo.Text.PadRight(8);
lateralidad = cboLateralidad.Text.Substring(0, 1).PadRight(1);
comentarios = txtObservaciones.Text.PadRight(200);

cadena = nombre + apellidos + edad + localidad + codPostal + dni + apodo + fechaNac + telefono + numHijos;
cadena = cadena + fumador + estatura + tallaZapato + peso + sueldo + lateralidad + comentarios;

MessageBox.Show("*" + cadena + "*");
}

/* Campos separados por comas (CSV) */
if (cboFormato.Text.CompareTo("CSV") == 0)
{
path = "CSV.csv";
nombre = txtNombre.Text.Trim();
apellidos = txtApellidos.Text.Trim();
edad = txtEdad.Text.Trim();
localidad = txtLocalidad.Text.Trim();
codPostal = txtCodPostal.Text.Trim();
dni = txtDNI.Text.Trim();
apodo = txtApodo.Text.Trim();
fechaNac = txtFechaNac.Text.Trim();
telefono = txtTelefono.Text.Trim();
numHijos = txtNumHijos.Text.Trim();
fumador = chkFumador.Checked == true ? "1" : "0";
estatura = txtEstatura.Text.Trim();
tallaZapato = txtTallaZapato.Text.Trim();
peso = txtPeso.Text.Trim();
sueldo = txtSueldo.Text.Trim();
lateralidad = cboLateralidad.Text.Substring(0, 1);
comentarios = txtObservaciones.Text.Trim();

cadena = nombre + "," + apellidos + "," + edad + "," + localidad + "," + codPostal + "," + dni + "," + apodo + "," +
fechaNac + "," + telefono + "," + numHijos + "," + fumador + "," + estatura + "," + tallaZapato + "," + peso +
"," + sueldo + "," + lateralidad + "," + comentarios;

MessageBox.Show("*" + cadena + "*");
}

/* Almacenar los datos en un fichero XML */
if (cboFormato.Text.CompareTo("XML") == 0)
{
/* Próxima versión */
}

if (!File.Exists(path))
{
fs = File.Create(path);
fs.Close();
}
if (File.Exists(path))
{
StreamWriter sw = new StreamWriter(path);
sw.WriteLine(cadena);
sw.Close();
}
}

/* Método auxiliar que divide una cadena con campos de longitud fija y obtiene los
valores correspondientes a cada uno de los campos */
private void fixedLength2form(string cadenaLongFija)
{
string fumador, lateralidad;

fumador = cadenaLongFija.Substring(101,1);
lateralidad = cadenaLongFija.Substring(121,1);

txtNombre.Text = cadenaLongFija.Substring(0, 15); ;
txtApellidos.Text = cadenaLongFija.Substring(15, 20);
txtEdad.Text = cadenaLongFija.Substring(35, 3); ;
txtLocalidad.Text = cadenaLongFija.Substring(38, 20);
txtCodPostal.Text = cadenaLongFija.Substring(58, 5);
txtDNI.Text = cadenaLongFija.Substring(63, 9);
txtApodo.Text = cadenaLongFija.Substring(72, 10);
txtFechaNac.Text = cadenaLongFija.Substring(82, 8);
txtTelefono.Text = cadenaLongFija.Substring(90, 9);
txtNumHijos.Text = cadenaLongFija.Substring(99, 2);
chkFumador.Checked = fumador.CompareTo("1") == 0 ? true : false;
txtEstatura.Text = cadenaLongFija.Substring(102, 4);
txtTallaZapato.Text = cadenaLongFija.Substring(106, 2);
txtPeso.Text = cadenaLongFija.Substring(108, 5);
txtSueldo.Text = cadenaLongFija.Substring(113, 8);
if (lateralidad.CompareTo("D") == 0) cboLateralidad.SelectedIndex = 0;
if (lateralidad.CompareTo("Z") == 0) cboLateralidad.SelectedIndex = 1;
if (lateralidad.CompareTo("A") == 0) cboLateralidad.SelectedIndex = 2;
txtObservaciones.Text = cadenaLongFija.Substring(122, 200);

}

/* Método auxiliar que divide una cadena de campos separados por comas y obtiene los valores
correspondientes a cada uno de los campos almacenados */
private void csv2form(string cadenaCSV)
{
string[] aElementosCadena;
string lateralidad;

aElementosCadena = cadenaCSV.Split(',');
txtNombre.Text = aElementosCadena[0];
txtApellidos.Text = aElementosCadena[1];
txtEdad.Text = aElementosCadena[2];
txtLocalidad.Text = aElementosCadena[3];
txtCodPostal.Text = aElementosCadena[4];
txtDNI.Text = aElementosCadena[5];
txtApodo.Text = aElementosCadena[6];
txtFechaNac.Text = aElementosCadena[7];
txtTelefono.Text = aElementosCadena[8];
txtNumHijos.Text = aElementosCadena[9];
if (aElementosCadena[10].CompareTo("1") == 0) chkFumador.Checked = true;
else chkFumador.Checked = false;
txtEstatura.Text = aElementosCadena[11];
txtTallaZapato.Text = aElementosCadena[12];
txtPeso.Text = aElementosCadena[13];
txtSueldo.Text = aElementosCadena[14];
lateralidad = aElementosCadena[15];
if (aElementosCadena[15].CompareTo("D") == 0) cboLateralidad.SelectedValue = 0;
if (aElementosCadena[15].CompareTo("Z") == 0) cboLateralidad.SelectedValue = 1;
if (aElementosCadena[15].CompareTo("A") == 0) cboLateralidad.SelectedValue = 2;
txtObservaciones.Text = aElementosCadena[16];

}

/* Método que se ejecuta al pulsar el botón Abrir fichero. En este método se abre el fichero
que se corresponde con el método de almacenamiento elegido (longitud fija o valores separados
por comas), se lee la línea que almacena los datos y se obtienen los valores para cada uno
de los campos. */
private void btnAbrirFichero_Click(object sender, EventArgs e)
{
string path = "";
string linea = "";

if (cboFormato.Text.CompareTo("Longitud fija") == 0)
{
path = "FixedLength.txt";
if (File.Exists(path))
{
TextReader tr = new StreamReader(path);
linea = tr.ReadLine();
MessageBox.Show("La línea es: " + linea);
fixedLength2form(linea);
tr.Close();
}
}
if (cboFormato.Text.CompareTo("CSV") == 0)
{
path = "CSV.csv";
if (File.Exists(path))
{
TextReader tr = new StreamReader(path);
linea = tr.ReadLine();
csv2form(linea);
tr.Close();
}
}
}
}
}