Este exercício explora uma nova forma de extender o conceito de formiga de Langton. Agora, o comportamento da formiga não depende apenas da cor no chão, mas também de seu estado interno (representado por um valor inteiro). A ideia de transformar a formiga em um autômato vem naturalmente do conceito de máquina de Turing. Isto explica o nome destes novos animais, que é um amálgama de Turing e Termite (se você não sabe o que uma máquina de Turing é, vá na wikipédia, por que é impossível ser um cientista da computação de verdade sem conhecê-la).
Novamente, você tem que simplesmente escrever o método step()
,
encarregado de fazer o turmite dar um passo. Novamente, você deve primeiro
encontrar o rank da cor do chão da célula atual na sequência de cores. Mas
agora, os dados de rule
(regras) dependem tanto da cor atual
quanto do estado atual. A rule
na verdade contém 3 informações
em cada situação: a cor que a escreve, o movimento a fazer e o valor do
próximo estado. Por exemplo,
[!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contém as informações
para usar quando state==1
e color==0
. Em outros
mundos, você pode recuperar a informação relativa à sua situação atual
usando
[!java|python]rule[state][currentColor][/!][!scala]rule(state)(currentColor)[/!]
.
Cada um destes conjuntos de informações contém 3 valores. O primeiro é o
rank da cor para escrever no chão. O segundo é o movimento para fazer, com a
seguinte notação: 0=stop, 1=noturn, 2=left, 4=u-turn, 8=right. Observe que
se o comando é stop, você não pode se mover nem para a frente neste passo
(mas você não pode parar o programa também: os próximos passos podem fazer
algo mais num estado futuro). Finalmente, o terceiro inteiro é o próximo
valor do state
a ir dentro da próxima iteração.
Uma vez que estas notações arbitrárias são de certa forma difíceis de
lembrar, você deve definir um conjunto de constantes que você deve usar no
lugar dos valores numéricos diretos. Seus nomes podem ser NOTURN, LEFT,
RIGHT etc. [!scala]Simplesmente declare elas usando keyword val
no lugar de var
. Você deve sempre usar val
no
lugar de var
quando possível de qualquer forma.[/!] [!java]Os
modificadores final static
antes do seu tipo é a forma de
marcar variáveis como constantes em Java. Você deve escrever, por exemplo,
static final int NOTURN=1;
Desculpe pela complesxidade desta
notação. [/!] [!python]Por convenção, tais variáveis constantes são escritas
em maiúsculas no python. Tecnicamente, você ainda pode modificá-las, mas
isto é uma má ideia.[/!] Você deve escrevê-las fora de qualquer método para
que elas se tornem visíveis globalmente.
Usar tais constantes ajuda em muito a fazer o código mais legível. Compare os dois blocos de código a seguir:
[!java]if (rule[state][currentColor][NEXT_MOVE] == LEFT) {[/!][!python]if rule[state][currentColor][NEXT_MOVE] == LEFT:[/!][!scala]if (rule(state)(currentColor)(NEXT_MOVE) == LEFT) {[/!] left()[!java];[/!] [!java|scala]}[/!]
Isto é muito mais fácil de se ler (embora seja mais longo) do que o seguinte:
[!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!] left()[!java];[/!] [!java|scala]}[/!][!python]
Finalmente, você provavelmente vai querer escrever um ramo elif
para a condição STOP
também. Ter um ramo else
mostrando uma mensagem de erro tal como "unknown case" é uma boa prática:
faz as suas suposições sobre seu código mais explícitas, e você tem uma
mensagem de erro se elas falharem. Quando fizer isto, o próximo problema vai
ser que você não tem nada para fazer no caso do STOP
, mas
python não permite que você escreva ramos elif
vazios. Você
deve usar a instrução pass
como substituto: ela diz ao python
que você tem um ramo aqui, e que ele não faz nada.
Provavelmente você deve usar uma construção [!java]switch case[/!][!scala]pattern matching[/!] para manter seu código legível. Se você não lembra o que é isto, veja este exercício.
[/!]Você agora tem informação o suficiente para conseguir.
De acordo com a wikipédia, os turmites foram inventados independentemente no final dos anos oitenta. Foi provado que turmites em geral são exatamente equivalentes em capacidade a máquinas de turing uni-dimensionais com uma fita infinita, pois um pode simular o outro. Isto significa que qualquer programa que você possa conceber pode teoricamente ser executado neste dispositivo...