01 · Visão geral
Sobre Karel
Karel é um robô que recebe instruções para resolver tarefas simples em um mundo de ruas, esquinas e paredes. O modelo foi criado para que os primeiros exercícios de programação enfatizem a decomposição de problemas e a sequência de comandos.
Esta página escolhe a referência Java da Stanford, que define uma classe de programa e um método run. Outras implementações podem usar Python ou sintaxes próprias; não misture exemplos de versões diferentes.
02 · Ambiente
O mundo em grade
O mundo de Karel é uma grade de ruas e avenidas; cada cruzamento é uma esquina. O robô ocupa uma esquina e aponta para norte, sul, leste ou oeste. O cenário tem paredes nas bordas, mas suas dimensões mudam de exercício para exercício.
- Posição e direção: a esquina ocupada e a orientação atual do robô.
- Paredes: bloqueiam o caminho entre duas esquinas; os sensores verificam o entorno relativo à orientação.
- Beepers: podem estar em uma esquina ou na bolsa do robô. Karel só detecta beepers na esquina atual; a bolsa padrão comporta uma quantidade ilimitada.
- Estado inicial e meta: cada exercício define o cenário inicial e o resultado que o programa deve alcançar.
Tentar atravessar uma parede, recolher um beeper inexistente ou colocar um beeper com a bolsa vazia gera um erro em tempo de execução.
03 · Organização
Estrutura do programa
Um programa Java de Karel declara uma classe que estende SuperKarel. O método público run() contém as instruções iniciais; métodos privados podem ser declarados dentro da classe para nomear sequências reutilizadas.
import stanford.karel.*;
public class ExemploKarel extends SuperKarel {
public void run() {
move();
turnLeft();
}
}
O código usa blocos entre chaves, ponto e vírgula ao fim das instruções e comentários Java com // ou entre /* e */.
04 · Ações
Comandos básicos
| Comando | Ação |
|---|---|
move() | Avança uma esquina, se não houver parede à frente. |
turnLeft() | Gira 90 graus para a esquerda. |
putBeeper() | Coloca um beeper na esquina atual e retira um da bolsa. |
pickBeeper() | Recolhe um beeper da esquina atual e o guarda na bolsa. |
As quatro instruções primitivas são chamadas com parênteses vazios e terminam com ponto e vírgula. move() falha diante de uma parede; pickBeeper() exige um beeper na esquina; putBeeper() exige um beeper na bolsa.
05 · Observação
Sensores e condições
Karel consulta condições do entorno imediato; ele não recebe o mapa inteiro como um valor. Cada sensor devolve um valor lógico que pode ser usado em if, while e expressões booleanas.
| Sensor | Verdadeiro quando |
|---|---|
frontIsClear() / frontIsBlocked() | Não há / há uma parede à frente. |
leftIsClear() / leftIsBlocked() | O caminho à esquerda está livre / bloqueado. |
rightIsClear() / rightIsBlocked() | O caminho à direita está livre / bloqueado. |
beepersPresent() / noBeepersPresent() | Há / não há beepers na esquina atual. |
beepersInBag() / noBeepersInBag() | A bolsa contém / não contém beepers. |
facingNorth(), facingEast(), facingSouth(), facingWest() | Karel aponta para a direção indicada. |
notFacingNorth(), notFacingEast(), notFacingSouth(), notFacingWest() | Karel não aponta para a direção indicada. |
Os sensores de parede referem-se à direção atual do robô. Em Java, condições podem ser negadas com ! ou combinadas com && e ||; use os nomes opostos da tabela quando isso deixar a intenção mais clara.
06 · Fluxo
Decisões e repetições
A referência Java usa as estruturas if, if/else, while e for. Elas permitem reagir às condições do mundo e repetir uma sequência de ações.
if (frontIsClear()) {
move();
} else {
turnLeft();
}
while (beepersPresent()) {
pickBeeper();
}
for (int i = 0; i < 3; i++) {
move();
}
Um laço baseado em sensor precisa modificar o mundo ou a posição do robô para alcançar uma condição de parada. Confira as paredes e os beepers do cenário antes de executar a sequência.
07 · Reuso
Métodos próprios
Um método privado dá nome a uma ação composta. Depois de declarado na classe, ele pode ser chamado por run() ou por outros métodos da mesma classe.
private void turnRightSafely() {
turnLeft();
turnLeft();
turnLeft();
}
public void run() {
move();
turnRightSafely();
move();
}
O método acima usa apenas três giros à esquerda, o comando primitivo listado na base de Karel. Quando SuperKarel está disponível, turnRight() expressa a mesma intenção diretamente.
08 · Estado
Estado e dados
O problema pode ser resolvido apenas com posição, direção, paredes e beepers, mas a referência Java também oferece construções comuns do Java, como variáveis locais e contadores em laços. O robô mantém o estado físico do mundo; variáveis do programa ajudam a registrar etapas ou quantidades.
int passos = 0;
while (frontIsClear()) {
move();
passos++;
}
putBeeper();
Use estado adicional somente quando ele ajudar a descrever a solução. Para exercícios iniciais, muitas tarefas podem ser resolvidas com sensores e métodos bem nomeados.
09 · Exemplo integrado
Avançar e marcar a esquina
O programa avança até encontrar uma parede e deixa um beeper na posição final, caso ainda não exista um:
import stanford.karel.*;
public class MarcarDestino extends SuperKarel {
public void run() {
while (frontIsClear()) {
move();
}
if (noBeepersPresent()) {
putBeeper();
}
}
}
10 · Recursos adicionais
Recursos de SuperKarel
SuperKarel acrescenta recursos à classe base. Eles ficam disponíveis quando a classe do programa estende SuperKarel.
| Elemento | Tipo | Comportamento |
|---|---|---|
turnRight() | Ação | Gira 90 graus para a direita. |
turnAround() | Ação | Gira 180 graus. |
random(p) | Condição | Retorna verdadeiro com probabilidade p, entre 0.0 e 1.0. |
paintCorner(color) | Ação | Pinta a esquina atual com uma cor. |
Nos materiais Java de Stanford, as cores são constantes como RED e YELLOW, sem aspas. O livro original também descreve random(), que tem 50% de chance de retornar verdadeiro, e a condição cornerColorIs(color). Esses dois recursos não aparecem na ficha resumida do Karel Reader; confirme se a biblioteca usada os oferece.
11 · Repetição com segurança
Laços, limites e erro de uma posição
for é adequado quando a quantidade de passos é conhecida. while é adequado quando o robô deve reagir ao mundo, como avançar até uma parede. A condição de um while é verificada antes do corpo, então o corpo pode não executar nenhuma vez.
while (frontIsClear()) {
if (noBeepersPresent() && beepersInBag()) {
putBeeper();
}
move();
}
if (noBeepersPresent() && beepersInBag()) {
putBeeper();
}
O teste dentro do laço cobre cada esquina antes do movimento; a verificação final cobre a esquina onde Karel para. Essa diferença entre quantas esquinas existem e quantas vezes o robô consegue avançar é a origem comum do erro de uma posição.
Todo laço precisa de uma condição de parada que possa ser alcançada. Em laços de sensores, cada volta deve mudar a posição, a orientação ou os beepers de modo que o teste possa mudar.
12 · Planejamento
Decomposição e contratos
Antes de escrever comandos, descreva o estado inicial e o resultado esperado: onde Karel começa, para que lado olha, quais paredes existem e quantos beepers estão disponíveis. Divida a solução em ações nomeadas que expressem uma intenção, como moveToWall() ou turnAround().
Um método privado sem parâmetros funciona como uma instrução nova. Para cada método, registre mentalmente a precondição — o que deve ser verdade antes da chamada — e a pós-condição — o que o método garante ao terminar. A saída de um método precisa satisfazer o que o próximo método espera.
private void moveToWall() {
while (frontIsClear()) {
move();
}
}
public void run() {
moveToWall();
turnAround();
}
Esse método deixa Karel na esquina mais distante em frente a ele, ainda voltado para a parede. Explicitar esse resultado facilita reutilizar e revisar a sequência.
13 · Verificação
Testar mais de um cenário
Uma solução correta deve respeitar o estado do mundo, e não apenas funcionar no cenário usado para escrevê-la. Varie o tamanho da grade, a posição das paredes, a orientação inicial e a presença de beepers.
- Teste uma grade mínima e um corredor com apenas uma esquina de avanço.
- Teste o caso em que a parede já está à frente no início.
- Teste esquinas com e sem beepers e a bolsa vazia quando a tarefa permite isso.
- Confira o estado final: posição, direção, paredes preservadas e quantidade de beepers.
Uma tentativa inválida de atravessar uma parede, recolher um beeper ausente ou colocar um beeper sem estoque é erro do programa para aquele mundo. Sensores devem proteger as ações que dependem dessas condições.
14 · Leitura adicional
Referências
- Karel Reader da Stanford, versão Java.
- Referência de comandos, condições e estrutura do programa.
- Livro introdutório original de Karel, que apresenta o mundo do robô e a motivação educacional do projeto.