You are here

Relatório 4 - SOAR: Tutorial 3

Sumário

Exercício 1

No programa TankSoar há 5 tipos de objetos, que são apresentados na Figura 1.1:


Figura 1.1: Objetos do programa TankSoar.

  1. Recarregador de energia: é usado para recarregar a energia do tanque. Ao ficar sobre esse objeto, a energia do tanque é aumentada em 250 unidades. O recarregador nunca se move.
  2. Obstáculos: nunca se movem e não podem ser explodidos.
  3. Pacotes de mísseis: são criados em horários e locais aleatórios. Quando um tanque se movimenta para o quadrado que contém um pacote de míssel, o pacote desaparece e o tanque recebe 7 mísseis.
  4. Tanques: são controlados por agentes do TankSoar. Os tanques de movimentam pelo mundo e soltam mísseis.
  5. Carregador de saúde: é usado para recarregar a saúde de um tanque. Ao ficar sobre esse objeto, a saúde do tanque é aumentada em 150 unidades.

Um tanque possui 6 sensores primários. Quase todos eles estão sempre ativados, exceto o sensor radar, que deve ser ativado quando vai ser usado. Os argumentos da estrutura input-link dos sensores, são os seguintes:

  • Sensor blocked: detecta se os quadrados adjacentes estão livres ou bloqueados. Esse sensor não consegue definir o que está bloqueando o caminho.
    ^blocked 
    	^backward yes/no 
    	^forward yes/no 
    	^left yes/no
    	^right yes/no
    
  • Sensor incoming: detecta se há algum míssel se aproximando, a qualquer distância, desde que não esteja do outro lado de algum obstáculo ou tanque.
    ^incoming
    	^backward yes/no 
    	^forward yes/no 
    	^left yes/no
    	^right yes/no
    
  • Sensor radar: detecta objetos que estão na frente, à direita ou à esquerda do tanque. A distância que o radar pode enxergar será a que está configurada atualmente ou a distância para o objeto que estiver mais perto. A distância que for menor é a que será usada. O uso do radar gera gasto de energia e, por isso, ele deve ser usado com moderação.
    ^radar 
    	^energy
    		^distance 0-d 
    		^position left/center/right 
    	^health 
    		^distance 0-d 
    		^position left/center/right 
    	^missiles 
    		^distance 0-d 
    		^position left/center/right 
    	^obstacle 
    		^distance 0-d 
    		^position left/center/right
    	^open 
    		^distance 0-d 
    		^position left/center/right 
    	^tank 
    		^distance 0-d 
    		^position left/center/right
    		^color red/blue/purple/…
    
  • Sensor rwaves: detecta se algum radar de outro tanque está detectando o tanque.
    ^rwaves
    	^backward yes/no 
    	^forward yes/no 
    	^left yes/no
    	^right yes/no
    
  • Sensor smell: detecta o tanque mais próximo. Caso, dois ou mais tanques estejam em distâncias iguais, então, um deles é escolhido aleatoriamente. É importante observar que esse sensor penetra em bloqueios e, por isso, nem sempre o tanque mais próximo, é o mais fácil de ser alcançado.
    ^smell
    	^color none/red/blue/purple/…
    	^distance none/0-28
    
  • Sensor sound: detecta o tanque mais próximo, em até 7 quadrados de distância, e que se moveu na última decisão. Se mais de um tanque se moveu e estão na mesma distância, o sensor escolhe um deles aleatoriamente.
    ^sound silent/left/right/forward/backward
    

O tanque também possui sensores secundários que fornecem informações sobre seu estado. Os argumentos da estrutura input-link desses sensores são apresentados a seguir:

  • Sensor clock: esse sensor é inicializado em 1 e é incrementado a cada decisão. Por ser um contador global, se um tanque é criado após outros tanques já terem atuado pelo mundo virtual por algum tempo, então, o valor inicial não será 1.
    ^clock 1-N
    
  • Sensor direction: fornece a direção que o tanque está tomando.
    ^direction north/east/south/west
    
  • Sensor energy: fornece o nível de energia atual. Se esse energia estiver com nível 0, não é possível utilizar o radar ou os escudos.
    ^energy 0-1000
    
  • Sensor energy recharger: possui valor yes se o tanque está sobre um recarregador de energia. Caso contrário, seu valor é no
    ^energyrecharger no/yes
    
  • Sensor health: fornece o nível de saúde atual. Se o nível é 0, o tanque morre e ressuscita em um quadrado aleatório.
    ^health 0-1000
    
  • Sensor health recharger: possui valor yes se o tanque está sobre um recarregador de saúde. Caso contrário, seu valor é no
    ^healthrecharger no/yes
    
  • Sensor missiles: fornece o número atual de mísseis que o tanque possui.
    ^missiles 0-N
    
  • Sensor my-color: fornece a cor do tanque.
    ^my-color blue/red/purple/…N
    
  • Sensor radar-distance: fornece a distância do radar na última vez que foi usado. Se não houve nenhum bloqueio, a distância é a mesma que está configurada para o radar. Porém, se houve algum bloqueio, é fornecida a distância até o bloqueio mais próximo.
    ^radar-distance 1-14
    
  • Sensor radar-setting: fornece a potência que foi configurada para o radar.
    ^radar-setting 1-14
    
  • Sensor radar-status: informa se o radar está ligado ou não.
    ^radar-status on/off
    
  • Sensor random: fornce um número real aleatório entre 0 e 1, que muda a cada decisão.
    ^random 0.0-1.0
    
  • Sensor resurrected: informa se o tanque já foi ressuscitado ou não.
    ^resurrected no/yes
    
  • Sensor shield-status: informa se o escudo está ativado ou não.
    ^shield-status on/off
    
  • Sensor x: informa a posição x do tanque no mapa, que pode variar de 1 (lado esquerdo) a 14 (lado direito).
    ^x 1-14
    
  • Sensor y: informa a posição y do tanque no mapa, que pode variar de 1 (parte superior) a 14 (parte inferior).
    ^y 1-14
    

Os tanques podem executar várias ações, que são realizadas por meio de argumentos do output-link. Essas ações são apresentadas abaixo:

  • Ação move: faz o tanque se mover para frente, para trás, para a direita, para a esquerda ou para nenhuma direção (ação de espera). Se um tanque tenta se mover e é bloqueado, ele perde 100 unidades de saúde.
    ^move.direction left/right/forward/backward/none
    
  • Ação roting: faz o tanque girar para a direita ou para a esquerda.
    ^rotate.direction left/right
    
  • Ação fire: dispara um míssel. Essa ação pode ser executada em paralelo com qualquer outra e, cada vez que é executada, diminui um míssel da capacidade atual do tanque. O míssel é disparado para a frente.
    ^fire.weapon missile
    
  • Ação radar: ativa ou desativa o radar. Para a ativação é necessário que haja energia suficiente.
    ^radar.switch on/off
    
  • Ação radar range: defini a potência do radar e pode variar de 1 a 14. Quanto maior a potência, maior o gasto de energia.
    ^radar-power.setting 1-14
    
  • Ação shields: ativa ou desativa os escudos do tanque. Para a ativação é necessário que haja energia suficiente.
    ^shields.switch on/off
    

Conforme foi solicitado no exercício, foram criados dois agentes usando a base de regras simple-bot.soar. Os dois agentes estão apresentadoos em destaque na Figura 1.2.


Figura 1.2: Agentes criados usando a base de regras simple-bot.soar.

 

Exercício 2

Tanque errante simples

Nessa seção serão apresentadas regras que guiam um tanque que vagueia pelo mundo virtual usando sensores para evitar colisão com obstáculos e para detectar outros objetos. O sensor principal desse tanque é o seu radar, que fica na sua frente. Por isso, apesar do tanque poder se movimentar em qualquer direção, é preferível seguir sempre em frente e virar para evitar obstáculos. Como o radar gasta energia, então é melhor usá-lo quando o tanque vira e desligá-lo quando não há nada importante para ver. Diante disso, os três operadores e controles de busca podem ser usados:

  • move-se para frente se não é bloqueado;
  • gire quando há algum obstáculo na sua frente e ligue o radar com potência 13 (potência máxima);
  • se o radar está ligado e não há objetos visíveis, desligue-o;
  • Se é proposto desligar o radar, então prefira se mover.

Para a criação das regras que irão definir o comportamento do tanque, foi criado um novo projeto no Visual Soar, a partir do template padrão fornecido no diretório do TankSoar. Esse template já contém um datamap completo para o input-link e output-link e contém um operador de inicialização. Veja o resultado na Figura 2.1.1.


Figura 2.1.1: Novo projeto no Visual Soar.

A primeira regra criada é a que propôe mover o tanque. Essa regra testa se há algum bloqueio na frente do tanque. Caso não exista, ela propôe o operador para mover para frente. Veja a regra na Figura 2.1.2.


Figura 2.1.2: Regra tanksoar*propose*move.

Outra regra importante é a que deve ser ativada quando existe um bloqueio na frente do tanque. Quando isso acontece, o tanque precisa girar para a direita ou esquerda. A direção não importa, se não existe um outro bloqueio. Quando o tanque precisa gerar, também é necessário que seja ligado seu radar com potência 13. A regra que foi criada é apresentada na Figura 2.1.3.


Figura 2.1.3: Regra tanksoar*propose*turn.

Na regra apresentada acima, é proposto girar o tanque em caso de não haver barreira na frente e não haver barreira dos lados esquerdo e direito. Porém, caso as duas direções estejam bloqueadas, o tanque precisa ir girando para um dos lados, até que possa voltar para trás. Então, foi criada uma regra que faz o tanque girar para a esquerda quando há obstáculo dos dois lados. Veja na Figura 2.1.4.


Figura 2.1.4: Regra tanksoar*propose*turn*backward.

Foram criadas também regras para controlar o radar. Se o radar estiver ligado e não houver objetos interessantes visíveis, deve-se desligá-lo para conservar energia. Além disso, se é proposto desligar o radar, é preferível mover em vez de girar. Veja, na Figura 2.1.5, o código dessas regras.


Figura 2.1.5: Regras para controlar o radar.

Executando o programa TankSoar com as regras propostas anteriormente, no debugger do programa poderá ser visto algo semelhante ao que é mostrado na Figura 2.1.6.


Figura 2.1.6: Regras para controlar o radar - Soar Debugger.

Operador vaguear (wander) - sugobjetivos

Considerando que as tarefas que o tanque pode executar são muitas, convém dividi-las em tarefas de auto nível e de baixo nível. As ações de alto nível podem ser executadas pela combinação de ações de baixo nível. Então, uma possível hierarquia de tarefas é apresenda abaixo:

  • vaguear
    • mover
    • girar
  • perseguir
    • mover
    • girar
  • stacar
    • mover
    • girar
    • inclinar
    • abrir fogo
  • recuar
    • mover
    • esperar

Outras regras que não estão nessa estrutura hierarquica, tais como ativar os escudos e relembrar sons, são independentes e podem ser propostas e aplicadas em qualquer objetivo.

Nessa seção serão introduzidos os subobjetivos da tarefa de auto nível vaguear. O primeiro passo é criar a regra que propõe essa tarefa. Veja na Figura 2.2.1.


Figura 2.2.1: Regra que propõe o operador wander.

O operador vaguear será aplicado quando os operadores no subestado não selecionados e aplicados. Então, as regras originais do operador vaguear devem ser mudadas, pois elas somente podem ser aplicadas quando o operador vaguear é selecionado. Logo, o operador move, apresentado na Figura 2.1.2, deve ser alterado conforme é apresentado na Figura 2.2.2.


Figura 2.2.2: Novo operador move.

A regra apresentada acima não pode ser executada, pois não existe o argumento io no subestado. Uma alternativa para contornar esse problema é copiar o argumento io para cada novo subestado. A regra usada para fazer isso, é apresentada na Figura 2.2.3.


Figura 2.2.3: Copiando o argumento io para cada novo subestado.

Com essa nova regra, todas as regras que propõe o operador wander devem testar se o superoperador wander está selecionado. Veja as mudanças na Figura 2.2.4.


Figura 2.2.4: Regras relacionadas ao operador wander.

Com as regras propostas até o momento, o tanque deve vaguear até encontrar outro tanque. Para que isso possa ocorrer, outras regras gerais devem ser acrescentadas, conforme apresentado na Figura 2.2.5.


Figura 2.2.5: Regras gerais.

 

Perseguir (chase), atacar (attack) e recuar (retreat)

Nessa seção serão apresentadas as regras que foram criadas para as tarefas perseguir, atacar e recuar.

A primeira tarefa que foi criada foi a tarefa perseguir. Um tanque deve iniciar uma perseguição se o sensor sound detectar que um tanque está próximo. Como não é possível saber exatamente onde o tanque inimigo está, é necessário persegui-lo. Porém, essa tarefa só será ativada caso o sensor radar não tenha detectado o tanque que está próximo e se houver energia e mísseis suficientes.

Diante disso, foi necessário criar regras que testam se a quantidade de mísseis e energia é suficiente. Essas regras são apresentadas na Figura 2.3.1.


Figura 2.3.1: Regras que verificam a energia e a quantidade de mísseis.

A regra que propõe o operador chase é apresentada na Figura 2.3.2.


Figura 2.3.2: Regra que propõe o operador chase.

Para aplicar o operador chase o operador move ou turn precisa ser selecionado. Esses operadores testam a direção do som por meio da informação acessada através do input-link. Porém, caso seja necessário alterar o modo com a direção é detectada, será necessário alterar todas as regras que testam a direção do som. Por isso, é mais vantajoso criar uma regra que copia a direção para o estado local, conforme apresentado na Figura 2.3.3. Outra regra que precisa ser criada é a que liga o radar quando o tanque começa uma perseguição. Essa regra também é apresentada na Figura 2.3.3.


Figura 2.3.3: Regra que copia a direção do som para o estado local e regra que liga o radar.

As regras que aplicam o operador chase, por meio dos operadores move ou turn, são apresentadas na Figura 2.3.4.


Figura 2.3.4: Regra que copia a direção do som para o estado local e regra que liga o radar.

Após criar as regras relacionadas a tarefa perseguir, foram desenvolvidas as regras da tarefa atacar. Essa última tarefa atira mísseis e bate no tanque inimigo. O operador relacionada a essa tarefa deve ser selecionado quando um tanque inimigo aparece no sensor radar. Porém, para isso é necessário que haja saúde e energia suficientes. Veja na Figura 2.3.5, a regra que propõe essa tarefa.


Figura 2.3.5: Regra que propõe o operador attack.

Para aplicar o operador attack é necessário que o operador move, turn ou fire (disparar um míssel) seja selecionado. Então, caso um inimigo esteja no radar na posição central do mesmo, então o tanque pode disparar um míssel. Porém, se o inimigo estive fora do centro do radar e na frente do tanque, então o tanque deve se mover para a esquerda ou direita para obter uma posição adequada para disparar o míssel. No entanto, se o tanque não pode deslizar por estar bloqueado, então ele deve mover para frente. Em outra situação, o inimigo pode estar ao lado do tanque, logo, o tanque deve girar. A Figura 2.3.6 apresenta as regras relacionadas a tarefa atacar.



Figura 2.3.6: Regras relacionadas a tarefa atacar.

Após criar as regras relacionadas a tarefa atacar, foram desenvolvidas as regras da tarefa recuar. Essa última tarefa tem por objetivo manter o tanque fora de perigo quando ele tem energia baixa ou poucos mísseis e há um inimigo próximo. Além disso, considerando que o tanque pode perceber a aproximação de um inimigo por meio de três sensores diferentes(sensores incoming, radar e sound, é necessário que o operador retreat seja proposto nas três situações. Essa tarefa também pode ser selecionada quando um tanque inimigo está próximo e não é possível saber qual a sua direção para poder atacá-lo. Veja na Figura 2.3.7 as regras que propõem essa tarefa.



Figura 2.3.7: Regras que propõem o operador retreat.

Na aplicação do operador retreat é importante saber a direção do inimigo para conseguir fugir dele. Então, foram adicionadas regras que elaboram o subestado que indica as direções que devem ser evitadas durante o recuo do tanque. Essas regras são apresentadas na Figura 2.3.8.



Figura 2.3.8: Regras de elaboração de estados - operador retreat.

O operador retreat é aplicado através da seleção de operadores move, que serão usados para contornar as direções que oferecem perigo. Caso não haja boa possibilidades de fuga o tanque pode esperar, em silêncio, até que o inimigo vá embora.

Para facilitar o cálculo da direção de fuga foi adicionada um estrutura na memória de trabalho que contém cada direção e as duas direção adjacentes a cada direção. Veja na Figura 2.3.9.


Figura 2.3.9: Criação de uma estrutura na memória de trabalho com as direções de fuga.

A regra que propõe o operador move relacionado a tarefa retreat é apresentada na Figura 2.3.10.


Figura 2.3.10: Operador move - tarefa retreat.

Outros recursos importantes para a defesa de um tanque são os escudos. Porém, como eles custam muita energia, é necessário usá-los apenas quando o tanque está sofrendo um ataque ou quando o risco de ataque é alto. Então, foram criadas as regras apresentadas na Figura 2.3.11 para controlar o uso desses recursos.


Figura 2.3.11: Regras para ativação e desativação dos escudos.

Como foi mencionado anteriormente caso não haja boa possibilidades de fuga, o tanque pode esperar, em silêncio, até que o inimigo vá embora. A regra que aplica esse comportamento ao tanque, é ativada também quando nenhum operador é selecionada. Isso evita que o Soar crie uma cascata de impasses state-no-change quando nenhum operador é selecionado. A regra que aplica esse comportamento é apresentada na Figura 2.3.12.


Figura 2.3.12: Operador wait.

Melhorando a detecção de som

O principal problema com o comportamento do tanque criado até o momento, é que ele perde a posição dos tanques inimigos, detectados pelo sensor sound, quando eles param de se mover. Para evitar que isso ocorra, nessa seção serão apresentadas regras que criam um estrutura permanente na memória de trabalho que guarda a direção dos tanques inimigos. Para atingir esse objetivo, é necessário criar um operador que cria a estrutura ne memória de trabalho quando um som é ouvido e outro para remover essa estrutura quando a direção do som muda ou o som, cuja direção está armazenada, expira.

A direção do som deve ser registrada quando o tanque está vagando, ou seja, quando o operador wander está ativado. Nessa situação o operador deve mudar para que seja iniciada uma perseguição. A regra que propõe o operador deve ter alta preferência, pois o armazenamento da direção do som inimigo deve ser prioridade. Veja a regra na Figura 2.4.1.


Figura 2.4.1: Operador record-sound.

A regra para aplicar o operador record-sound deve testar se o operador é record-sound, a direção de onde vem o som e o relógio atual, para saber quando o som deve ser removido. O valor do relógio é 5 porque é o tempo suficiente para o tanque girar e usar seu radar para localizar o tanque inimigo.

Um problema que pode ser encontrado é que a direção fornecida pelo sensor é relativa, pois depende da posição do tanque. Logo, quando o tanque gira, essa posição relativa já não corresponde a posição verdadeira do tanque inimigo. Diante disso, foi criada uma estrutura na memória de trabalho que guarda a posição absoluta do inimigo, que pode ser norte, sul, leste ou oeste, conforme é apresentado na Figura 2.4.2.


Figura 2.4.2: Criando estrutura na memória de trabalho que guarda as posições absolutas.

Após criar a estrutura na memória de trabalho com as possíveis posições absolutas, a regra que aplica o operador record-sound foi criada, conforme mostra a Figura 2.4.3.


Figura 2.4.3: Operador record-sound.

Apesar da posição absoluta do som ser armazenada, quando o tanque inicia uma perseguição, usando o operador chase, ele usa a posição relativa. Então, assim como foi feito nas regras que aplicam o operador chase, a direção armazenada será usada para calcular a posição relativa e copiá-la para o estado chase. A regra que calcula a posição relativa e a copia para o estado chase, é apresentada na Figura 2.4.4.


Figura 2.4.4: Cálculo da posição relativa a ser usada no operador chase.

Depois que o tempo expira, o estrutura que armazena a posição absoluta do inimigo deve ser removida. Isso pode ocorrer em qualquer tarefa: vaguear, perseguir, atacar ou recuar. A regra que propõe esse operador é apresentada na Figura 2.4.5.


Figura 2.4.4: Regra que propõe o operador remove-sound.

A regra que aplica o operador remove-sound deve remover a estrutura de dados do superestado, conforme mostrado na Figura 2.4.5.


Figura 2.4.5: Regra que aplica o operador remove-sound.

Criando um mapa

Nessa seção será criado um mapa, que é uma estrutura que deve ser armazenada e atualizada enquando o tanque está jogando. O mapa consiste de uma grade de 16 x 16 quadrados, o que inclui as bordas e o espaço onde o tanque pode se mover. O mapa é gerado pelo operador init-map que é proposto e selecionado no início do jogo.

Cada quadrado é inicializado com uma localização x e y, que são as informações mínimas para distinguir dois quadrados. Além disso, informações e estruturas adicionais são necessárias para facilitar o acesso aos quadrados adjacentes ao quadrado atual, tais como, se o quadrado contém um recarregador, tanque, míssel ou é um obstáculo ou não possui nada. Outra maneira de facilitar o acesso a quadrados adjacentes é adicionar argumentos entre os quadrados. Por exemplo, quadrados ao norte e sul que são adjacentes, possuem o mesmo valor x e diferem na coordenada y por um. Logo, adicionando um ao valor de x de cada quadrado é possível encontrar o quadrado a leste e adicionando um ao valor de y é possível encontrar o quadrado ao sul. Diante disso, pode-se criar links leste-oeste e norte-sul entre pares de estados, conforme é feito pelas regras apresentadas na Figura 2.5.1.


Figura 2.5.1: Criando links entre pares de estados.

Outra inicialização que deve ser feita é a marcação de todos os quadrados da fronteira como obstáculo. Para isso, todos os quadrados que tenham coordenada x ou y com valor 0 ou 15 devem receber um argumento yes. Por exemplo, na regra apresentada na Figura 2.5.2, todos os quadrados com coordenada x igual a 15 recebem o argumento yes.


Figura 2.5.2: Marcando os quadrados com coordenada x igual a 15 como obstáculo.

Para que o agente consiga usar e atualizar o mapa, ele precisa saber em que quadrado no mapa ele está. Para isso, pode-se criar um link chamado ^square com a localização x,y atual do agente a partir das informações obtidas no input-link.


Figura 2.5.3: Marcando o quadrado atual.

Depois que o quadrado atual é armazenado, é necessário atualizar o mapa interno com as informações fornecidas pelo radar. Para isso, a regra de elaboração de direções deve ser usada para calcular as localizações x e y dos objetos detectados no radar. Então, a regra mostrada na Figura 2.5.4 foi criada.


Figura 2.5.4: Regra que calcula as localizações x e y dos objetos detectados pelo radar.

Também pode ser criada uma regra que marca qual tipo de objeto está no quadrado. Por exemplo, se no quadrado há o recarregador de saúde, então cria-se um argumento ^healthyes. Veja a regra na Figura 2.5.5.


Figura 2.5.5: Marcando o tipo de objeto que há no quadrado.

Considerando que existem obstáculos que não são permanentes, como os tanques e os mísseis, deve-se criar regras que removem essas marcações do quadrado quando se verifica, por meio do radar do tanque, que ele está livre, conforme apresentado na Figura 2.5.6.


Figura 2.5.6: Verificando se o quadrado está livre de mísseis e tanques.

Também podem ser criadas regras que marcam o quadrado atual como livre ou marcar que sobre ele há um carregador de energia ou de saúde, conforme apresentado na Figura 2.5.7.


Figura 2.5.7: Marcando o quadrado atual como livre ou como localização de algum carregador.

 

Exercício 3

Nesse exercício foi desenvolvido um programa Soar, utilizando o mapa do ambiente, para fazer com que o tanque, além de suas atividades normais, dirija-se aos carregadores de energia e saúde, quando estiverem com baixa energia ou baixa saúde. O link do programa que foi desenvolvido é apresentado abaixo:

A primeira coisa que foi desenvolvida nesse exercício foram as regras que identificam que o tanque está com energia ou saúde baixa. Para facilitar os testes relacionados ao funcionamento do programa, a energia e saúde são consideradas baixas quando estiverem com o valor abaixo de 800. Se a energia estiver baixa, o argumento ^energy-charge recebe o valor low. Se a saúde estiver baixa, o argumento ^health-charge recebe o valor low. As regras desenvolvidas são apresentadas na Figura 3.1.


Figura 3.1: Regras que identificam se a energia está baixa.

Caso os argumentos criados nas regras apresentadas na Figura 3.1 indiquem que a energia ou saúde estejam baixas, então, o superoperador recharge é proposto. Esse superoperador será semelhante ao superoperador wander e terá dois operadores, move e turn. Esses dois operadores, terão a função de vagar pelo mundo virtual até encontrar algum recarregador. Além disso, o superoperador recharge tem preferência sobre os outros superoperadores, pois quando o tanque está com energia baixa, ele fica vulnerável e precisa ser recarregado. As regras que propõe o superoperador recharge são apresentadas na Figura 3.2.


Figura 3.2: Regras que propõe o operador recharge.

Como foi mencionado, um dos operadores da tarefa recharge é o move. Esse operador é semelhante ao criado para a tarefa wander, e será acionado quando não há um bloqueio na frente do tanque e se, ainda, nenhum recarregador foi encontrado. Veja a regra que propõe esse operador na Figura 3.2.


Figura 3.3: Regra que propõe o operador move.

O outro operador da tarefa recharge é o turn. Esse operador será ativado caso haja algum bloqueio na frente do tanque e se nenhum recarregador foi encontrado. Existem duas regras que propõe esse operador. A primeira é satisfeita caso não haja bloqueio no lado direito ou esquerdo do tanque, fazendo com que o tanque gire para o lado que estiver desbloqueado. Porém, caso haja bloqueio nos dois lados, então outra regra propõe girar o tanque para a esquerda, enquanto tiver bloqueio dos dois lados, o que faz com que ele gire para trás. Veja as regras que propõem esse operador na Figura 3.3.


Figura 3.4: Regras que propõem o operador turn.

Os operadores move e turn do operador recharge são propostos quando nenhum recarregador foi encontrado no mundo virtual. Porém, caso algum recarregador já tenha sido encontrado, um novo operador será proposto, o move-recharge. As regras que propõe esse operador farão com que o tanque se mova rumo ao recarregador. É importante mencionar que no exercício anterior, já foi criada uma estrutura na memória de trabalho que guarda a posição dos recarregadores que são encontrados pelo tanque. Para isso foram usadas as regras apresentadas nas Figuras 2.5.4, 2.5.5 e 2.5.7. Porém, para que o tanque consiga se mover para a posição (x,y) do recarregador, é necessário saber se essa posição esta ao norte ou sul do tanque e a leste ou oeste. Então, foi criada na memória de trabalho uma estrutura que armazena essa posição, cujas regras para sua criação, funcionam da seguinte forma: caso a posição y do tanque seja menor que a posição y do recarregador, então o argumento ^direction-recharge recebe o valor south; caso contrário esse argumento recebe o valor north; se a posição x do tanque for menor que a posição x do recarregador, então o argumento ^direction-recharge2 recebe o valor east; caso contrário esse argumento recebe o valor west. Veja as regras que criam esses argumentos na Figura 3.5.




Figura 3.5: Argumentos que armazenam a direção do carregador.

Após a criação dos argumentos que armazenam a direção do carregador, foi criado o operador move-recharge, que faz o tanque se mover na direção do recarregador. A Figura 3.6 apresenta a regra que propõe esse operador.


Figura 3.5: Operador move-recharge.

Veja parte a execução do programa na imagem abaixo:


Figura 3.6: Execução do programa.

As regras criadas até o momento ainda possuem alguns problemas, pois normalmente o tanque consegue tomar a direção do recarregador, mas por algum motivo desconhecido, surge o impasse state-no-change. Acredita-se que para resolver o problema é necessário criar alguma estrutura na memória de trabalho que transforme as posições do recarregador em posições relativas, como esquerda, direita, frente ou trás. Além disso, deve-se criar regras que impessam a criação de impasses quando o recarregador está, por exemplo, no norte e leste e existem bloqueio nessas direções.

 

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer