Uma solução é ler a próxima célula e copiá-la à posição antes de voltar para
ler a segunda célula. Mas já que é proibido usar os métodos de
teletransporte de buggle para uma posição específica (setPos()
e similares), esta abordagem seria muito difícil de implementar.
O mais simples é armazenar a sequência de cores que constituem o padrão inteiro numa [!java|scala]array[/!][!python]list[/!]. Mas antes de fazer isto, devemos aprender um pouco sobre o que [!java|scala]arrays[/!][!python]lists[/!] são.
[!java|scala]Uma array[/!][!python]Uma list[/!] é uma sequência ordenada de
variáveis que ficam juntas. é similar a uma estante onde em cada prateleira
se coloca um valor separado. Cada variável da sequência é identificada pela
posição dela e pode armazenar um valor específico. [!java|scala]todas as
células da array devem armazenar valores do mesmo tipo por que arrays são
homogêneas em [!thelang]. É possível burlar esta restrição a usar tipos de
dados [!java]Object[/!][!scala]Any[/!]
que contenham
[!java]praticamente[/!] qualquer outro tipo de dados. [!java]Tipos
primitivos como aqueles que vimos anteriormente (int, boolean, double, char,
etc) não podem ser armazenados numa variável Object, mas suas contrapartidas
objetificadas (Integer, Boolean, Double, Char, Boolean, etc) podem.[/!]
Entretanto, é boa prática fazer o tipo de uma array o mais específico
possível, p.ex., se planea armazenar alguns inteiros na sua array, faça dela
uma array de inteiros, não de [!java]Object[/!][!scala]Any[/!].[/!]
[!python]Lists podematé mesmo misturar valores de diferentes tipos, como
valores inteiros em algumas células e cores em outras células.[/!]
T é o nome da [!java|scala]array[/!][!python]list[/!], [!java|python]T[0][/!][!scala]T(0)[/!] é o nome da primeira célula, [!java|python]T[1][/!][!scala]T(1)[/!] é o nome da segunda célula, [!java|python]T[2][/!][!scala]T(2)[/!] da terceira e etc. E sim, a primeira célula é numerada [!java|python]T[0][/!][!scala]T(0)[/!] e a última de uma [!java|scala]array[/!][!python]list[/!] de tamanho N é [!java|python]T[N-1][/!][!scala]T(N-1)[/!]. Pode parecer estranho contar a partir de 0 e não de 1 como normalmente, mas por motivos históricos isto agora é inevitável.
Podemos usar uma variável inteira i para acessar com
[!java|python]T[i][/!][!scala]T(i)[/!] as células: quando o valor de
i é 0, [!java|python]T[i][/!][!scala]T(i)[/!] acessa
[!java|python]T[0][/!][!scala]T(0)[/!]; quando o valor de i é 10,
[!java|python]T[i][/!][!scala]T(i)[/!] acessa
[!java|python]T[10][/!][!scala]T(10)[/!]. Sizemos que i é o
índice em T. [!java|python]T[i][/!][!scala]T(i)[/!]
pode
ser usada simplesmente como qualquer variável. Podemos configurar um novo
valor:
[!java|python]T[i][/!][!scala]T(i)[/!] = 78[!java];[/!]
Podemos recuperar e usar valor dele:
x = [!java|python]T[i][/!][!scala]T(i)[/!][!java];[/!]
Podemos testar este valor:
if ([!java|python]T[i][/!][!scala]T(i)[/!] > 0) [!scala|java]{[/!][!python]:[/!] [!java|scala]//[/!][!python]#[/!] instruções... [!java|scala]}[/!]
É muito fácil percorrer toda a [!scala|java]array[/!][!python]list[/!], por exemplo para iniciar as células.
[!java]for (int i = 0; i<T.length; i++) {[/!][!python]for i in range(len(T)):[/!][!scala]for (i <- 0 to T.length-1) {[/!] [!java|python]T[i][/!][!scala]T(i)[/!] = 3[!java];[/!] [!java|scala]}[/!]
[!java|scala]A notação T.length
recupera o comprimento (length)
da array T,[/!] [!python]A função len()
recupera o comprimento
da lista T,[/!] a permitir que se construa um loop clássico facilmente.
[!python]Na verdade, a função len()
é muito mais genérica e
pode ser usada para recuperar o comprimento de muitos objetos. Aplicada numa
cadeia, por exemplo, ela retorna a quantidade de caracteres na cadeia.[/!]
[!scala]Não se esqueça de começar em 0
e terminar em
T.length-1
ao invés de ir de 1
até
T.length
.[/!]
Se quer simplesmente iterar nos valores de T sem controlar o índice, pode simplesmente escrever:
[!java]for (int i: T) {[/!][!scala]for (i <- T) {[/!][!python]for i in T:[/!] ação()[!java];[/!] [!java|scala]}[/!]
[!java]Esta construção é chamada um loop extendido em Java. A
variável i assume todos os valores do conjunto localizado a direita
do dois-pontos (:), um depois do outro.[/!] [!python|scala]Isto é na verdade
muito similar à construção anterior. Simplesmente,
[!python]range(n)[/!][!scala]i to j[/!]
retorna um conjunto de
inteiros sobre os quais o loop for itera. Na verdade, [!thelang] oferece
formas muito mais elegantes de percorrer
[!python]lists[/!][!scala]arrays[/!] e outras coleções de dados, mas isto
fica para um conjunto específico de exercícios (que ainda será escrito no
PLM).[/!]
Se sabe antecipadamente o conteúdo da sua lista, pode atribuir os valores todos juntos. Ponha eles simplesmente entre colchetes e separados por vírgulas como segue:
L = [1, 3, 5, 7, 9]
# L agora é uma array de 5 valores, todos eles inteiros
Por outro lado, provavelmente vai criar uma lista vazia e depois anexar-la os valores separadamente:
L2 = [] # neste momento, L2 é uma lista vazia L2.append(1) L2.append(3) L2.append(5) L2.append(7) L2.append(9) # E agora o seu conteúdo é igual ao de L, vista antes[/!] [!java|scala]
Para declarar uma variável chamada T que pode guardar uma array de inteiros, deve escrever:
[!java]int[] T;[/!][!scala]var T:Array[Int][/!]
[!java]int
significa que os elementos da array são do tipo
inteiro; []
significa que estamos a falar de uma array e
T
é o nome da variável. Por motivos históricos, também pode ser
escrito como int T[]
(com o [] depois do nome da variável), mas
como assim é menos legível, é melhor evitar esta forma.[/!] [!scala]A
notação [Int]
especializa o tipo Array (que é genérico), a
especificar que cada célula desta array é um inteiro. Um array de booleanos
deve ser escrito simplesmente como Array[Boolean]
.[/!]
Declarar uma variável T
que armazena uma array apenas reserva o
nome T
para uso futuro, mas não reserva a área de
memória para armazenar as células. A array ainda não está inicializada: ela
não tem qualquer valor. O que significa
[!java]T[4][/!][!scala]T(4)[/!]
se ainda não dissemos que a
array tem 5 células?
Primeiramente, temos que dar um valor a T
:
[!java]T = new int[10];[/!][!scala]var T = new Array[Int](10)[/!]
new
(novo) significa que queremos criar algo e
[!java]int[10][/!][!scala]Array[Int](10)[/!]
significa que é
uma array de 10 valores inteiros. Como resultado, uma array de 10 células
para valores inteiros é criada na memória e a variável T
faz
referência a esta array.
O tamanho de uma array é fixo e não pode ser mudado depois da criação da
array. O tamanho de uma array T
pode ser recuperado ao se
consultar a variável T.length
.
Ao alocar pode especificar o tamanho com uma variável: [!java]int[] T
= new int[i];[/!][!scala]var T = new Array[Int](i);[/!]
Neste caso, o
tamanho da array será ajustado para o valor de i
quando
new
for chamado. O tamanho da array ainda não pode ser
modificado: mesmo se a variável i
mudar depois disto, o tamanho
permanece o do valor dado no momento da alocação. [!java]Além disto, é
proibido escrever algo como int T[10];
no momento de declarar a
variável. Deve usar a instrução new
para alocar o array, como
em int[] T = new int[10];
[/!]
Se sabe previamente o conteúdo da sua array, pode declarar, alocar e inicializar-la toda de uma vez:
[!java]int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };[/!][!scala]var T = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)[/!]
Para saber o tamanho da array para alocar, o compilador conta os valores dados. Este código é equivalente a:
[!java]int[] T = new int[10]; T[0] = 1; T[1] = 2; ... T[9] = 10;[/!][!scala]var T = new Array[Int](10); T(0) = 1 T(1) = 2 ... T(9) = 10[/!]
também é equivalente a:
[!java]int[] T = new int[10]; for (int i=0; i<T.length; i++) { T[i] = i+1; }[/!][!scala]var T = new Array[Int](10); for (i <- 0 to T.length-1) { T(i) = i+1 }[/!][/!]
Não há nenhum problema em passar uma [!python]list[/!][!java|scala]array[/!] para um método como parâmetro. Este método pode então usar este parâmetro como se fosse definido localmente:
[!java]boolean has42First(int[] array) { return array[0] == 42; }[/!][!python]def has42First(list): return list[0] == 42[/!][!scala]def has42First(array:Array[Int]):Boolean = { return array(0) == 42 }[/!]
No lado de quem invoca também é bastante simples:
[!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!] [!java|scala]// inicialização de valores omitida [/!]if (has42First(tab))[!java|scala] {[/!][!python]:[/!] [!java|scala]//[/!][!python]#[/!] faz algo [!java|scala]}[/!][!java]
Se quer alocar e inicializar o array de uma vez só, é um pouco mais complicado pois o compilador terá que saber o tipo do parâmetro queestá a criar. Para isto, use a seguinte construção (feia):
if (has42First( new int[] {1, 3, 5, 7, 9} ) {
// faz algo
}
[/!]
Métodos também podem retornar [!java|scala]arrays[/!][!python]lists[/!] como resultado sem nenhuma complicação. Aqui está um método que retorna uma [!java|scala]array[/!][!python]list[/!] do tamanho pedido, preenchido com 42s.
[!java]int[] fill42(int size) { int[] res = new int[size]; for (int i=0; i<size; i++) res[i] = 42; return res; }[/!][!scala]def fill42(size:Int):Array[Int] = { var res = new Array[int] (size) for (i <- 0 to size -1) { res(i) = 42; } return res; }[/!][!python]def fill42(size): res = [] for i in range(size): res.append(42) return res[/!]
Finalmente! Depois desta longa explicação, podemos voltar ao exercício.
A sua missão é bastante simples, na verdade. O seu código deve guardar o
padrão de cores observado na primeira linha numa
[!java|scala]array[/!][!python]list[/!]. [!python]O mais fácil é criar uma
lista vazia e depois usar append()
para adicionar as cores uma
por uma à medida que for a ler elas (com getGroundColor()
).[/!]
[!java|scala]Para isto, deve declarar e alocar uma array de
Cor
. Mas atencção, existem vários mundos, de diferentes
tamanhos; use getWorldHeight()
para recuperar o tamanho do
mundo atual. Uma que a array esteja alocada, preencha ela a ler a cor do
chão em cada um dos pontos (com getGroundColor()
).[/!]
Uma vez que conseguiu ler e gravar o padrão na primeira linha, tem que
reaplicar o padrão nas outras linhas, por exemplo a executar
getWorldHeight()
vezes um método escrito especificamente para
isto.