You are here

Aula 11 - Clarion: Controlando o WorldServer3D

Teste 1




Foi criado um programa para controlar a criatura a partir do programa cliente.

Ações da criatura:

  1. Se encontrar uma parede na frente então vire à direita;

  2. Se tem algum objeto diferente de parede, comida ou outra criatura a menos de 35 unidades de distancia, então pegue o objeto;

  3. Se tem comida a menos de 35 unidades de distância, mas a energia é superior a 450 então vire à direita para desviar da comida;

  4. Se tem alguma joia na frente então adicione ela em uma lista de joias vistas;

  5. Se tem comida na frente então adicione ela a uma lista de comidas vistas;

  6. Se a energia estiver baixa (Fuel < 450) então procure na lista de comida qual está mais próxima e siga em direção a ela;

  7. Se tem elementos na lista de joias, então procura a joia que está mais perto e siga para pegá-la;

  8. Se não encontrar nenhuma joia a frente então vire à direita.

Cada vez que a criatura pega um elemento ela verifica sua lista de objetos e compara com a lista de objetivos (leaflet) se ela tem todas as joias que estão na leaflet o programa deve acabar e a criatura para.

Foi feito até esse ponto um programa inicial onde a criatura identifica a joia mais próxima e vai pegá-la sem verificar sua cor e se ela é um objetivo, assim possivelmente ela irá obter mais joias do que realmente precisa. Mas quando o número mínimo de joias for atingido o programa para e o jogo encerra.

Inicialmente serão criados: o mundo e a criatura.

Após a criação dos objetos será chamado o método StartWorld que gera as paredes externas do mundo, posiciona aleatoriamente 5 joias de cada tipo (ao todo serão 30 joias) e posiciona 3 comidas de forma aleatória.

Após essa inicialização será criado uma leaflet pelo servidor.

Nesta etapa algumas classes foram adicionadas para organizar os objetivos da criatura:

  • A classe Goal, possui 4 atributos (figura 1):

    • Color: Color da joia que deve ser procurada

    • NumRequest: número de joias que devem ser obtidas da cor dada por Color

    • NumStack: número de joias que já foram obtidas pela criatura

    • completed: Se o numero de joias solicitadas é igual ao que a criatura já pegou então o objetivo está completo e completed = True, senão, então completed = False

Figura 1


A próxima classe (figura2) será a Leaflet, que é a lista de objetivos (Gols), essa classe possui 3 atributos:

    • NumGoals: número de objetivos na lista

    • Points: número de pontos que a criatura irá ganhar se cumprir os objetivos

    • GoalsList: lista de classes tipo Goal com os objetivos a serem cumpridos




Figura 2



Após a criação dessas duas classes foram feitos ajustes em outras classes existentes:

- Classe Creature (figura3): foram incluídas duas listas. A primeira é uma lista de leaflets ou seja, uma lista de objetos tipo Leaflet, e uma lista de objetos tipo Thing que contem todas as joias que a criatura já obteve.



Figura 3



As 4 ações utilizadas pela criatura foram:

private DimensionValuePair InputWallAhead;
private DimensionValuePair InputJewel;
private DimensionValuePair InputFoodAhead;
private DimensionValuePair InputSackIt; 

As regras utilizadas foram as seguintes:

  1. Se encontra parede a frente então vire à direita:

            // Detecta se tem uma parede a frente
            Boolean wallAhead = sensorialInformation.Where(item => (item.CategoryId == Thing.CATEGORY_BRICK && item.DistanceToCreature <= 35)).Any();
            
            if (wallAhead)
            {                
                si.Add(InputSackIt, CurrentAgent.Parameters.MIN_ACTIVATION);
                si.Add(InputFoodAhead, CurrentAgent.Parameters.MIN_ACTIVATION);
                si.Add(InputJewel, CurrentAgent.Parameters.MIN_ACTIVATION);
                si.Add(InputWallAhead, CurrentAgent.Parameters.MAX_ACTIVATION);
                
                return si;
            }


Então será criado um foreach para avaliar cada elemento dentro da sensorialInformation

List<Thing> JewelList = new List<Thing>();
List<Thing> FoodList = new List<Thing>(); foreach (Thing item in sensorialInformation) {

 2. Se encontra um objeto diferente da parede, comida ou criatura a menos de 35 unidades de distancia, então pega o objeto.


                // Detecta se é um objeto a ser obtido
                if(item.CategoryId != Thing.CATEGORY_CREATURE && item.CategoryId != Thing.CATEGORY_PFOOD &&  item.CategoryId != Thing.CATEGORY_NPFOOD && item.CategoryId != Thing.CATEGORY_BRICK && item.DistanceToCreature <= 35)
                {    
                    SackItItem = item;
                    si.Add(InputSackIt, CurrentAgent.Parameters.MAX_ACTIVATION);
                    si.Add(InputFoodAhead, CurrentAgent.Parameters.MIN_ACTIVATION);
                    si.Add(InputJewel, CurrentAgent.Parameters.MIN_ACTIVATION);                    
                    return si;
                }


 3. Se tem comida a menos de 35 unidades de distancia, mas a energia é superior a 450 então vire à direita para desviar da comida.


                // Se tiver comida a 35 de distancia e energia maior que 450 desvie
                if(item.CategoryId == Thing.CATEGORY_PFOOD && item.DistanceToCreature <= 35 && Oss.Fuel >= 450)
                {    
                    si.Add(InputWallAhead, CurrentAgent.Parameters.MAX_ACTIVATION);
                    si.Add(InputSackIt, CurrentAgent.Parameters.MIN_ACTIVATION);
                    si.Add(InputJewel, CurrentAgent.Parameters.MIN_ACTIVATION);
                    si.Add(InputFoodAhead, CurrentAgent.Parameters.MIN_ACTIVATION);
                    return si;
                }


4. Se tem uma joia na frente então adicione ela a lista de joias vistas

                // Detecta joia e adiciona na lista vista
                if(item.CategoryId == Thing.CATEGORY_JEWEL)
                    JewelList.Add(item);

5. Se tem comida na frende então adicione ela a uma lista de comidas vistas


                // Detecta comida e adiciona na lista vista
                if(item.CategoryId == Thing.CATEGORY_PFOOD)
                    FoodList.Add(item);


6. Se estiver com baixa energia (Fuel < 450) então procure na lista de comidas vistas qual a mais próxima e vá pegá-la


            if(Oss.Fuel < 450//se a energia estiver menor que 450
            {
                if(FoodList.Count > 0)
                {
                    Console.Out.WriteLine("Energia baixa! \n");
                
                    FoodList = FoodList.OrderBy(o=>o.DistanceToCreature).ToList();
                
                    int x =  (int)FoodList[0].X1;
                    int y = (int)FoodList[0].Y1;
                    int dis = (int)FoodList[0].DistanceToCreature;
                                                
                    param_food[0] = x;
                    param_food[1] = y;
                    param_food[2] = dis;                        
                    foodName = FoodList[0].Name;
                
                    Console.WriteLine("Comida, Pos: " + x.ToString() + " , " + y.ToString() + " Dist = " + dis.ToString());

                    si.Add(InputWallAhead, CurrentAgent.Parameters.MIN_ACTIVATION);
                    si.Add(InputSackIt, CurrentAgent.Parameters.MIN_ACTIVATION);
                    si.Add(InputJewel, CurrentAgent.Parameters.MIN_ACTIVATION);            
                    si.Add(InputFoodAhead, CurrentAgent.Parameters.MAX_ACTIVATION);            
                    
                    return si;
                }
                
            }


7. Caso possua elementos na lista de joias, então procure a joia mais próxima e vá pegá-la.

            if(JewelList.Count > 0)
            {
                Console.WriteLine("Found " + JewelList.Count.ToString() + " Jewels !!");    

                JewelList = JewelList.OrderBy(o=>o.DistanceToCreature).ToList();
                
                int x =  (int)JewelList[0].X1;
                int y = (int)JewelList[0].Y1;
                int dis = (int)JewelList[0].DistanceToCreature;
                param[0] = x;
                param[1] = y;
                param[2] = dis;
                
                si.Add(InputJewel, CurrentAgent.Parameters.MAX_ACTIVATION);
                
                return si;
            }


8. Se não tem joia nenhuma na frente então vire à direita.


            si.Add(InputWallAhead, CurrentAgent.Parameters.MAX_ACTIVATION);
     si.Add(InputSackIt, CurrentAgent.Parameters.MIN_ACTIVATION);
     si.Add(InputJewel, CurrentAgent.Parameters.MIN_ACTIVATION);            
     si.Add(InputFoodAhead, CurrentAgent.Parameters.MIN_ACTIVATION);

return si;


Além das classes criadas e ajustes foi criado o código abaixo para fazer o Parse do leaftlet gerado no servidor.

                       // faz parser do leaflet!
                        if(creature.HasLeaflet)
                        {
                            int num_leaflet = creature.NumberOfLeaflets;
                            
                            for(int i = 0; i < num_leaflet ; i++)
                            {
                                enumerator.MoveNext();
                                Leaflet aux = new Leaflet();
                                SetAttribute(aux, "NumGoals", enumerator);
                                for(int j = 0; j < Convert.ToInt32(aux.NumGoals); j++)
                                {
                                    Goal aux2 = new Goal();
                                    SetAttribute(aux2, "Color", enumerator);                                    
                                    SetAttribute(aux2, "NumRequest", enumerator);
                                    SetAttribute(aux2, "NumStack", enumerator);
                                    aux.GoalsList.Add(aux2);                                    
                                }
                                
                                SetAttribute(aux, "Points", enumerator);
                                creature.LeafletList.Add(aux);
                            }
                        }

Criatura no WorldServer3D.




Figura 4



Arquivos



  1. Executável do controlador:

    aqui
  2. Código fonte:

    aqui



Teste 2


A figura a seguir mostra as duas criaturas no WorldServer3D.



  • WorldServer 3D: aqui
  • Cliente modificado do Soar: aqui


  • Figura 5


    Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer