Ciclos de repetição - Pascal - Portugal-a-Programar
By crazypt14, June 8, 2013 in Pascal
Boas pessoal, tenho um trabalho de tema livre, em que tenho de usar todos os ciclos de repetição escolhi fazer um quiz sobre jogos, mas agora nao sei onde por os ciclos, se me pudessem dar ideias sff vou deixar o codigo que já tenho abaixo, aviso que o que está em branco é que eu ainda vou acabar...
var nome, terror1,terror2,terror3,terror4,guerra1,guerra2,guerra3,guerra4,guerra5,rpg1,moba1,moba2,moba3,moba4,moba5:string;
idade,certo,op,consola,escolha1,topico:integer;
certo:=0;
writeln('Bem-vindo ao quiz de escolha multipla sobre jogos/consolas!! Boa Sorte!');
writeln('Para começar, introduza o seu nome, por favor:');
writeln('Introduza a sua idade, por favor:');
writeln('Escolha uma das opções seguintes:');
writeln('1-Consolas;');
writeln('2-Jogos.');
readln(escolha1);
case escolha1 of
writeln('Voçê escolheu consolas!');
writeln('Escolha uma das consolas abaixo:');
writeln('1-Playstation;');
writeln('2-Xbox;');
writeln('3-Nintendo.');
readln(consola);
case consola of
writeln('Escolha uma das seguintes opções, por favor:');
writeln('1- Terror;');
writeln('2- Guerra;');
writeln('3- RPG;');
writeln('4- Mobas.');
readln(topico);
case topico of
writeln('Qual foi o primeiro jogo de terror publicado?');
writeln('  A -> Amnesia;');
writeln('  B -> Haunted House;');
writeln('  C -> Daylight.');
terror1:=upcase(readkey);
writeln(terror1);
if (terror1<>'A') and (terror1<>'B') and (terror1<>'C') then writeln('ERRO! Caracter errado.');
until (terror1='A') or (terror1='B') or (terror1='C');
writeln('A resposta certa é....');
writeln('B - Haunted House. Publicado em 1972, pela empresa Magnavox.');
writeln('Pressione <ENTER> para continuar.');
writeln('O jogo Amnesia: The Dark Descent é passado onde?');
writeln('A - Castelo Windsor;');
writeln('B - Castelo Brougham;');
writeln('C - Castelo Brennenburg.');
terror2:=upcase(readkey);
writeln(terror2);
if (terror2<>'A') and (terror2<>'B') and (terror2<>'C') then writeln('ERRO! Caracter errado.');
until (terror2='A') or (terror2='B') or (terror2='C');
writeln('Qual o nome da personagem do jogo "The Stanleys Parable"?');
readln(terror3);
readln(terror4);
Writeln('Você escolheu a categoria de Guerra, ou por outras palavras, First person shooters/ Thrid person shooters, vamos começar:');
writeln('Qual foi o primeiro jogo de guerra publicado e em que tempo era passado?');
readln(guerra1);
writeln('Quantas armas tem o Battlefield 3?');
readln(guerra2);
writeln('Qual a idade da maioria dos jogadores de CoD (Call Of Duty)?');
readln(guerra3);
writeln('Quais as empresas que desenvolvem os jogos Battlefield?');
readln(guerra4);
writeln('Quantos jogos de guerra conhece?');
readln(guerra5);
writeln('Quantos RPGs conhece?');
readln(rpg1);
writeln('Quantos mobas conhece?');
readln(moba1);
writeln('Começando pelo League of Legends, quantos champions/personagens existem?');
readln(moba2);
writeln('Quantos modos de jogo existem?');
readln(moba3);
writeln('Quantos tipos de jogador existem num jogo de 5vs5?');
readln(moba4);
writeln('Em Ranked,quantas divisoes existem? Qual a divisao mais alta?');
readln(moba5);
Coloca ciclos para saber se o utilizador quer jogar outra vez, para introduzir uma idade válida, coisas assim.
já estou a usar repeat para as respostas nao sairem de 'A' 'B' ou 'C' mas nao sei mesmo onde por o for e o while...
O while para o controlo da idade, e o for seria ideal se tivesses as perguntas guardadas num ficheiro e não num emaranhado de código sem fim no próprio programa.
Talvez seja interessante que você descubra um pouco mais sobre cada tipo de comando que implementa ciclos.
Por exemplo, o for é usado, geralmente, para se executar um trecho em uma determinada quantidade de ciclos, valor que é periodicamente armazenado em um "contador" que pode ser amplamente aproveitado. Já o while e o repeat permitem que se repita um trecho de código até que determinada condição seja alcançada, não necessariamente importando a quantidade de vezes que o trecho será reiterado, por assim dizer.
A minha sugestão é que você utilize o while e o repeat alternadamente para realizar a mesma função, neste caso para basicamente validar as entradas do usuário, como você já fez. Se precisar use o comando break. Como não vi uma aplicação clara para o for no objetivo principal deste programa, recomento que você desenhe retângulos para decorar a tela. Dica: Use o caractere #219 para criar os retângulos.
Deixo claro que por somente se tratar de um exercício didático isso ainda pode ser válido, mas as minhas sugestões são meras "extensões de luz" ou "gambiarras", como se diz na minha terra, isso porque só uma das funções, especialmente o repeat, seria necessária. ;-)
Edited June 9, 2013 by GRSa
Ainda não dei com ficheiros, ainda nem arrays dei por isso... Estou limitado a tudo o que está dos ciclos de repetições para trás...
Obrigado pela sugestão @GRSa
Resumo da utilidade das estruturas repetitivas (ciclos):
FOR: Sempre que um determinado código deva ser repetido um certo numero de vezes
REPEAT: Sempre que um determinado código deva ser repetido pelo menos uma vez, até que uma certa condição se revele verdadeira
WHILE: Sempre que um determinado código deva ser repetido enquanto uma determinada condição se mantenha verdadeira, podendo dar-se o caso desta ser falsa logo à partida e neste caso o código não é executado nenhuma vez.
for inicializacao to valor_fim do
(incremento automático)
while condição_fim do
until condição_fim
o while e o repeat são praticamente iguais, no entanto o repeat executa pelo menos uma vez as instruções
ao contrário do while e do repeat nos quais o incremento pode ser o que tu quiseres no ciclo for o incremento é de 1 (ou decremento se usares o down to)
Edited June 18, 2013 by thoga31
Ok, obrigado pela explicação pessoal, não vos quero chatear nem nada, mas eu já sabia disso... O meu problema não era esse, era o que haveria de fazer no código para meter os ciclos, não ia por exemplo meter um for a repetir um writeln('Olá tudo bem?');
Percebemos isso! Mas é mais fácil escolher o ciclo a usar quando temos em ideia um programa, do que escolher o programa a fazer quanto temos em ideia um ciclo!
Ora, muito genericamente:
Repeat - Menu
For - Isto era mesmo para arrays... Lembra-te que nem sempre o facto de não teres aprendido não significa que não possas usar... Se eu só tivesse usado, em tempos de escola, o que os professores me ensinaram de Pascal, hoje eu seria um excelente agricultor (ou qualquer outra profissão, que ao caso não interessa qual).
While - Assim de repente não vejo nada para usares o while directamente. Mas não é dificil inverteres a utilização, e meteres um while onde normalmente punhas um repeat. É um bocadinho rebuscado, mas também o é a ideia de fazer um programa com o intuito de usar comandos, sem haver um objectivo prático definido... Se é para usar, que se usem!
Pode perfeitamente transformar-se nisto:
Para mim, o programa perfeito para aplicar ciclos continua a ser uma calculadora com alguns "enfeites natalícios" (que não são exactamente desenhos e coisas assim).
Utilizar um for sem ser para uma Array é simples: podes utilizar para uma TStringList, mas se apareces com isso ao professor, ele ainda se questiona se é Pascal (claro que sim) - o meu ponto é: utilizar for por utilizar não faz sentido, o grande objecto de uso dele são os arrays.
Quanto ao resto, já não há muito a dizer.
Eu diria até que usar seja o que for só por usar...
Bem, eu tenho tentado perceber como é que os arrays funcionam, mas cada vez que penso que já consigo utiliza-los apareçe me algo para me confundir todo e nunca consigo lá chegar...
Eu pergunto-me o que isso faz?
E o que é uma TStringList?
(Woaw! Tanta coisa que eu nunca ouvi falar!)
Bem, começando com os arrays, é só expores as tuas duvidas... É do tipo de coisas que facilmente vais compreender.
Uma TStringList é uma classe (programação orientada a objectos) que no fundo traduz um array de strings... com mais uns pozinhos!
Sabendo que um array é um conjunto de variáveis de um determinado tipo, e que podes aceder através de um número índice, imagina agora que num array do tipo string, tens além das variáveis comuns num array, a possibilidade (entre outras) de:
- Saber a cada momento quantas posições do array tens ocupadas
- Procurar em que posição está uma determinada string
- Apagar uma posição, ficando automáticamente "compactado" (todas as strings se arrumam à maneira de não haver espaços livres entre elas, causadas pelas eliminadas)
- Inserir uma nova string numa determinada posição, sem ter necessáriamente de ser no fim
- gravar todas as strings num ficheiro
- ler de um ficheiro para a StringList (cada linha do ficheiro é uma posição no array)
- Guardar um outro valor, de qualquer tipo, associado a cada posição do array (por exemplo, um array de nomes de jogos, mas em cada posição ou nome podes guardar também o endereço internet correspondente a esse jogo)
Isto são apenas algumas das funções da TStringList.
Não sendo um tipo de dados normal, mas sim uma classe, dentro da propria variável deste tipo tens não só o local para guardar dados, mas também as funções e procedimentos necessários para lidar com essa variável.
Arriscaria dizer que a maior parte dos professores que andam por aí a ensinar pascal não têm ideia sequer do que é isto, quando mais que isto seja possível em Pascal.
Mas o reverso da medalha: Para usares isto, enterra definitivamente o PZim. Instala o FreePascal, que é um compilador a sério. O PZim não é mais do que uma amostra, uma demonstração da linguagem Pascal (e nem os seus criadores pretendiam que fosse mais do que isso).
Quanto ao meu exemplo, tanto um código como o outro fazem o mesmo:
Leem uma tecla até que essa tecla seja o ESCAPE (#27).
Imagina que fazes um menu para o teu programa.
Queres que, quando o utilizador termine o que está a fazer, volte ao menu. Só terminará quando a opção escolhida for ESCAPE.
Logo, fazes isto:
// Inicia o ciclo do Menu
// Apaga o ecrã
// Escreve as opções do menu
WriteLn('<C>onsultar Jogos');
WriteLn('<A>dicionar Jogo');
WriteLn('<E>Eliminar Jogo');
WriteLn('<O>rdenar Jogos');
WriteLn('<T>erminar');
// Inicializa a variável ch com um valor nulo #0 - Isto é preciso porque estamos a usar o while em vez do repeat
// Inicia o ciclo de validação de opções
while not (ch IN ['C','A','E','O','T']) do   // Repete o ciclo enquanto a variável ch não for uma das opções apresentadas
ch:=UpCase(ReadKey);  // Lê para a variavel ch uma qualquer tecla (ReadKey), transforma-a em maiúscula (UpCase)
// Escreve no ecrã a opção escolhida - o ReadKey lê uma tecla sem precisar carregar em enter, mas não escreve nada no ecrã
// Testa a opção escolhida pelo utilizador. Se for uma das opções "de trabalho", chama os procedimentos respectivos (que para o caso não pus aqui, pois é só exemplificativo
'C':Consultar;
'A':Adicionar;
'E':Eliminar;
'O':Ordenar;
End;  // Note-se que não testei a opção de saida, não é necessário neste caso
Until ch='T';  // O ciclo termina quando a opção for a letra T
Atenção que pode haver neste exemplo coisas que no PZim não funcionem... NADA funciona no PZim!
Em relação á questão do PZim, já está resolvido, acabei de instalar o Lazarus 1.0.10 e vou começar a trabalhar nele... Ok percebi, muito obrigado pela explicação!
Só uma luzinha de atenção: o @nunopicado falou acerca do tipo de dados TStringList, que é, como ele disse naquele post exemplar, uma classe. Antes de pensares neste tipo de dados e noutros, concentra-te noutras coisas.
Vamos por partes. O professor autoriza a utilização de pequenos "artifícios" que ele ainda não leccionou (vá-se lá saber porquê, estamos no final do ano, e ainda não saber arrays... o que sabem afinal?)?
Se sim, então os Arrays são a forma perfeita de aplicar ciclos for.
O que é uma array? É uma estrutura bem organizada que pode ter várias dimensões e que permite guardar uma série de dados todos do mesmo tipo - não podes guardar uma String num índice e um Integer noutro.
Qual a sua estrutura? Cada elemento da array está localizado no seu índice. Uma array pode ser unidimensional (tipo um vector ou lista), bidimensional (tipo tabela) ou multidimensional (virtualmente podes ter as dimensões que quiseres).
Por exemplo, vejamos uma array unidimensional:
var lista : array [1..5] of integer;
Estamos perante uma array de integers que guarda 5 elementos, do nº 1 ao nº 5. Para aceder ao 2º elemento da lista, fazemos lista[2]. Se acederes ao elemento indice[6] vais apanhar literalmente lixo - não é nada que o Pascal não permita, mas estás a apontar para um índice não definido, pelo que vais apanhar qualquer coisa da memória RAM que é lixo.
Esta array pode ser representada em forma de uma lista. Por exemplo: [2, 7, 5, 4, 4].
E se quiser mais dimensões?
var lista : array [1..2, 1..5] of integer;
Como se pode ver, separa-se com vírgula. Aceder ao elemento de índice (1,4): lista[1,4].
Agora é começares a fazer experiências, e vens aqui esclarecer as tuas dúvidas.
btw, onde tens batido na parede com as arrays? Mostra-nos, não há forma mais fácil de aprender se não expor os nossos erros a quem sabe e quer ajudar
Bem, eu peguei num dos exemplos que estão no teu tutorial de pascal (@thoga31) e fiz isto, para tentar perceber melhor...
var lista : array[1..10] of integer;
i, aux,n:integer;
writeln('Introduza um numero para o espaço: ',i);
if(lista[i+1]<lista[i]) then begin
aux:=lista[i+1];
lista[i+1]:=lista[i];
writeln('pressione <ENTER>.');
No entanto, quando devia de aparecer os números por ordem, aparece tudo 0.
Se calhar estou a fazer tudo ao contrario ahah
Lê bem o teu código...
Fazes readln à variável n... Onde estás a atribuir valores à array lista?
E aviso-te já que esse método não organiza bem os números da lista.
Edited June 22, 2013 by thoga31
Ou se calhar, estás a ler 10 vezes para a mesma variável (n), e não para o Array!
Não precisas do n para nada.
Fazes o readln(lista); directamente.
Depois, o algoritmo de ordenação está errado.
Estás a testar cada número com o seu próximo, mas não com todos os próximos. Se tivesses 5,2,8,9,1, o resultado seria 2,5,8,1,9 e não 1,2,5,8,9
EDIT: Há aqui sintonia...
Edited June 22, 2013 by nunopicado
Mas temos ainda assim formas diferentes de abordar estas questões. Eu opto quando possível por puxar pela cabeça do pessoal, tu optas mais por explicar logo as coisas (quase) todas.