Programa básico se comportando de forma inesperada

14 respostas
F

Escreví um programa com o seguinte código:

/**

  • Title : RandomN.java
  • Author : Filipe Jardim de Almeida
  • Version : 3.00 2007/11/14
    */
public class RandomN {

public static void main(String[] args)

throws java.io.IOException {
char LeSec, Resp, alfabeto[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'z'};
		int rI = 0 + (int)(Math.random() * 23);
		int i;		
					
		LeSec = alfabeto[rI];
		System.out.println("** Jogo 'advinhe a letra' V3.00 ** \nAdvinhe qual letra eu estou pensando?\nVoce tem 10 tentativas:");
		//System.out.println(LeSec);
		
		for (i = 0; i <= 10; ) {
			Resp = (char) System.in.read();
			i++;
			
			if (LeSec == Resp) {
				System.out.println("BLZ! Vc acertou!!!");
				i = 11;
			}
			
			else if (Resp > LeSec) System.out.println("N, vc chutou ALTO d+!");
			
			else if (Resp < LeSec) System.out.println("N, vc chutou BAIXO d+!");
			
			else System.out.println("Tilt");
		}
}

}

Entretanto a execução é sempre algo do tipo:

C:\Documents and Settings\filipe.almeida\Meus documentos\CURSO - JAVA\exercícios\Livro - A beginner’s Guide>java RandomN
** Jogo ‘advinhe a letra’ V3.00 **
Advinhe qual letra eu estou pensando?
Voce tem 10 tentativas:
a
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
a
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
a
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!

N, vc chutou BAIXO d+!

Pq ele faz isso? pq o loop executa 3vezes ao mesmo tempo?
Obrigado por qualquer ajuda!

14 Respostas

wamarra

Tente trocar:

for (i = 0; i <= 10; ) { Resp = (char) System.in.read(); i++;
Por:

for (i = 0; i <= 10; i++) { Resp = (char) System.in.read();

F

Já tinha tentado isso…
não fez qualquer diferença…
Obrigado de qualquer forma, alguma outra ideia?

wamarra

só uma dica:

Se o usuário tem 10 tentativas.
Pelo seu for está sendo executado 11 vezes

Teria que trocar:

for (i = 0; i <= 10; i++) { Resp = (char) System.in.read();

por:

for (i = 0; i < 10; i++) { Resp = (char) System.in.read();

ou:

for (i = 1; i <= 10; i++) { Resp = (char) System.in.read();

G

Não sei te responder, mas tem algo com os ifs…

fiz uns teste alterando - os e veja o resultado…

** Jogo ‘advinhe a letra’ V3.00 **
Advinhe qual letra eu estou pensando?
Voce tem 10 tentativas:
f
N, vc chutou ALTO d+!
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
j
N, vc chutou ALTO d+!
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
e
N, vc chutou ALTO d+!
N, vc chutou BAIXO d+!
N, vc chutou BAIXO d+!
g
N, vc chutou ALTO d+!
N, vc chutou BAIXO d+!

Como q ele pode dizer ALTO e BAIXO???

F

Sobre as tentativas, n tem problema…
E sobre os ifs…
é justamente oq eu tou tentando entender…

J
Antes do for vc faz assim

Scanner scan=new Scanner(System.in);

Na sua linha

Resp = (char) System.in.read();

coloca assim

Resp=scan.next().charAt(0);
AndreAlves

O problema é que o System.in.read só executa após o .

Quando o usuário digita o caractere e dá , você recebe três bytes… o caracter digitado, o line feed e o carriage return.
Então, para o teu código funcionar, você precisa fazer o seguinte:

resp = (char) System.in.read();
System.in.read();
System.in.read();

As duas chamadas irão pegar o line feed e o carriage return que representam o
Uma dica… não inicie nome de variável/atributo com letra maiúscula. Siga o padrão da Sun.

L

Caro colega subtitua seu código pelo abaixo. Note que foi usado o BufferedReader para realizar a leitura do teclado. Se não enteder de um grito!!!

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	for (i = 0; i <= 10;) {
	    Resp = (char) br.readLine().charAt(0);

O seu código

for (i = 0; i < 10; i++) {     
  Resp = (char) System.in.read();
G

Putz… eu ja tava testando usando o o Scanner… mas nao sabia como ele pega o char…

G
/** 
* Title : RandomN.java 
* Author : Filipe Jardim de Almeida 
* Version : 3.00 2007/11/14 
*/ 

import java.util.Scanner;

public class RandomN { 
public static void main(String[] args) 
throws java.io.IOException { 

char LeSec, Resp, alfabeto[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'z'}; 
int rI = 0 + (int)(Math.random() * 23); 
int i; 

LeSec = alfabeto[rI]; 
System.out.println("** Jogo 'advinhe a letra' V3.00 ** \nAdvinhe qual letra eu estou pensando?\nVoce tem 10 tentativas:"); 
//System.out.println(LeSec); 


Scanner input = new Scanner(System.in);

for (i = 0; i <= 9; i++) { 
Resp = input.next().charAt(0); 
 

if (LeSec == Resp) { 
System.out.println("BLZ! Vc acertou!!!"); 
i = 9; 
} 

else if (Resp > LeSec) System.out.println("N, vc chutou ALTO d+!"); 

else if (Resp < LeSec) System.out.println("N, vc chutou BAIXO d+!"); 

else System.out.println("Tilt"); 
} 
} 
}
ViniGodoy

Tá quase certo.

Mas algumas dicas:
System.in.read() não funciona dessa forma, melhor usar a classe scanner.
O Math.random() não gera bons números aleatórios, melhor usar a classe Random.

Exemplo:
import java.util.Random;
import java.util.Scanner;

/**
 * Title : RandomN.java Author : Filipe Jardim de Almeida Version : 3.00
 * 2007/11/14
 */
public class RandomN {
    public static void main(String[] args) throws java.io.IOException {
        char LeSec, Resp, alfabeto[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
                'i', 'j', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                'v', 'x', 'z'};
        
        Random random = new Random();        
        int rI = random.nextInt(alfabeto.length);
        
        int i;

        LeSec = alfabeto[rI];
        System.out.println("** Jogo 'advinhe a letra' V3.00 ** \nAdvinhe qual letra eu estou pensando?\nVoce tem 10 tentativas:");
        Scanner in = new Scanner(System.in);        
        
        for (i = 0; i <= 10;) {
            Resp = in.nextLine().charAt(0);
            i++;

            if (LeSec == Resp) {
                System.out.println("BLZ! Vc acertou!!!");
                i = 11;
            }
            else if (Resp > LeSec)
                System.out.println("N, vc chutou ALTO d+!");
            else if (Resp < LeSec)
                System.out.println("N, vc chutou BAIXO d+!");
            else
                System.out.println("Tilt");
        }
    }
}

PS: Legal o joguinho. Bem casual. E se o usuário tiver uma noção de busca binária, pode vencer sempre.

ViniGodoy

Oi. Esse é o mesmo código anterior, só que com algumas refatorações:

import java.util.Random;
import java.util.Scanner;

/**
 * Title : RandomN.java Author : Filipe Jardim de Almeida Version : 3.00
 * 2007/11/14
 */

public class RandomN {
    public static void main(String[] args) {
        char leSec = (char) ('a' + new Random().nextInt(26));        
        System.out.println("** Jogo 'advinhe a letra' V3.00 **");
        System.out.println("Advinhe qual letra eu estou pensando!");
        System.out.println("Voce tem 10 tentativas:");
        Scanner in = new Scanner(System.in);

        for (int i = 0; i <= 10; i++) {
            char resp = in.nextLine().charAt(0);            

            if (leSec == resp) {
                System.out.println("BLZ! Vc acertou!!!");
                break;
            }
            
            System.out.println("Não, você chutou " + (resp > leSec ? "ALTO" : "BAIXO") + " d+!");            
        }
    }
}
ViniGodoy

O que eu fiz:

  1. Variáveis agora seguem a convenção do Java: Seus nomes iniciam com minúsculas;

  2. A criação das variáveis estão no ponto imediatamente anterior onde vão ser usadas;

  3. O for está sendo usado de uma maneira mais tradicional;

  4. Usei a propriedade dos chars de poderem ser somados como valores numéricos. Então, ‘a’ é a primeira letra e ‘a’ + 25 é o ‘z’. Note que seu código não sorteava todas as letras do alfabeto.

  5. Ao invés de atribuir i = 11 (algo que é meio obscuro), usei o comando break para parar o for. O break irá mandar o código para depois do for, portanto o else fica desnecessário;

  6. Eliminei o else com “Tilt”. É impossível ocorrer aquilo mesmo. Ou então troque por else assert(false);

  7. O for para ALTO e BAIXO foi substituído pelo operador ternário.

  8. Os printlns foram divididos em várias linhas, o que deixa o código mais limpo;

F

Valeu gente! Brigadão! Vocês me ajudaram bastante! E brigado também pelas dicas de como melhorar o código, isso foi bem legal para eu entender melhor sobre java, tou começando agora e é legal ter umas dicas assim pra engrenar na programação. :smiley:

Um abração gente!
FJA.

Criado 14 de novembro de 2007
Ultima resposta 16 de nov. de 2007
Respostas 14
Participantes 7