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;
        }
    }
}



1 comentario: