Bienvenido, invitado ( Identificarse | Registrarse )

 
Reply to this topicStart new topic
Maquinas de estados finitos, Inteligencia artificial
hdstryOwrld
mensaje Mar 11 2010, 04:55 AM
Publicado: #1


Administrador
Ícono de Grupo

Grupo: VIP
Edad: 20
Temas por día: 0.37
Mensajes: 353
Hora local: Jul 31 2010, 06:23 AM
Registrado: 26-December 07
Desde: México
Miembro No.: 1



Si lo sé hace mucho tiempo que no escribia pero bien ahora con mi poco tiempo vengo acá a traerles un ejemplo de simulación de inteligencia artificial, es un código en C# que maneja en práctica lo que se conocen como maquinas de estados finitos, la explicación y la documentación viene perfecta dentro del código fuente que incluyo en adjunto, espero les sea de utilidad. Cualquier duda ya saben esto a sus órdenes.

Clase CMaquina:

CÓDIGO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MEF
{
    class CMaquina
    {
        /// <summary>
        /// Estructura que posee los elementos que conforman los objetos que recogera el robot
        /// </summary>
        public struct S_objeto
        {
            public bool Activo; //¿El objeto se encuentra activo?
            public int x, y; //Coordenadas del objeto
        };

        /// <summary>
        /// Enumeración que posee los estados que pueden ocurrir veasé tabla de transiciones
        /// </summary>
        public enum estados
        {
            BUSQUEDA,
            NBUSQUEDA,
            IRBATERIA,
            RECARGAR,
            MUERTO,
            ALEATORIO
        };

        private int state;

        public estados strEstado;

        /// <summary>
        /// Representa el estado en el que se encuentra el robot
        /// </summary>
        public int Estado
        {
            get
            {
                return (int)state;
            }
            set
            {
                state = (int)value;
            }
        }

        /// <summary>
        /// Representa la coordenada eje x de la posición del robot
        /// </summary>
        public int x
        {
            get;
            set;
        }

        /// <summary>
        /// Representa la coordenada eje x de la posición del robot
        /// </summary>
        public int y
        {
            get;
            set;
        }

        /// <summary>
        /// Contiene las instancias de los objetos
        /// </summary>
        public S_objeto[] objetos;

        //Número de baterias a crear
        public S_objeto baterias;

        //Indice del elemento que buscamos [Inicialmente ninguno]
        private int index = -1;

        //Energía actual del robot
        private int energia = 400;

        /// <summary>
        /// Constructor de la clase que crea las instancias de los objetos
        /// </summary>
        /// <param name="nObjetos">número de objetos a crear</param>
        public CMaquina(int nObjetos)
        {
            objetos = new S_objeto[(int)nObjetos];
            Estado = (int)estados.NBUSQUEDA; //Inicialmente comenzamos buscando el objeto
            //Coordenadas del robot
            x = 320;
            y = 240;
        }

        public void Inicializar()
        {
            Random random = new Random();

            //Recorremos todos los objetos
            for (int i = 0; i < objetos.Length; i++)
            {
                //Colocamos las coordenadas de los objetos
                objetos[i].x = random.Next(0, 639);
                objetos[i].y = random.Next(0, 479);

                //Lo indicamos activos
                objetos[i].Activo = true;
            }

            //Colocamos la batería
            baterias.x = random.Next(0, 639);
            baterias.y = random.Next(0, 479);
            baterias.Activo = true;
        }
        /// <summary>
        /// Esta función es el núcleo central del proceso a la que llamara el timer cuando genere su evento
        /// </summary>
        public void control()
        {
            switch (Estado)
            {
                case (int)estados.BUSQUEDA:
                    Busqueda();//Se lleva a cabo la operación

                    //Verificamos si existe transición
                    if (x == objetos[index].x && y == objetos[index].y)
                    {
                        //Se encontro un nuevo objeto abra que desactivarlo
                        objetos[index].Activo = false;

                        //Cambiamos de estado
                        Estado = (int)estados.NBUSQUEDA;
                    }
                    else if (energia < 400)
                    {
                        //Chequeamos la condición de transisión
                        Estado = (int)estados.IRBATERIA;
                    }
                break;
                case (int)estados.NBUSQUEDA:
                    NBusqueda();
                    if (index == -1)
                    {
                        //Ya no hay más objetos pasamos al estado aleatorio
                        Estado = (int)estados.ALEATORIO;
                    }
                    else
                    {
                        //A buscar
                        Estado = (int)estados.BUSQUEDA;
                    }
                break;
                case (int)estados.IRBATERIA:
                    IrBateria();
                    if (baterias.x == x && baterias.y == y)
                    {
                        //Encontro la bateria hay que recargar
                        Estado = (int)estados.RECARGAR;
                    }
                    else if (energia == 0)
                    {
                        //Acabo el programa
                        Estado = (int)estados.MUERTO;
                    }
                break;
                case (int)estados.RECARGAR:
                    Recargar();
                    Estado = (int)estados.NBUSQUEDA;
                break;
                case (int)estados.ALEATORIO:
                    Aleatorio();
                    if (energia < 400)
                    {
                        Estado = (int)estados.IRBATERIA;
                    }
                    else if (energia == 0)
                    {
                        Estado = (int)estados.MUERTO;
                    }
                break;
                case (int)estados.MUERTO:
                    Muerto();
                    //no hay más transiciones
                break;
            }
            strEstado = (estados)Estado;
        }

        /// <summary>
        /// Realiza las operaciones del estado búsqueda
        /// </summary>
        private void Busqueda()
        {
            //Lógica del estado búsqueda

            //Nos acercamos al objeto
            if (x < objetos[index].x)
            {
                x++;
            }
            else if (x > objetos[index].x)
            {
                x--;
            }

            if (y < objetos[index].y)
            {
                y++;
            }
            else if (y > objetos[index].y)
            {
                y--;
            }

            //A cada paso disminuimos la energía
            energia--;
        }

        /// <summary>
        /// Realiza las operaciones del estado nueva búsqueda
        /// </summary>
        private void NBusqueda()
        {
            //Lógica del estado nueva búsqueda
            //Hay objeto?
            index=-1; //Damos por hecho que no
            for (int i = 0; i < objetos.Length; i++)
            {
                if (objetos[i].Activo)
                {
                    //Si hay objeto activo... a por el
                    index = i;
                }
            }
        }

        /// <summary>
        /// Realiza las operaciones del estado ir a bateria
        /// </summary>
        private void IrBateria()
        {
            //Lógica del estado ir por batería
            if (x < baterias.x)
            {
                x++;
            }
            else if (x > baterias.x)
            {
                x--;
            }

            if (y < baterias.y)
            {
                y++;
            }
            else if (y > baterias.y)
            {
                y--;
            }

            //Disminuimos la energía
            energia--;
        }

        /// <summary>
        /// Recargar la bateria
        /// </summary>
        private void Recargar()
        {
            //Lógica del estado recargar
            energia = 1000;
            System.Threading.Thread.Sleep(500);
        }

        /// <summary>
        /// Entra en el estado de aleatorio
        /// </summary>
        private void Aleatorio()
        {
            //Lógica del estado aleatorio
            //Creamos un objeto para generar valores aleatorios
            Random random = new Random();

            int nx = random.Next(0, 3);
            int ny = random.Next(0, 3);

            //Modificamos la posición al azar
            x += nx - 1;
            y += nx - 1;
            energia--;
        }

        /// <summary>
        /// Ya el objeto muere y finaliza el programa
        /// </summary>
        private void Muerto()
        {
            //Lógica del estado muerto
        }
    }
}



Código del formulario
CÓDIGO
namespace MEF
{
    partial class frmMain
    {
        /// <summary>
        /// Variable del diseñador requerida.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Limpiar los recursos que se estén utilizando.
        /// </summary>
        /// <param name="disposing">true si los recursos administrados se deben eliminar; false en caso contrario, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Código generado por el Diseñador de Windows Forms

        /// <summary>
        /// Método necesario para admitir el Diseñador. No se puede modificar
        /// el contenido del método con el editor de código.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.archivoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.salirToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.iniciarToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.iniciarToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
            this.pararToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.tmrCerebro = new System.Windows.Forms.Timer(this.components);
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            //
            // menuStrip1
            //
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.archivoToolStripMenuItem,
            this.iniciarToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(692, 24);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            //
            // archivoToolStripMenuItem
            //
            this.archivoToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.salirToolStripMenuItem});
            this.archivoToolStripMenuItem.Name = "archivoToolStripMenuItem";
            this.archivoToolStripMenuItem.Size = new System.Drawing.Size(55, 20);
            this.archivoToolStripMenuItem.Text = "&Archivo";
            //
            // salirToolStripMenuItem
            //
            this.salirToolStripMenuItem.Name = "salirToolStripMenuItem";
            this.salirToolStripMenuItem.Size = new System.Drawing.Size(105, 22);
            this.salirToolStripMenuItem.Text = "&Salir";
            this.salirToolStripMenuItem.Click += new System.EventHandler(this.salirToolStripMenuItem_Click);
            //
            // iniciarToolStripMenuItem
            //
            this.iniciarToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.iniciarToolStripMenuItem1,
            this.pararToolStripMenuItem});
            this.iniciarToolStripMenuItem.Name = "iniciarToolStripMenuItem";
            this.iniciarToolStripMenuItem.Size = new System.Drawing.Size(66, 20);
            this.iniciarToolStripMenuItem.Text = "Aplicación";
            //
            // iniciarToolStripMenuItem1
            //
            this.iniciarToolStripMenuItem1.Name = "iniciarToolStripMenuItem1";
            this.iniciarToolStripMenuItem1.Size = new System.Drawing.Size(152, 22);
            this.iniciarToolStripMenuItem1.Text = "Iniciar";
            this.iniciarToolStripMenuItem1.Click += new System.EventHandler(this.iniciarToolStripMenuItem1_Click);
            //
            // pararToolStripMenuItem
            //
            this.pararToolStripMenuItem.Name = "pararToolStripMenuItem";
            this.pararToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.pararToolStripMenuItem.Text = "Parar";
            this.pararToolStripMenuItem.Click += new System.EventHandler(this.pararToolStripMenuItem_Click);
            //
            // tmrCerebro
            //
            this.tmrCerebro.Interval = 5;
            this.tmrCerebro.Tick += new System.EventHandler(this.tmrCerebro_Tick);
            //
            // frmMain
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(692, 516);
            this.Controls.Add(this.menuStrip1);
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "frmMain";
            this.Text = "Maquina de estados finitos";
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.frmMain_Paint);
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem archivoToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem salirToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem iniciarToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem iniciarToolStripMenuItem1;
        private System.Windows.Forms.ToolStripMenuItem pararToolStripMenuItem;
        private System.Windows.Forms.Timer tmrCerebro;
    }
}


Y los archivos adjuntos con explicación detallada dentro de la carpeta documentación.
Archivo(s) Adjunto(s)
Archivo Adjunto  MEF.zip ( 18.35k ) Número de descargas: 39
 


--------------------
Contáctanos: staff@codebit.org
Soporte: support@codebit.org

Aprendiendo a usar el foro
Pagina de inicio

Go to the top of the page
 
+Quote Post
hdstryOwrld
mensaje Mar 11 2010, 05:22 AM
Publicado: #2


Administrador
Ícono de Grupo

Grupo: VIP
Edad: 20
Temas por día: 0.37
Mensajes: 353
Hora local: Jul 31 2010, 06:23 AM
Registrado: 26-December 07
Desde: México
Miembro No.: 1



A y acá les dejo el video del funcionamiento de la aplicación notese que cuando el pequeño robot (cuadrito de color verde) se queda sin batería (cuadrito color rojo) va a llenar su combustible , y mientras allá objetos (Cuadrito color morado) el sigue atrapandolos.



--------------------
Contáctanos: staff@codebit.org
Soporte: support@codebit.org

Aprendiendo a usar el foro
Pagina de inicio

Go to the top of the page
 
+Quote Post

Fast ReplyReply to this topicStart new topic
1 usuario(s) está(n) leyendo esta discusión (1 invitado(s) y 0 usuario(s) anónimo(s))
0 miembro(s):

 

Versión Lo-Fi Fecha y Hora actual: 31st July 2010 - 11:23 AM