Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Prévia do material em texto

<p>REVISTA ELETRÔNICA PARA OS AFICCIONADOS DA LINGUAGEM PASCAL1</p><p>História da História da</p><p>Linguagem Linguagem</p><p>PascalPascal</p><p>LinguagemLinguagem</p><p>de Máquinade Máquina</p><p>AssemblyAssembly FortranFortran AlgolAlgol PascalPascal</p><p>Já é possível usar o Free PascalJá é possível usar o Free Pascal</p><p>como ambiente profissional?como ambiente profissional?</p><p>Confira entrevista com o criador do Pixel32Confira entrevista com o criador do Pixel32</p><p>RedirecionamentoRedirecionamento</p><p>e Interconexãoe Interconexão</p><p>Comunicação entre aplicaçõesComunicação entre aplicações</p><p>SnakeSnake</p><p>O jogo da cobraO jogo da cobra E muito maisE muito mais</p><p>AMBIENTES DE DESENVOLVIMENTO BASEADOS EM PASCAL</p><p>PROGRAMAÇÃO - APLICAÇÕES – JOGOS</p><p>REPORTAGENS</p><p>DICAS</p><p>JU</p><p>N</p><p>HO</p><p>/2</p><p>00</p><p>7</p><p>Nº 1</p><p>NESTE NÚMERO</p><p>FUNDAMENTOS</p><p>HISTÓRIA DA LINGUAGEM PASCAL</p><p>A origem, evolução e fatos que envolveram a história desta incrível e poderosa linguagem. De ferramenta de ensino</p><p>para base de alguns dos ambientes de maior destaque da atualidade, a linguagem Pascal tem lugar garantido na</p><p>história da Informática ..................................................................................................................................................... 5</p><p>REPORTAGEM</p><p>FREE PASCAL COMO AMBIENTE PROFISSIONAL</p><p>É possível usar o Free Pascal como uma ferramenta profissional? Confira nesta reportagem as possibilidades deste</p><p>versátil compilador de código aberto e veja como tornar o Free Pascal a ferramenta do seu dia a dia de trabalho .... 10</p><p>PROGRAMAÇÃO - JOGOS</p><p>SNAKE – O JOGO DA COBRA</p><p>Código comentado de um dos jogos eletrônicos mais difundidos pelo mundo ........................................................... 16</p><p>PROGRAMAÇÃO - JOGOS</p><p>PEDRA, PAPEL E TESOURA</p><p>Desafie o computador em um dos jogos de azar mais tradicionais do mundo numa versão criada de modo a antecipar</p><p>as jogadas de seu oponente humano ........................................................................................................................... 24</p><p>PROGRAMAÇÃO - APLICAÇÕES</p><p>REDIRECIONAMENTO E INTERCONEXÃO COM FREE PASCAL E LAZARUS</p><p>Aprenda a usar mecanismos de intercomunicações entre programas através de exemplos práticos e crie inter-</p><p>conexões entre programas independentes .................................................................................................................. 34</p><p>DICAS</p><p>Confira nossas dicas e veja se há algo que possa ajudar a complementar o seu código ........................................... 42</p><p>COLABORADORES</p><p>● Ericson Benjamim</p><p>● Geraldo Martins Fontes Jr.</p><p>Várias Marcas Registradas aparecem no decorrer desta revista. Mais do que simplesmente listar esses nomes e informar quem possui</p><p>seus direitos de exploração, ou ainda exibir os logotipos das mesmas, o editor declara estar utilizando tais nomes apenas para fins</p><p>editoriais e não lucrativos, em benefício exclusivo do dono da marca registrada, sem intenção de infringir as regras de sua utilização.</p><p>N.º 1</p><p>EDITORIAL 26 de junho de 2007</p><p>Caro Leitor,</p><p>É com imenso prazer que anuncio a você o nascimento da FANZINE.PAS, uma revista eletrônica que surge a</p><p>partir do esforço amador de colaboradores fanáticos por Pascal, a linguagem. Apesar de amador, o esforço é</p><p>suficientemente sério para trazer conteúdo prático e útil. Claro que não somos profissionais da editoração, logo,</p><p>portanto, perdoem nossas falhas, por favor. FANZINE.PAS é uma publicação sem muita pretensão, mas que tem</p><p>como objetivo informar e entreter o leitor. E nós, colaboradores, também acabamos por nos entreter e nos informar, a</p><p>medida que preparamos nossa fanzine.</p><p>FANZINE.PAS também conta com você, leitor, com suas críticas e, caso seja sua vontade, com sua</p><p>colaboração. De certo estamos precisando de colaboradores, pois somos poucos e pouco tempo dispomos. Sabe?</p><p>Aquela velha falta crônica de tempo. Tentaremos manter a periodicidade trimestral de nossa fanzine.</p><p>Vamos tentar ao máximo trazer uma compilação de artigos interessantes, sejam oriundos da Internet, livros,</p><p>revistas ou de nossa própria imaginação. Sugestões também são muito bem vindas.</p><p>Quanto ao assunto abordado pela fanzine nada poderia ser mais óbvio: linguagem Pascal. E tudo que tiver a</p><p>ver com esta linguagem, desde compiladores como Turbo Pascal, Free Pascal e outros, a ambientes como o Delphi,</p><p>Lazarus, Bloodshed Dev-Pascal etc.</p><p>Bem, esperamos que você, caro leitor, aprecie nossas matérias e ficamos a sua disposição para o que estiver a</p><p>nosso alcance.</p><p>Ericson Benjamim</p><p>FUNDAMENTOS 5</p><p>HISTÓRIA DA</p><p>LINGUAGEM</p><p>PASCAL</p><p>Conheça um pouco da</p><p>história de umas das</p><p>linguagens mais usada</p><p>em toda história da</p><p>Informática.</p><p>Por Ericson Benjamim</p><p>A origem de Pascal é bem diferente</p><p>da maioria das outras linguagens. Sua</p><p>proposta inicial era para ser apenas uma</p><p>ferramenta de ensino: moldar mentes ao</p><p>rigor matemático da programação</p><p>estruturada. E nisso, a linguagem é uma</p><p>ferramenta ímpar, bastando ver os diversos</p><p>cursos de informática espalhados por todo</p><p>mundo que adotaram Pascal nos primeiros</p><p>passos que seus alunos darão durante seu</p><p>aprendizado de programação. Realmente</p><p>muitos professores preferem ensinar</p><p>algoritmos e estruturas de dados usando</p><p>Pascal ao invés de linguagem</p><p>algorítmica, principalmente pela facilidade</p><p>em testar o código que os alunos</p><p>escreveram.</p><p>Outra coisa que torna ainda mais</p><p>peculiar a origem da linguagem é que ela</p><p>foi criada por apenas um homem, o suíço</p><p>Niklaus Wirth. O mais comum, na época,</p><p>seria de se esperar que um comitê de</p><p>especialistas definissem toda especificação</p><p>da linguagem. Enquanto professor do</p><p>Instituto Federal de Tecnologia em Zurique,</p><p>em 1970, Niklaus Wirth criou a linguagem e</p><p>deu a ela o nome do famoso matemático</p><p>Blaise Pascal, inventor de uma das</p><p>primeiras calculadoras mecânicas, dentre</p><p>outras coisas.</p><p>Pascal tem como ancestral a</p><p>linguagem Algol, da qual Niklaus Wirth se</p><p>envolveu durante sua especificação. Algol</p><p>é considerada a primeira linguagem de</p><p>programação estruturada da história. Aliás,</p><p>Algol é considerada ancestral comum de</p><p>todas as linguagens estruturadas que</p><p>surgiram nas décadas de 1970 e 1980.</p><p>Niklaus Wirth baseou toda a definição de</p><p>Pascal no Algol W (W de Wirth?) - uma</p><p>versão de Algol que ele mesmo sugeriu.</p><p>Tela do Turbo Pascal 1.0 para MSDOS (16bits).</p><p>O objetivo de Niklaus Wirth ao criar</p><p>Pascal, era de desenvolver uma linguagem</p><p>que estimulasse o estudante a elaborar a</p><p>estrutura do programa antes de começar a</p><p>codificá-lo. Ele introduziu uma série de</p><p>FUNDAMENTOS 6</p><p>recursos que permitisse a solução pro-</p><p>gramada conter a própria informação a ser</p><p>processada. Ou seja, para se escrever um</p><p>programa em Pascal é necessário planejar</p><p>como resolver o problema antes. A solução</p><p>escolhida é refinada sucessivamente,</p><p>cobrindo detalhes cada vez menores, até</p><p>se alcançar o nível de um procedimento</p><p>(unidade algorítmica), Só se trabalha no</p><p>programa principal depois que todos os</p><p>procedimentos necessários estiverem</p><p>programados.</p><p>Tela do Apple Pascal para Apple II (8bits).</p><p>A plataforma original de Pascal</p><p>foram os computadores de grande porte,</p><p>porém sua projeção significativa no mundo</p><p>se deve as versões que surgiram para</p><p>microcomputadores. Hoje, quando se fala</p><p>em Pascal o que vem logo na mente é</p><p>Turbo Pascal, a versão mais famosa,</p><p>desenvolvida pela Borland. Mas muitos</p><p>deixam de lembrar uma versão que foi</p><p>muito famosa, mesmo antes do Turbo</p><p>Pascal: UCSD Pascal. Esta deve seu nome</p><p>ao local onde foi desenvolvida, a</p><p>Universidade da Califórnia – San Diego. O</p><p>UCSD Pascal era um ambiente com-</p><p>pleto, com compilador Pascal, editor de</p><p>código, gerenciador de arquivos e sistema</p><p>operacional! A versão mais famosa foi</p><p>implementada nos microcomputadores de</p><p>8 bits Apple II.</p><p>Tela do Kyan Pascal para Apple//e e //c (8bits).</p><p>Pouco</p><p>then</p><p>Memo1.Lines.Add(NomeObjeto[Jogada] + ' vence ' +</p><p>NomeObjeto[Resposta] + '.')</p><p>else</p><p>Memo1.Lines.Add('Houve um empate nesta rodada.');</p><p>Memo1.Lines.Add('');</p><p>end;</p><p>function TForm1.PontuacaoNecessaria: Boolean;</p><p>{ Avalia condicoes para terminar o jogo }</p><p>begin</p><p>PontuacaoNecessaria := ((Pontos[Computador] >= 50) or</p><p>(Pontos[Humano] >= 50)) and</p><p>(ABS(Pontos[Computador] - Pontos[Humano]) > 1);</p><p>end;</p><p>procedure TForm1.RodaJogo;</p><p>{ Rotina principal }</p><p>begin</p><p>SemRodadas := SemRodadas + 1;</p><p>Comprimento := ComprimentoMaximo;</p><p>Decidido := false;</p><p>repeat</p><p>Procura(Comprimento);</p><p>Jogada := EscolheJogada;</p><p>Comprimento := Comprimento - 1;</p><p>until (Decidido) or (Comprimento = 0);</p><p>ExibeMinhaJogada;</p><p>Historico[Computador, SemRodadas] := Jogada;</p><p>Historico[Humano, SemRodadas] := Resposta;</p><p>AtualizaPontuacao;</p><p>ExibePontuacao;</p><p>end;</p><p>procedure TForm1.ImagemEscolha(ObjetoEscolhido: Objeto);</p><p>begin</p><p>if not FimDeJogo then</p><p>begin</p><p>Image2.Picture.LoadFromFile(</p><p>LowerCase(NomeObjeto[ObjetoEscolhido]) + '.xpm');</p><p>Memo1.Clear;</p><p>Memo1.Lines.Add('Você escolheu ' +</p><p>NomeObjeto[ObjetoEscolhido] + '.');</p><p>Memo1.Lines.Add('');</p><p>Resposta := ObjetoEscolhido;</p><p>RodaJogo;</p><p>end</p><p>else</p><p>begin</p><p>PROGRAMAÇÃO - JOGOS 31</p><p>Image1.Picture.Clear;</p><p>Image2.Picture.Clear;</p><p>Memo1.Clear;</p><p>Memo1.Lines.Add('O jogo chegou ao fim. Clique em Início para ' +</p><p>'jogar novamente.');</p><p>Memo1.Lines.Add('');</p><p>end;</p><p>if PontuacaoNecessaria then MensagemVitoria</p><p>end;</p><p>Agora acesse o evento OnCreate do Form1 (clique duplo na</p><p>área vazia do Form1) e insira o código a seguir:</p><p>procedure TForm1.FormCreate(Sender: TObject);</p><p>begin</p><p>{ Configura e formata os componentes do form }</p><p>Form1.Caption := 'Pedra, Papel e ' +</p><p>'Tesoura @ Lazarus';</p><p>Form1.Height := 358;</p><p>Form1.Width := 592;</p><p>{ Centraliza form }</p><p>Form1.Left := (Screen.Width div 2) - (Form1.Width div 2);</p><p>Form1.Top := (Screen.Height div 2) - (Form1.Height div 2);</p><p>Button1.Caption := 'Início';</p><p>Button1.Left := 212;</p><p>Button1.Top := 317;</p><p>Button2.Caption := 'Sair';</p><p>Button2.Left := 305;</p><p>Button2.Top := 317;</p><p>Memo1.Font.Name := 'Courier New';</p><p>Memo1.Font.Size := 10;</p><p>Memo1.ReadOnly := true;</p><p>Memo1.Left := 199;</p><p>Memo1.Top := 16;</p><p>Memo1.Height := 208;</p><p>Memo1.Width := 377;</p><p>Label1.Caption := 'Computador:';</p><p>Label1.Left := 16;</p><p>Label1.Top := 46;</p><p>Label2.Left := 23;</p><p>Label2.Top := 62;</p><p>Label3.Caption := 'Humano:';</p><p>Label3.Left := 24;</p><p>Label3.Top := 136;</p><p>Label4.Left := 23;</p><p>Label4.Top := 152;</p><p>Label5.Caption := 'Empate(s):';</p><p>Label5.Left := 26;</p><p>Label5.Top := 200;</p><p>Label6.Left := 112;</p><p>Label6.Top := 200;</p><p>Image1.AutoSize := true;</p><p>Image1.Left := 100;</p><p>Image1.Top := 32;</p><p>Image2.AutoSize := true;</p><p>Image2.Left := 100;</p><p>Image2.Top := 120;</p><p>Image3.Left := 141;</p><p>Image3.Top := 240;</p><p>Image4.Left := 253;</p><p>Image4.Top := 240;</p><p>Image5.Left := 365;</p><p>Image5.Top := 240;</p><p>Image3.AutoSize := true;</p><p>Image4.AutoSize := true;</p><p>Image5.AutoSize := true;</p><p>{ Carrega bitmaps }</p><p>Image3.Picture.LoadFromFile('pedra.xpm');</p><p>Image4.Picture.LoadFromFile('papel.xpm');</p><p>Image5.Picture.LoadFromFile('tesoura.xpm');</p><p>NomeObjeto[Pedra] := 'Pedra';</p><p>NomeObjeto[Papel] := 'Papel';</p><p>NomeObjeto[Tesoura] := 'Tesoura';</p><p>MessagemIntroducao;</p><p>end;</p><p>Insira o código para os eventos OnClick dos componentes</p><p>Image3, Image4, Image5, Button1 e Button2, respectivamente:</p><p>procedure TForm1.Image3Click(Sender: TObject);</p><p>begin</p><p>ImagemEscolha(Pedra);</p><p>end;</p><p>procedure TForm1.Image4Click(Sender: TObject);</p><p>begin</p><p>ImagemEscolha(Papel);</p><p>end;</p><p>procedure TForm1.Image5Click(Sender: TObject);</p><p>begin</p><p>ImagemEscolha(Tesoura);</p><p>end;</p><p>procedure TForm1.Button1Click(Sender: TObject);</p><p>begin</p><p>MessagemIntroducao;</p><p>end;</p><p>procedure TForm1.Button2Click(Sender: TObject);</p><p>begin</p><p>Form1.Close;</p><p>end;</p><p>PROGRAMAÇÃO - JOGOS 32</p><p>Pronto. Agora é só compilar e jogar a vontade. Os arquivos</p><p>bitmaps devem estar no mesmo diretório do executável. Se for</p><p>usar o Delphi, converta os arquivos XPM para BMP ou outro</p><p>formato que este ambiente aceite. Utilize um editor de imagens</p><p>como o GIMP, por exemplo.</p><p>Como podem ver o visual do programa está bem simples,</p><p>mas você pode incrementar o programa de modo a deixá-lo bem</p><p>melhor. Está dado o convite.</p><p>Eu acrescentei o código para incluir o ícone na aplicação,</p><p>como podem ver no início do código. Isto não é necessário no</p><p>caso do Delphi. Na realidade também não é no Lazarus, já que</p><p>não passa de pura ação cosmética.</p><p>Este artigo pode ser usado como exemplo para a conversão</p><p>de um programa em modo console ao modo gráfico amigável. A</p><p>transição neste caso foi bem tranqüila. Na maioria deve ser assim</p><p>também. Devemos tomar o cuidado de sair encaixando as rotinas</p><p>pelos eventos que acontecem em um ambiente gráfico.</p><p>Quanto ao código original não podemos deixar de dar os</p><p>devidos créditos a Bob Mackay, autor da primeira versão deste</p><p>programa, publicado em 1983 na revista londrina Practical</p><p>Computing. A nossa versão em Pascal puro está mais para uma</p><p>tradução das mensagens e pequenos ajustes do código criado</p><p>originalmente do que para uma adaptação. Já a versão para</p><p>Lazarus representa uma verdadeira adaptação de um código com</p><p>mais de duas décadas de criado.</p><p>ANÁLISE DAS ROTINAS</p><p>Vamos analisar o código do jogo para ver como o programa</p><p>funciona. O algoritmo inicia tentando encontrar no histórico de</p><p>jogadas um padrão similar às cinco últimas jogadas efetuadas pelo</p><p>oponente humano. Caso não encontre, o algoritmo começa a</p><p>procurar por seqüências mais curtas. O vetor bidimensional</p><p>Historico é usado para armazenar o histórico de jogadas.</p><p>PROGRAMAÇÃO - JOGOS 33</p><p>O computador começa avaliando</p><p>cinco jogadas por vez, no histórico, através</p><p>do procedimento Procura. Este procedi-</p><p>mento tenta encontrar uma combinação</p><p>comparando as seqüências históricas</p><p>através da função booleana Combina. Esta</p><p>função retorna verdadeiro quando achar o</p><p>comprimento correto no qual as combina-</p><p>ções coincidam com as das últimas</p><p>jogadas. Por fim o procedimento Procura</p><p>armazena o total de acordo com a jogada</p><p>escolhida.</p><p>Em seguida o computador escolhe</p><p>sua jogada (ou seu objeto) através da</p><p>função EscolheJogada. Procurando pela</p><p>maioridade de jogadas específicas do</p><p>oponente humano, esta função decide</p><p>através da verificação dos totais de cada</p><p>objeto. Um exemplo para esclarecer: se o</p><p>total de jogadas de papel for maior que o</p><p>total das outras jogadas do humano, o</p><p>computador escolherá tesoura. Se o total</p><p>maior for de jogadas de tesoura, então ele</p><p>decide por pedra. Conseqüentemente no</p><p>caso do total de jogadas de pedra for</p><p>maior, então a jogada será decidida por</p><p>papel.</p><p>Simples, não? E se a função não</p><p>encontrar um total de jogadas definido?</p><p>Paciência, a escolha terá de ser aleatória.</p><p>Neste caso, na função JogadaAleatória,</p><p>utilize um gerador de números aleatórios</p><p>que retorne um inteiro entre 3 e 255. Eu</p><p>utilizei a função RANDOM, neste caso,</p><p>mas pode haver variações, dependendo do</p><p>compilador usado. A maioria dos compila-</p><p>dores Pascal modernos possui esta função.</p><p>Todo esse processo é repetido a</p><p>cada jogada e o número de verificações</p><p>será decrementado em um na variável</p><p>Comprimento, caso, durante a rodada, não</p><p>seja encontrado um padrão. Você pode</p><p>alterar o comprimento máximo pela variável</p><p>ComprimentoMáximo, indicando em quanto</p><p>deve começar a a verificação do padrão de</p><p>jogadas humanas.</p><p>O procedimento AtualizaPontuacao</p><p>tem dupla função. Ele atualiza a pontuação</p><p>tanto do computador como do jogador</p><p>humano e exibe o ganhador</p><p>da rodada,</p><p>ou anuncia o empate, se for o caso.</p><p>E aqui chegamos ao fim de nosso</p><p>artigo. Ele pode ser melhor incrementado,</p><p>tanto visualmente quanto a nível de</p><p>algoritmo e aqui deixo o convite, para você,</p><p>caro leitor. █</p><p>Referências bibliográficas</p><p>1. Practical Computing, Volume 6, Issue 9, setembro/1983, End of File,</p><p>páginas 172 e 173;</p><p>2. http://pt.wikipedia.org/wiki/Pedra,_papel,_tesoura</p><p>http://pt.wikipedia.org/wiki/Pedra,_papel,_tesoura</p><p>PROGRAMAÇÃO - APLICAÇÕES 34</p><p>REDIRECIONAMENTO</p><p>E INTERCONEXÃO</p><p>COM FREE PASCAL</p><p>E LAZARUS</p><p>Aprenda a fazer</p><p>suas aplicações</p><p>comunicarem</p><p>entre si</p><p>Por Geraldo Martins Fontes Jr.</p><p>Todos nós que utilizamos a dupla</p><p>Free Pascal e Lazarus sabemos que cada</p><p>um desses programas é um desenvolvi-</p><p>mento independente. Tanto um quanto</p><p>outro têm suas equipes de</p><p>desenvolvimento distintas, embora os dois</p><p>trabalhem em conjunto. Sendo assim,</p><p>como esses programas – o compilador</p><p>Free Pascal e o ambiente de</p><p>desenvolvimento Lazarus – se comuni-</p><p>cam? Qual o mecanismo que permite que</p><p>essas maravilhosas ferramentas de</p><p>programação proporcionem a beleza do</p><p>conjunto que constituem? Podemos</p><p>também construir parcerias de software</p><p>como essa?</p><p>A resposta para esses ques-</p><p>tionamentos reside em recursos que</p><p>nasceram muito antes desses programas.</p><p>Recursos esses que estão presentes até</p><p>hoje, nas versões mais atuais dos sistemas</p><p>operacionais que dão suporte aos</p><p>programas em questão: redirecionamentos</p><p>e conexões (pipes).</p><p>Usaremos o Linux como sistema de</p><p>partida para as explanações de conceitos e</p><p>exemplos. Contudo, os conceitos apresen-</p><p>tados são perfeitamente válidos para</p><p>muitos outros sistemas, incluindo aqui o</p><p>Mac OS X, OS/2, DOS e Windows 95 e 98,</p><p>embora o exemplo prático apresentado no</p><p>final não seja adequado a esses sistemas,</p><p>por utilizar um utilitário exclusivo do Linux.</p><p>REDIRECIONANDO ENTRADAS E SAÍDAS</p><p>Para saber o que são redirecio-</p><p>namentos e conexões, precisamos enten-</p><p>der primeiramente os conceitos de entrada</p><p>padrão e saída padrão.</p><p>Toda vez que o computador neces-</p><p>sitar de dados para um processamento, ele</p><p>os obtém a partir de um dispositivo qual-</p><p>PROGRAMAÇÃO - APLICAÇÕES 35</p><p>quer de entrada. Da mesma forma, quando</p><p>for necessário externar uma informação, a</p><p>mesma será direcionada a um dispositivo</p><p>de saída. A entrada mais comum é o</p><p>teclado, enquanto a saída tradicional é a</p><p>tela do computador. Evidentemente que</p><p>estamos nos referindo a sistemas em modo</p><p>texto, sem a presença do mouse. Vejamos</p><p>um exemplo de uma entrada e uma saída</p><p>em Pascal:</p><p>(* Uma entrada a partir do teclado *)</p><p>Readln(variavel);</p><p>(* Uma saída para a tela do micro *)</p><p>Writeln('Você digitou:', variavel);</p><p>No início da micro-informática, esses</p><p>dispositivos de entrada e saída – teclado e</p><p>tela – eram tão comuns (e na verdade</p><p>ainda o são), que os sistemas operacionais</p><p>os viam de maneira especial. Receberam</p><p>então os nomes de entrada padrão e saída</p><p>padrão respectivamente.</p><p>Até aqui, segundo acreditamos, não</p><p>há nenhuma novidade. O que talvez nem</p><p>todo mundo sabe é que, tanto a entrada</p><p>padrão, quanto a saída, podem ser</p><p>redirecionados, ou seja, ligados momen-</p><p>taneamente a outros pontos de entrada ou</p><p>saída.</p><p>Assim, poderemos associar a entra-</p><p>da padrão a um arquivo texto, de onde</p><p>originar-se-iam os dados para o processa-</p><p>mento de um programa qualquer. Da</p><p>mesma forma, as informações que o</p><p>programa geraria, seriam dirigidas à</p><p>impressora ou a um arquivo em disco, ao</p><p>invés de serem mostradas na tela do</p><p>computador. Vejamos alguns exemplos.</p><p>No Linux, o comando ls mostra na</p><p>tela os arquivos presentes num diretório.</p><p>Se desejarmos gravar uma lista contendo</p><p>os arquivos de um diretório, poderemos</p><p>redirecionar a saída do ls para o arquivo</p><p>lista_de_arquivos.txt, da seguinte forma:</p><p>ls > lista_de_arquivos.txt</p><p>Nesse exemplo, o sinal “>” indica</p><p>que a saída padrão vai ser redirecionada</p><p>para o que vier após o referido sinal. Em</p><p>nosso caso, para o arquivo citado.</p><p>Para redirecionar a saída do ls para</p><p>a impressora, bastaria substituir o nome de</p><p>arquivo do exemplo acima pela especifi-</p><p>cação do dispositivo correspondente à</p><p>impressora:</p><p>ls > /dev/lp0</p><p>Assim como redirecionamos a saída</p><p>padrão nos exemplos acima, poderíamos</p><p>redirecionar a entrada do comando more,</p><p>como abaixo:</p><p>more < lista_de_arquivos.txt</p><p>Veja que a única diferença no</p><p>redirecionamento de entrada é o sinal</p><p>utilizado. Você pode entender esse sinal</p><p>como uma seta que indica a direção para</p><p>onde flui a informação.</p><p>Além da entrada e da saída padrão,</p><p>existe um terceiro dispositivo virtual,</p><p>chamado erro padrão, que recebe as</p><p>mensagens de erro do programa. Esse</p><p>dispositivo está normalmente associado à</p><p>tela do computador e também pode ser</p><p>redirecionado. O sinal de redirecionamento</p><p>para esse caso é o “2>”.</p><p>cd /diretorio_inexistente 2 > erros.txt</p><p>Importante a ser observado é que,</p><p>para realizar o redirecionamento de um</p><p>comando ou programa qualquer, é</p><p>necessário que o mesmo o permita. Assim,</p><p>o comando ls, somente possui saída. Ele</p><p>não espera nenhuma digitação ou o que</p><p>quer que seja pela entrada padrão e assim,</p><p>não é possível redirecionar sua entrada. O</p><p>comando more, por outro lado, aceita</p><p>entrada e saída e ambos podem ser</p><p>direcionados, embora não faça muito</p><p>sentido redirecionar a saída desse</p><p>comando.</p><p>CONEXÕES</p><p>Embora o termo em inglês – pipe –</p><p>possa ser traduzido como cano, não</p><p>necessitaremos aqui de nenhum bombeiro</p><p>hidráulico para estudarmos a questão.</p><p>Preferiremos inclusive o termo conexão ou</p><p>mesmo interconexão, que traduz melhor a</p><p>idéia em questão.</p><p>PROGRAMAÇÃO - APLICAÇÕES 36</p><p>Após estudar o redirecionamento de</p><p>entrada e saída, fica a questão: Seria</p><p>possível direcionar a saída de um</p><p>programa para a entrada de outro? Se você</p><p>teve essa dúvida, está no caminho certo.</p><p>E a resposta não poderia ser outra.</p><p>Não só é possível, como também isso é</p><p>muitíssimo útil. Vejamos alguns exemplos</p><p>de interconexões, para que possamos</p><p>entender do que estamos falando:</p><p>ls | sort</p><p>Veja que aqui utilizamos dois</p><p>comandos. O ls, já vimos para que serve; o</p><p>sort, por sua vez, classifica tudo que</p><p>receber em sua entrada em ordem</p><p>alfabética. O símbolo “|” é o sinal de</p><p>interconexão e faz uma ponte entre o ls e o</p><p>sort. O resultado dessa brincadeira é que a</p><p>saída do ls vai ser colocada em ordem</p><p>alfabética e só então será enviada à tela.</p><p>Se a saída final for muito grande e</p><p>não couber toda na tela, é possível</p><p>introduzir pausas pelo comando more, da</p><p>seguinte maneira:</p><p>ls | sort | more</p><p>Não há limite para as conexões que</p><p>você quiser fazer numa mesma linha. E</p><p>você também pode misturar conexões e</p><p>redirecionamentos. Assim, para criar nossa</p><p>lista de arquivos devidamente ordenada,</p><p>faríamos o seguinte:</p><p>ls | sort > lista_de_arquivos.txt</p><p>Se você quiser se aprofundar nesse</p><p>assunto, sugerimos que recorra a algum</p><p>livro sobre o assunto, lembrando sempre</p><p>que os conceitos apresentados são</p><p>também válidos para outros sistemas.</p><p>Somente os comandos é que podem ser</p><p>outros. Mas até mesmo os sinais de</p><p>redirecionamento e interconexão são os</p><p>mesmos.</p><p>O que veremos a partir de agora é</p><p>como tirar proveito de tudo o que vimos</p><p>nos programas que iremos escrever no</p><p>Lazarus e no Free Pascal.</p><p>INTERCONEXÕES NO FREE PASCAL</p><p>Até aqui vimos como utilizar os</p><p>recursos de redirecionamento e</p><p>interconexão utilizando tão somente</p><p>comandos do sistema operacional. Mas o</p><p>nosso objetivo final não é esse, mas</p><p>aproveitar esses recursos para um</p><p>programa que escreveremos.</p><p>Se você é usuário de Linux, já está</p><p>habituado</p><p>a ver programas gráficos que se</p><p>utilizam de outros em modo texto para</p><p>fazer o serviço pesado. É o caso, por</p><p>exemplo, do “File Roller” do ambiente</p><p>Gnome. Esse programa é um gerenciador</p><p>de arquivos compactados. É similar ao</p><p>Winzip, velho conhecido dos usuários de</p><p>Windows. Mas ao contrário do Winzip, o</p><p>File Roller é apenas uma interface gráfica</p><p>que trabalha em conjunto com os</p><p>programas tar, zip e unzip. Esses últimos</p><p>fazem o trabalho real de compactação e</p><p>descompactação de arquivos. Costuma-se</p><p>dizer que o File Roller é um front end para</p><p>aqueles utilitários. Assim como ele, vários</p><p>programas utilizam esse tipo de parceria.</p><p>Mas o que tudo isso tem a ver com o</p><p>assunto que estamos vendo? Tudo!</p><p>Acontece que, uma das formas de fazer</p><p>essa parceria entre o programa gráfico e</p><p>aquele que roda em modo texto é a nossa</p><p>conhecida interconexão. Criaremos agora</p><p>uma parceria entre um utilitário em modo</p><p>texto do Linux e um programa gráfico, que</p><p>escreveremos no Lazarus.</p><p>Mas antes, vamos conhecer a</p><p>sintaxe de alguns procedimentos e funções</p><p>da unit oldLinux.</p><p>Popen</p><p>Esse procedimento cria uma</p><p>conexão entre um comando especificado e</p><p>o programa que o chamou, possibilitando a</p><p>passagem de dados ao comando e/ou a</p><p>obtenção, como resposta, da saída do</p><p>comando. A sintaxe da procedure é a</p><p>seguinte:</p><p>procedure Popen(var F: Text; const Prog: String; rw: Char);</p><p>Aqui, F é uma variável de arquivo</p><p>texto, que usaremos para capturar as saída</p><p>do comando Prog. Deveremos especificar o</p><p>PROGRAMAÇÃO - APLICAÇÕES 37</p><p>modo de abertura da conexão, passando a</p><p>variável rw com os valores “r” ou “w”,</p><p>conforme queiramos escrita ou leitura. O</p><p>exemplo a seguir ilustra a utilização do</p><p>Popen:</p><p>var f: file;</p><p>popen(f, 'ls -laf', 'f');</p><p>Pclose</p><p>Fecha uma conexão aberta com</p><p>Popen. Aqui não há nenhum mistério. Uma</p><p>conexão funciona como um arquivo. Assim,</p><p>a mesma deve ser fechada quando</p><p>terminarmos de utilizá-la, da mesma forma</p><p>que faríamos com um arquivo. A sintaxe é</p><p>a seguinte:</p><p>function PClose(var F: text): LongInt</p><p>rpm [opções] pacote.rpm</p><p>Esse comando tem a função de</p><p>verificar e instalar pacotes RPM. Esses</p><p>pacotes são uma das formas de instalar</p><p>programas no Linux. O comando rpm não</p><p>só faz a instalação desses pacotes, como</p><p>também mostra o conteúdo dos mesmos e</p><p>informações sobre o pacote.</p><p>Para obter a descrição de um pacote</p><p>RPM, precisaremos especificar na linha de</p><p>comando do rpm as opções “q”, “i” e “p” e</p><p>para obter a lista de arquivos que</p><p>compõem o pacote, as opções são “q”, “l”,</p><p>e “p”.</p><p>Agora sim! Já dispomos de toda</p><p>informação que precisaremos para criar</p><p>nosso programa. Só falta mesmo abrir o</p><p>Lazarus e por mãos à obra. Se você ainda</p><p>não adivinhou, escreveremos uma interface</p><p>gráfica para o rpm, que permitirá obter da-</p><p>dos sobre um determinado pacote RPM.</p><p>Não faremos a instalação do pacote, para</p><p>não nos estendermos demais. Se você</p><p>desejar, poderá modificar o programa para</p><p>que faça também a instalação de pacotes,</p><p>apenas acrescentando mais um botão e as</p><p>linhas de código que você poderá</p><p>facilmente escrever.</p><p>CRIANDO O FORMULÁRIO</p><p>Para começar, vamos criar uma</p><p>nova aplicação. Basta selecionar a opção</p><p>“Novo Projeto” do menu “Projeto” e então,</p><p>escolher “Aplicação” e clicar sobre o botão</p><p>“Criar”. Se você já é usuário do Lazarus,</p><p>sabe exatamente do que estou falando.</p><p>Uma nova aplicação é então aberta</p><p>e surge um formulário em branco.</p><p>Redimensione esse formulário para</p><p>aproximadamente 270 x 90 (width x height).</p><p>F, como já se esperava, é a mesma</p><p>variável utilizada quando abrimos o “pipe”.</p><p>A função retorna um longint, que será zero</p><p>no caso de sucesso na utilização da</p><p>conexão e outro valor no caso de algo sair</p><p>errado.</p><p>Sugerimos consultar o “Run-Time</p><p>Library Reference Guide” do Free Pascal</p><p>para maiores detalhes sobre esse</p><p>procedimento e essa função. Para nós</p><p>nesse momento, o que temos é suficiente.</p><p>Aproveitemos também para ver a</p><p>sintaxe do comando rpm do Linux, que</p><p>utilizaremos em nossa empreitada:</p><p>Fig. 1: O formulário</p><p>PROGRAMAÇÃO - APLICAÇÕES 38</p><p>Guiando-se pela figura 1, posicione sobre o formulário os</p><p>seguintes componentes:</p><p>• Label, com a propriedade Caption tendo como valor a</p><p>expressão “Arquivo:”;</p><p>• Editbox, cujo nome deverá ser edRmFile, sendo colocado à</p><p>direita do label “Arquivo”. A propriedade Text desse Editbox</p><p>deverá estar vazia;</p><p>• Memo, logo abaixo e ocupando a maior parte do formulário.</p><p>Deverá ter sua propriedade Name mudada para</p><p>“mmConteudo” e seu conteúdo também deverá ser vazio;</p><p>• Um botão do tipo TbitBtn (aba Additional), posicionado logo</p><p>à direita do Editbox, que deverá receber o nome btAbrir.</p><p>Adicione um “glyph” a esse botão, modificando essa</p><p>propriedade. Utilize um arquivo tipo XPM contendo uma</p><p>seta apontando para baixo ou qualquer outra figura que lhe</p><p>agrade. Esse botão servirá para abrir o diálogo de seleção</p><p>de pacote RPM.</p><p>• Dois botões TbitBtn, um pouco maiores que o anterior, que</p><p>deverão ser nomeados btInfo e btConteudo</p><p>respectivamente. Escolha também figuras sugestivas das</p><p>funções que desempenharão. Se preferir, poderá usar</p><p>botões Tbutton, ajustando sua propriedade Caption para</p><p>“Informações” e “Conteúdo”. Qualquer que seja o tipo</p><p>escolhido, o desempenho será o mesmo.</p><p>• Um diálogo TopenDialog em qualquer posição do</p><p>formulário. Ajuste a propriedade Name para “dlgAbrir”,</p><p>Default ext para “.rpm”, File name para “*.rpm”, e Filter para</p><p>“Pacote RPM|*.rpm”.</p><p>Agora é só acrescentar o código.</p><p>Clique no botão btAbrir e selecione a aba Events no Object</p><p>Inspector. Selecione o evento “On click” e acrescente o código</p><p>listado a seguir:</p><p>procedure TfrmGrpm.btAbrirClick(Sender : TObject);</p><p>begin</p><p>if dlgAbrir.execute then</p><p>begin</p><p>mmConteudo.clear;</p><p>edRpmFile.text := dlgAbrir.fileName;</p><p>btInfoClick(Sender);</p><p>end;</p><p>end; (* btAbrirClick *)</p><p>Fig. 2: Ajustando o tratador do evento</p><p>Esse botão, como se pode constatar pela análise do código</p><p>mostrado, apenas abre o diálogo padrão do sistema e permite que</p><p>se faça a escolha de um arquivo. Uma vez que alteramos algumas</p><p>propriedades desse diálogo ao colocá-lo no formulário, o mesmo</p><p>já está devidamente filtrado para mostrar apenas arquivos do tipo</p><p>RPM, como era de se esperar.</p><p>Depois é a vez do botão btInfo. Selecione-o e insira o</p><p>código correspondente:</p><p>PROGRAMAÇÃO - APLICAÇÕES 39</p><p>procedure TfrmGrpm.btInfoClick(Sender : TObject);</p><p>var linhaStr,</p><p>comando: string;</p><p>begin</p><p>mmConteudo.lines.clear;</p><p>comando := 'rpm -qip ' + edRpmFile.text + ' 2>&1';</p><p>popen(pipeRpm,comando,'r');</p><p>while not eof(pipeRpm) do</p><p>begin</p><p>readln(pipeRpm,linhaStr);</p><p>mmConteudo.lines.add(linhaStr);</p><p>end; (* while *)</p><p>pclose(pipeRpm);</p><p>end;</p><p>É aqui que reside toda a mágica do programa. Veja a linha</p><p>“popen(pipeRpm, comando, 'r')”. É essa linha que cria a</p><p>conexão entre o utilitário rpm e o nosso programa. O parâmetro</p><p>comando do popen recebeu, na linha anterior, exatamente o que</p><p>deveríamos digitar se o rpm fosse chamado diretamente da linha</p><p>de comando. Nem mesmo foi necessário utilizar o sinal de</p><p>conexão - “|” - já que o popen já faz isso por nós.</p><p>Contudo, como precisamos fazer também um</p><p>redirecionamento dos erros, foi necessário acrescentar o o trecho</p><p>“2>&1”. A razão disso é que precisamos fazer com que possíveis</p><p>mensagens de erro geradas pelo rpm possam ser também</p><p>capturadas pela nossa conexão.</p><p>Após a abertura da conexão, temos que ler a mesma, o que</p><p>é feito em um loop while. Dentro desse loop, lemos pipeRpm e</p><p>transferimos o valor lido para linhaStr:</p><p>readln(pipeRpm, linhaStr)</p><p>Depois é só acrescentar essa variável a mmConteudo:</p><p>mmConteudo.lines.add(linhaStr)</p><p>O loop de leitura da conexão é semelhante àquele</p><p>utilizado</p><p>para ler um arquivo texto. O pipe é lido enquanto não receber um</p><p>marcador de final de arquivo - “not eof(pipeRpm)”.</p><p>Para finalizar, a conexão é fechada com a função pclose,</p><p>sendo que nem mesmo analisamos o valor retornado pela mesma.</p><p>Seguindo os mesmos passos que adotamos até aqui,</p><p>acrescente o código do botão btConteúdo:</p><p>procedure TfrmGrpm.btConteudoClick(Sender : TObject);</p><p>var linhaStr,</p><p>comando : string;</p><p>begin</p><p>mmConteudo.lines.clear;</p><p>comando:= 'rpm -qlp ' + edRpmFile.text + ' 2>&1';</p><p>popen(pipeRpm,comando,'r');</p><p>while not eof(pipeRpm) do</p><p>begin</p><p>readln(pipeRpm,linhaStr);</p><p>mmConteudo.lines.add(linhaStr);</p><p>end; (* while *)</p><p>pclose(pipeRpm);</p><p>end; (* btConteudoClick *)</p><p>Veja que a única diferença entre essa procedure e a</p><p>anterior é a variável comando, que recebeu agora opções</p><p>diferentes para o utilitário rpm -”-qlp”.</p><p>O restante do código é para tratar do visual, inicialização e</p><p>coisas assim. Sinta-se livre para modificá-lo se desejar.</p><p>Finda a digitação, basta compilar, acionando a opção Build all do</p><p>menu Execute do Lazarus. E se nenhum erro foi encontrado, rode</p><p>o programa. Selecione um pacote RPM qualquer, clique nos</p><p>botões btInfo e btConteudo e veja o resultado.</p><p>CONCLUSÃO</p><p>O recurso da interconexão é de utilidade inquestionável no</p><p>ambiente Linux, bem como em vários outros sistemas. Dispor</p><p>desse recurso em nossos programas em Pascal pode ser o que</p><p>PROGRAMAÇÃO - APLICAÇÕES 40</p><p>precisamos para dar vida nova a programas da linha de comando,</p><p>que nem sempre estão ao alcance do usuário comum.</p><p>Fig. 3: O programa mostrando o conteúdo de um pacote RPM</p><p>As funções e procedimentos vistos aqui não são as únicas</p><p>que o Free Pascal oferece e o que vimos não é nem a ponta do</p><p>iceberg. O leitor interessado deverá procurar a documentação do</p><p>compilador para ver mais detalhes sobre Popen, Pclose e demais</p><p>procedimentos e funções a esse respeito. Muito ainda há para ser</p><p>estudado, compreendido e posto em prática. O que pretendíamos</p><p>com esse artigo era dar o pontapé inicial, além de compartilhar o</p><p>conhecimento que adquirimos ao longo dos anos.</p><p>Não incluímos em nosso programa-exemplo recursos para</p><p>instalar pacotes RPM. Nossa intenção era apenas mostrar os</p><p>recursos sem nos alongarmos demais. Mas com o que aqui</p><p>aprendemos, ficou fácil introduzir mais esse recurso ao programa,</p><p>bastando apenas passar as opções necessárias ao utilitário rpm.</p><p>Essa tarefa deixamos para o leitor como dever de casa.</p><p>LISTAGEM COMPLETA</p><p>unit rpmviewer;</p><p>{$mode objfpc}{$H+}</p><p>interface</p><p>uses</p><p>Classes, SysUtils, LResources, Forms, Controls, Graphics,</p><p>Dialogs, StdCtrls, Buttons, oldlinux;</p><p>type</p><p>{ TfrmGrpm }</p><p>TfrmGrpm = class(TForm)</p><p>btAbrir : TbitBtn;</p><p>btInfo : TBitBtn;</p><p>PROGRAMAÇÃO - APLICAÇÕES 41</p><p>btConteudo : TBitBtn;</p><p>edRpmFile : TEdit;</p><p>lbArquivo : TLabel;</p><p>mmConteudo : TMemo;</p><p>dlgAbrir : TOpenDialog;</p><p>procedure btAbrirClick(Sender : TObject);</p><p>procedure FormCreate(Sender : TObject);</p><p>procedure FormResize(Sender : TObject);</p><p>procedure btConteudoClick(Sender : TObject);</p><p>procedure btInfoClick(Sender : TObject);</p><p>procedure edRpmFileKeyPress(Sender : TObject; var Key : char);</p><p>private</p><p>{ private declarations }</p><p>public</p><p>{ public declarations }</p><p>end;</p><p>var</p><p>frmGrpm : TfrmGrpm;</p><p>implementation</p><p>const Enter = #13; (* A tecla ENTER *)</p><p>{ TfrmGrpm }</p><p>var pipeRpm : text;</p><p>procedure TfrmGrpm.btAbrirClick(Sender : TObject);</p><p>begin</p><p>if dlgAbrir.execute then</p><p>begin</p><p>mmConteudo.clear;</p><p>edRpmFile.text:= dlgAbrir.fileName;</p><p>btInfoClick(Sender);</p><p>end;</p><p>end;</p><p>procedure TfrmGrpm.btInfoClick(Sender : TObject);</p><p>var linhaStr,</p><p>comando : string;</p><p>begin</p><p>mmConteudo.lines.clear;</p><p>comando:= 'rpm -qip ' + edRpmFile.text + ' 2>&1';</p><p>popen(pipeRpm,comando,'r');</p><p>while not eof(pipeRpm) do</p><p>begin</p><p>readln(pipeRpm,linhaStr);</p><p>mmConteudo.lines.add(linhaStr);</p><p>end; {(* while *)}</p><p>pclose(pipeRpm);</p><p>end;</p><p>procedure TfrmGrpm.edRpmFileKeyPress(Sender:TObject;var Key : char);</p><p>begin</p><p>if key = Enter then</p><p>btInfoClick(sender)</p><p>end;</p><p>procedure TfrmGrpm.FormCreate(Sender: TObject);</p><p>begin</p><p>edRpmFile.text:= '';</p><p>if paramCount > 0 then</p><p>begin</p><p>edRpmFile.text:= paramStr(1);</p><p>btInfoClick(sender);</p><p>end; (* if *)</p><p>end; (* FormCreate *)</p><p>procedure TfrmGrpm.FormResize(Sender : TObject);</p><p>begin</p><p>btConteudo.left:= frmGrpm.Width - 50;</p><p>btInfo.left:= btConteudo.left - 55;</p><p>end; (* btInfoClick *)</p><p>procedure TfrmGrpm.btConteudoClick(Sender : TObject);</p><p>var linhaStr,</p><p>comando : string;</p><p>begin</p><p>mmConteudo.lines.clear;</p><p>comando:= 'rpm -qlp ' + edRpmFile.text + ' 2>&1';</p><p>popen(pipeRpm,comando,'r');</p><p>while not eof(pipeRpm) do</p><p>begin</p><p>readln(pipeRpm,linhaStr);</p><p>mmConteudo.lines.add(linhaStr);</p><p>end; {(* while *)}</p><p>pclose(pipeRpm);</p><p>end; {(* btConteudoClick *)}</p><p>initialization</p><p>{$I rpmviewer.lrs}</p><p>end. █</p><p>Geraldo Martins Fontes Jr. é técnico eletrônico formado pela CEFET-MG e</p><p>programa nas linguagens C, Pascal e Assembly Z80/8086. Atualmente está</p><p>envolvido com a dupla Free Pascal e Lazarus.</p><p>DICAS 42</p><p>DICAS Aproveite nossas dicas.</p><p>Confira as sugestões de</p><p>nossos colaboradores</p><p>DIA DA SEMANA</p><p>É muito fácil conseguir o dia da</p><p>semana no Free Pascal. A função</p><p>DayOfWeek retorna o número do dia,</p><p>mas associando esta a um pequeno</p><p>vetor podemos retornar o nome do dia,</p><p>como podem ver no exemplo a seguir.</p><p>Não se esqueça de incluir a unidade</p><p>SysUtils na cláusula Uses de seu</p><p>programa.</p><p>program DiaDaSemana;</p><p>uses SysUtils;</p><p>const</p><p>Semana:</p><p>array[1..7] of string =</p><p>('Domingo', 'Segunda', 'Terça', 'Quarta',</p><p>'Quinta', 'Sexta', 'Sabado');</p><p>begin</p><p>writeln('Hoje eh: ', Semana[DayOfWeek(Now)]);</p><p>end.</p><p>ACENTUAÇÃO NO CONSOLE</p><p>Quem usa o Free Pascal em modo</p><p>console no Windows já deve ter percebido</p><p>que textos corretamente acentuados num</p><p>editor como o Bloodshed Dev-Pascal,</p><p>exibem caracteres estranhos quando o</p><p>programa está em execução. Isto se deve</p><p>ao fato do Free Pascal usar o código ASCII</p><p>para suas strings, enquanto que o</p><p>Windows utiliza o código ANSI/UTF-8. Se</p><p>você usa o Delphi ou Lazarus (em modo</p><p>GUI) está livre deste problema. Para</p><p>corrigir isto pode usar uma função como</p><p>esta:</p><p>program Teste_Ajuste_Acento_Console;</p><p>function AcentuaConsole(StrMsg: String): String;</p><p>const StrAcentWin = 'ÇüéâäàåçêëèïîìÄÅÉæÆôöò' +</p><p>'ûùÿÖÜ£áíóúñѪº½¼ÁÂÀãÃð' +</p><p>'ÊËÈÍÎÏÌÓÔÒõÕÚÛÙ';</p><p>const StrAcentCon = Chr(128) + Chr(129) +</p><p>Chr(130) + Chr(131) +</p><p>Chr(132) + Chr(133) +</p><p>Chr(134) + Chr(135) +</p><p>Chr(136) + Chr(137) +</p><p>Chr(138) + Chr(139) +</p><p>Chr(140) + Chr(141) +</p><p>Chr(142) + Chr(143) +</p><p>Chr(144) + Chr(145) +</p><p>Chr(146) + Chr(147) +</p><p>Chr(148) + Chr(149) +</p><p>Chr(150) + Chr(151) +</p><p>Chr(152) + Chr(153) +</p><p>Chr(154) + Chr(156) +</p><p>Chr(160) + Chr(161) +</p><p>Chr(162) + Chr(163) +</p><p>Chr(164) + Chr(165) +</p><p>Chr(166) + Chr(167) +</p><p>Chr(171) + Chr(172) +</p><p>Chr(181) + Chr(182) +</p><p>Chr(183) + Chr(198) +</p><p>Chr(199) + Chr(208) +</p><p>Chr(210) + Chr(211) +</p><p>Chr(212) + Chr(214) +</p><p>Chr(215) + Chr(216) +</p><p>Chr(222) + Chr(224) +</p><p>Chr(226) + Chr(227) +</p><p>Chr(228) + Chr(229) +</p><p>Chr(233) + Chr(234) +</p><p>Chr(235);</p><p>var WdIndex: Word;</p><p>begin</p><p>for WdIndex := 1 to Length(StrAcentWin) do</p><p>while</p><p>Pos(StrAcentWin[WdIndex], StrMsg) > 0 do</p><p>StrMsg[Pos(StrAcentWin[WdIndex],StrMsg)]:=</p><p>StrAcentCon[WdIndex];</p><p>AcentuaConsole := StrMsg;</p><p>end;</p><p>begin</p><p>writeln('AÇÚCAR açúcar ELÉTRICA elétrica ' +</p><p>'ÁGUA água SAÚDE saúde');</p><p>writeln(AcentuaConsole('AÇÚCAR açúcar ' +</p><p>'ELÉTRICA elétrica ' +</p><p>'ÁGUA água ' +</p><p>'SAÚDE saúde'));</p><p>end.</p><p>A função AcentuaConsole ajusta a</p><p>grande maioria dos caracteres especiais da</p><p>língua portuguesa. Por exemplo, se for</p><p>encontrado o caracter “é” (terceira posição</p><p>na constante StrAcentWin) na string a ser</p><p>ajustada, este será substituído pelo</p><p>caracter de código ASCII 130 (terceira po-</p><p>DICAS 43</p><p>sição na constante StrAcentCon). Caso</p><p>falte algum caracter, descubra o código</p><p>deste e inclua-o como os que já estão nas</p><p>constantes.</p><p>MESSAGEBOX EM PORTUGUÊS</p><p>Quem usa o MessageBox no</p><p>Lazarus deve ter percebido que os botões</p><p>deste apresentam mensagens em inglês.</p><p>Para corrigir isto é só editar o arquivo</p><p><lazarusdir>/lcl/lclstrconsts.pas e</p><p>trocar as mensagens de inglês para</p><p>português e depois recompilar o Lazarus.</p><p>Vale para Linux e Windows.</p><p>TAB POR ENTER NO LAZARUS</p><p>É muito comum encontrar esta dica</p><p>para o Delphi. Mas e no Lazarus? Como</p><p>fazer a tecla ENTER funcionar como TAB?</p><p>Fácil, insira o código abaixo no evento</p><p>OnKeyDown de seus componentes:</p><p>procedure TForm1.Edit1KeyDown(Sender: Tobject;</p><p>var Key: Word; Shift:TShiftState);</p><p>begin</p><p>if Key = 13 then</p><p>begin</p><p>if ssShift in Shift then</p><p>SelectNext(Sender as TWinControl, false,</p><p>true)</p><p>else</p><p>SelectNext(Sender as TWinControl, true,</p><p>true);</p><p>Key := 0;</p><p>end;</p><p>end;</p><p>Funciona no Linux e no Windows,</p><p>incluindo a combinação SHIFT + ENTER,</p><p>que retorna o foco para o componente</p><p>anterior (como SHIFT + TAB).</p><p>GRADIENTE EM FORM NO LAZARUS</p><p>Com esta dica você vai conseguir</p><p>deixar o seu Form com aquele efeito de</p><p>gradiente de cor, ou seja, a cor vai</p><p>mudando suavemente para outra</p><p>tonalidade.</p><p>procedure TForm1.FormPaint(Sender: Tobject);</p><p>var</p><p>WordAlt,</p><p>WordCol: Word;</p><p>begin</p><p>WordAlt := (ClientHeight + 255) div 256;</p><p>for WordCol := 0 to 255 do</p><p>with Canvas do</p><p>begin</p><p>Brush.Color := RGB(WordCol, 0, 0);</p><p>FillRect(0, WordCol * WordAlt,</p><p>ClientWidth, (WordCol + 1) * WordAlt);</p><p>end;</p><p>end;</p><p>Esta dica funciona apenas no</p><p>Lazarus para Windows e para isso é</p><p>necessário incluir a unidade Windows, na</p><p>cláusula Uses de seu Form.</p><p>TOCAR WAV NO LAZARUS/DELPHI</p><p>Se você usa o Delphi ou Lazarus no</p><p>Windows, pode facilmente tocar arquivos</p><p>de som do tipo WAV.</p><p>procedure TForm1.Button1Click(Sender: TObject);</p><p>var StrWave: String;</p><p>begin</p><p>StrWave := 'C:\MinhaPasta\dingdong.wav');</p><p>PlaySound(PChar(StrWave), 0, SND_SYNC);</p><p>end;</p><p>Para rodar você deve antes incluir a</p><p>unidade MMSystem na cláusula Uses de</p><p>seu Form. █</p><p>Todas as dicas e programas divulgados aqui</p><p>podem ser baixados em:</p><p>http://www.forumpascal.clic3.net/</p><p>Achou algo interessante na Internet ou</p><p>encontrou uma solução rápida para um problema?</p><p>Divulgue aqui na nossa seção de dicas. Envie um</p><p>email para ericsonbenjamim@yahoo.com.br. Críticas e</p><p>sugestões também são muito bem vindas.</p><p>mailto:ericsonbenjamim@yahoo.com.br?subject=Dicas para FANZINE.PAS</p><p>http://www.forumpascal.clic3.net/</p><p>tempo depois do UCSD</p><p>Pascal ser lançado, seria a vez do Turbo</p><p>Pascal chegar ao mercado. Criada por</p><p>Anders Hejlsberg, quando começou sua</p><p>carreira na Borland. Baseado em seu</p><p>trabalho anterior (Blue Label Pascal –</p><p>Nascom-2), Turbo Pascal foi implementado</p><p>em duas plataformas, IBM-PC (Intel</p><p>8086/8088) e CP/M 80 (Intel 8080 ou Z80).</p><p>A versão da Borland consolidou a</p><p>linguagem Pascal como ferramenta profis-</p><p>sional de programação.</p><p>A primeira versão de Pascal foi</p><p>criada para os computadores CDC 6000.</p><p>Também em 1970 Donald B. Gillies,</p><p>seguindo as especificações de Niklaus</p><p>Wirth, implementou um compilador Pascal</p><p>para mini-computadores PDP-11. Diversas</p><p>outras versões surgiram, mas isso é palco</p><p>para outro artigo futuro.</p><p>Tela do Turbo Pascal 5.5 para IBM/PC (16bits).</p><p>Esta é a primeira versão da Borland a dar suporte a orientação a objetos.</p><p>O Turbo Pascal, devido ao seu</p><p>baixo custo e conseqüentemente sua am-</p><p>pla difusão, influenciou de maneira</p><p>significativa toda a comunidade Pascal.</p><p>Tudo que acontecia no Turbo Pascal teria</p><p>reflexo nos diversos pacotes baseados em</p><p>Pascal que estavam por surgir nos anos</p><p>seguintes. A medida que o Turbo Pascal</p><p>evoluía diversas características eram im-</p><p>plementadas no ambiente, dentre as quais</p><p>podemos destacar suporte a programação</p><p>orientada a objetos, disponível desde a</p><p>versão 5.5. Para implementar POO no</p><p>Turbo Pascal, a Borland baseou-se na es-</p><p>FUNDAMENTOS 7</p><p>pecificação do Object Pascal da Apple</p><p>Computer.</p><p>Antes do Delphi, a Borland lançou o</p><p>Turbo Pascal for Windows (3.1x), um</p><p>esboço do que seria a principal ferramenta</p><p>RAD (Rapid Application Development)</p><p>baseada na linguagem Pascal, porém sem</p><p>Pascal 7.0. Aliás, utilizar a ferramenta para</p><p>criar a próxima versão da mesma</p><p>ferramenta (pelo menos em parte) é algo</p><p>comum na Borland. A interface de várias</p><p>versões do Delphi foram construídas diver-</p><p>sas vezes com versões anteriores do pró-</p><p>prio Delphi. Voltando ao Turbo Pascal for</p><p>Tela do TML Pascal</p><p>para GS/OS</p><p>Apple IIGS (16bits).</p><p>as facilidades de desenvolvimento da parte</p><p>gráfica que o Delphi possui. Na realidade,</p><p>a Borland criou o TPW baseado no seu</p><p>trabalho anterior, para MSDOS, chamado</p><p>de Turbo Vision, uma coleção de objetos</p><p>que tratam de eventos de interface. A</p><p>biblioteca do Turbo Vision foi tão versátil</p><p>que a própria Borland fez uso desta</p><p>ferramenta para construir a interface do</p><p>ambiente de seu compilador – Turbo</p><p>Windows, o lançamento desta ferramenta</p><p>veio preencher uma lacuna para aqueles</p><p>que queriam desenvolver software para</p><p>Windows 3.1x mas não estavam</p><p>confortáveis com a complexidade de</p><p>Assembly ou mesmo de C, e não se</p><p>conformaram com a inflexibilidade de</p><p>ferramentas como Toolbook ou mesmo as</p><p>primeiras versões do Visual Basic.</p><p>Em resposta ao lançamento do</p><p>Visual Basic, a Borland criou em 1995, o</p><p>Delphi – um ambiente integrado</p><p>verdadeiramente RAD, muito fácil de se</p><p>usar e, ao mesmo tempo, muito poderoso,</p><p>extremamente flexível. A primeira versão</p><p>do Delphi foi lançada ainda para o famoso</p><p>ambiente Microsoft Windows 3.1x. O Delphi</p><p>tornou-se a ferramenta mais poderosa</p><p>baseada na linguagem Pascal. A partir de</p><p>então os fãs de Pascal têm um ambiente de</p><p>indiscutível versatilidade a disposição para</p><p>criar software para Windows. Mesmo</p><p>aplicações que acessem banco de dados</p><p>são facilmente desenvolvidas no Delphi. A</p><p>segunda versão, lançada um ano depois, já</p><p>era específica para Windows 95 (32bits).</p><p>Em 2001 era vez do Linux ganhar uma</p><p>versão do Delphi. Rebatizado de Kylix, o</p><p>ambiente oferecia a mesma facilidade de</p><p>uso que as versões para Windows.</p><p>Também a VCL (biblioteca de</p><p>componentes) foi rebatizada com nome</p><p>CLX. Mais outra lacuna foi preenchida, um</p><p>ambiente RAD finalmente surgia no</p><p>horizonte do mundo Linux. O Delphi</p><p>continuou evoluindo, mudou o nome de sua</p><p>linguagem, de Object Pascal para Delphi</p><p>Language e ganhou suporte a plataforma</p><p>.NET. Hoje a Borland passa por mudanças</p><p>e ao que parece o Delphi e outras</p><p>ferramentas da companhia deverão</p><p>passar para outra empresa do grupo.</p><p>Devido ao mercado conquistado pelo</p><p>ambiente, é provável que ainda haja</p><p>FUNDAMENTOS 8</p><p>continuidade da ferramenta e novas</p><p>versões devem ser lançadas. Atualmente o</p><p>ambiente encontra-se na linha Turbo,</p><p>apresentando duas versões: Explorer</p><p>(gratuita) e Professional (paga).</p><p>Até o momento vimos que a história</p><p>da linguagem Pascal foi praticamente</p><p>escrita por ferramentas comerciais,</p><p>algumas de preço bastante acessível, mas</p><p>ainda assim, pagas. Vamos falar agora de</p><p>um software que tornou-se marco na</p><p>história da linguagem Pascal.</p><p>Estamos falando do famoso Free</p><p>Pascal, uma ferramenta fabulosa, que deu</p><p>poder inimaginável aos programadores</p><p>Pascal. A história do Free Pascal é muito</p><p>interessante e é uma prova incontestável</p><p>de que a linguagem Pascal está viva na</p><p>mente de muitos fãs e adoradores,</p><p>espalhados por todo mundo.</p><p>Em meados da década de 90, a</p><p>Borland descontinuou seus compiladores</p><p>Pascal (Turbo Pascal e Borland Pascal),</p><p>deixando órfã uma ampla comunidade de</p><p>programadores. Nesta época, uma série de</p><p>projetos tentando preencher a lacuna em</p><p>aberto, deixada pela Borland, surgiram na</p><p>tentativa de amparar a comunidade Pascal.</p><p>De todas as ferramentas, a mais</p><p>promissora foi o FPK-Pascal. Escrito pelo</p><p>estudante Florian Paul Klaempfl, o qual deu</p><p>partida ao projeto em junho de 1993, o</p><p>compilador foi renomeado, em 1997, para</p><p>Free Pascal Compiler (FPC). Em suas</p><p>primeiras versões, o FPC foi escrito em</p><p>Turbo Pascal, mas, depois de dois anos,</p><p>ele já era capaz de compilar a si mesmo,</p><p>através de um processo conhecido como</p><p>bootstraping, utilizado até hoje nas atuais</p><p>versões do Free Pascal.</p><p>Tela do Free Pascal IDE (Win32).</p><p>De substituto do Turbo Pascal a</p><p>compilador de código aberto compatível</p><p>com o Delphi, o Free Pascal extendeu seu</p><p>poder, tornando-se uma ferramenta muito</p><p>estável, capaz de concorrer em pé de</p><p>igualdade com linguagens como C++. Sua</p><p>alta portabilidade também o torna muito</p><p>atraente para os desenvolvedores que</p><p>desejam construir software para diversas</p><p>plataformas. Características inexistentes no</p><p>Turbo Pascal, foram adicionadas ao Free</p><p>Pascal, como sobrecarga de operadores e</p><p>arrays dinâmicos, deixando o FPC mais</p><p>profissional que qualquer um de seus</p><p>ancestrais. O Turbo Vision (biblioteca de</p><p>objetos para desenvolvimento de interface</p><p>em modo console) foi “clonada” e im-</p><p>plementada no FPC, agora sob código Free</p><p>Vision. Isso tudo e ainda com código-fonte</p><p>aberto (sob licença GPL) e amplamente</p><p>documentado (o FPC vem com mais de</p><p>1800 páginas de documentação).</p><p>Outros compiladores Pascal de</p><p>código aberto surgiram, mas, desculpem-</p><p>me (sou realmente suspeito por esta</p><p>alegação), o Free Pascal ainda é o melhor.</p><p>Porém alguns merecem nossa atenção,</p><p>como o GNU Pascal, por exemplo.</p><p>De tão poderoso, o FPC foi base</p><p>para outro projeto revolucionário, que está</p><p>começando a influenciar a comunidade</p><p>Delphi de todo mundo: o Lazarus.</p><p>O Lazarus é o resultado do desejo</p><p>de se ver uma ferramenta como o Delphi,</p><p>da Borland, nos moldes dos softwares de</p><p>código aberto, como o próprio Free Pascal.</p><p>O nome do projeto foi escolhido devido a</p><p>analogia com a história do personagem</p><p>bíblico de mesmo nome. Um projeto com</p><p>intuito de criar um software como o foi</p><p>iniciado, sob codinome Megido. No entanto,</p><p>o projeto não vingou e acabou “morrendo”.</p><p>Assim como Lazarus foi ressuscitado da</p><p>FUNDAMENTOS 9</p><p>morte, por Cristo, o projeto de mesmo</p><p>nome também foi ressuscitado da morte do</p><p>Megido (obviamente não por Cristo).</p><p>Da instabilidade das primeiras ver-</p><p>sões, o Lazarus caminha a passos largos</p><p>para a estabilidade, sendo possível cogitá-</p><p>lo como ferramenta de desenvolvimento</p><p>com certa cautela. O Lazarus é a prova</p><p>viva do poder do Free Pascal. A</p><p>similaridade com o ambiente da Borland é</p><p>tanta que é necessário olhar com mais</p><p>atenção, em alguns momentos, para ver se</p><p>está trabalhando no Delphi ou no Lazarus.</p><p>A compatibilidade com o Delphi é parcial,</p><p>mas alguns programas serão recompilados</p><p>no Lazarus sem mudança alguma no có-</p><p>digo fonte. Isto torna-se ainda mais acei-</p><p>tável ao lembrar que acontece a mesma</p><p>coisa entre versões diferentes do Delphi.</p><p>Apesar de não ser tão portável</p><p>quanto as primeiras versões do Free</p><p>Pascal, é possível usar o Lazarus nas</p><p>principais plataformas do momento:</p><p>Microsoft Windows (32/64 bits), Linux</p><p>(32/64 bits) e MacOS X. Nada mal para</p><p>uma ferramenta gratuita, principalmente</p><p>quando comparada com o seu clone –</p><p>Delphi, o qual, atualmente, tem suporte</p><p>apenas para trabalhar no Microsoft</p><p>Windows (o Kylix, para Linux, foi</p><p>descontinuado). As últimas versões do</p><p>Lazarus contam com diversos</p><p>componentes visuais e não visuais,</p><p>incluindo de acesso a banco de dados,</p><p>tornando esta ferramenta uma opção muito</p><p>Tela do Lazarus (clone do Delphi), rodando no Mac OS X.</p><p>atraente para a comunidade Delphi.</p><p>Bem, esta é a história (parte dela,</p><p>pelo menos) da linguagem Pascal. De</p><p>ferramenta de ensino a poderosa ferra-</p><p>menta de desenvolvimento rápido, Pascal</p><p>vem ganhando cada vez mais força,</p><p>principalmente através de softwares como</p><p>o Free Pascal e o Lazarus, e se firmando</p><p>como ferramenta profissional séria. A incrí-</p><p>vel trajetória desta linguagem denota a ele-</p><p>gância e o poder de uma ferramenta em</p><p>constante evolução. █</p><p>Referências bibliográficas</p><p>1. http://pt.wikipedia.org/wiki/Free_Pascal</p><p>2. http://pt.wikipedia.org/wiki/Turbo_Pascal</p><p>3. http://pt.wikipedia.org/wiki/Pascal_(linguagem_de_ programação )</p><p>4. http://www.lazarus.freepascal.org/</p><p>5. Palmer, Scott D.; Guia do Programador Turbo Pascal for Windows;</p><p>páginas 3 e 4; Editora Ciência Moderna Ltda.; 1992.</p><p>6. Reis, Maurício Costa; Pascal; revista Micro Sistemas Nº 19; páginas</p><p>34 e 35; ATI Editora Ltda.; abril/1983.</p><p>http://www.lazarus.freepascal.org/</p><p>http://pt.wikipedia.org/wiki/Pascal_(linguagem_de_programa??o</p><p>http://pt.wikipedia.org/wiki/Turbo_Pascal</p><p>http://pt.wikipedia.org/wiki/Free_Pascal</p><p>REPORTAGEM 10</p><p>FREE PASCAL</p><p>COMO AMBIENTE</p><p>PROFISSIONAL</p><p>Se você é um entusiasta</p><p>da linguagem Pascal e</p><p>está decidindo qual</p><p>ferramenta usar para tocar</p><p>seus projetos, não deixe</p><p>de ler esta reportagem.</p><p>Por Ericson Benjamim</p><p>Ao longo da história da linguagem</p><p>Pascal vimos diversos ambientes basea-</p><p>dos nesta linguagem surgirem. Alguns se</p><p>consagraram na área acadêmica e outros</p><p>como ferramenta de uso genérico, servindo</p><p>de base a projetos de diversas áreas.</p><p>Houve o UCSD Pascal, que foi usado até</p><p>no desenvolvimento de sistemas operacio-</p><p>nais; o Turbo Pascal, muito usado na área</p><p>acadêmica e também na indústria e</p><p>comércio; e mais recentemente o Delphi foi</p><p>a principal ferramenta baseada na</p><p>linguagem Pascal. Em resposta a descon-</p><p>tinuidade do Turbo Pascal surgiu o Free</p><p>Pascal, um compilador que rapidamente</p><p>ganhou força e destaque na comunidade.</p><p>Suas principais armas são a estabilidade</p><p>atingida pela ferramenta e a ampla capa-</p><p>cidade multi plataforma, além de outras</p><p>características como a excelente legibili-</p><p>dade do código e facilidade de aprendizado</p><p>proporcionado pela linguagem Pascal.</p><p>A capacidade de evolução da lingua-</p><p>gem e o surgimento de diversas bibliotecas</p><p>de apoio que complementam o poder do</p><p>Free Pascal. Bibliotecas estas que</p><p>permitem ao programador acessar banco</p><p>de dados como MySQL, PostgreSQL e</p><p>outros, criar sistemas de comunicação</p><p>via TCP/IP,</p><p>utilizar interface gráfica, tirar proveito da</p><p>multi tarefa e muito mais. A constante</p><p>evolução do Free Pascal e a</p><p>disponibilidade de bibliotecas diversas</p><p>permitiu que projetos como o Lazarus (o</p><p>ambiente clone do Delphi) fossem criados.</p><p>É bom comentar que estamos falando do</p><p>Free Pascal e não do Lazarus. Apesar do</p><p>Lazarus ter sido construído em Free Pascal</p><p>e ter esse compilador embutido, são duas</p><p>ferramentas diferentes. O Free Pascal</p><p>atualmente encontra-se com diversa</p><p>versões estáveis mas o Lazarus ainda está</p><p>em versão beta e não é considerado um</p><p>software estável. Calma, ele chega lá muito</p><p>em breve.</p><p>Mas aí vem a pergunta: porque não</p><p>usar um compilador baseado em C?</p><p>Poderíamos fazer a mesma pergunta para</p><p>o Free Pascal: porque não usar o Free</p><p>Pascal? No fim das contas o que acaba</p><p>decidindo que compilador usar é o gosto</p><p>pessoal dos envolvidos no projeto, pois já</p><p>encontramos no Free Pascal praticamente</p><p>o mesmo poder computacional encontrado</p><p>em compiladores baseados em C. É claro</p><p>que a disponibilidade de uma certa</p><p>biblioteca pode pesar na hora da decisão,</p><p>REPORTAGEM 11</p><p>mas o grande peso mesmo acaba sendo a</p><p>afinidade que o programador possui com a</p><p>linguagem que deseja trabalhar. E escolher</p><p>a ferramenta certa resultará no sucesso ou</p><p>no fracasso do projeto. Ninguém quer</p><p>escolher uma ferramenta que subitamente</p><p>pare no tempo ou mesmo mude drastica-</p><p>mente de filosofia.</p><p>Pois é, isto já aconteceu algumas</p><p>vezes e podem acreditar, é uma situação</p><p>muito frustrante. Depois de dedicar sua</p><p>confiança e tempo a uma ferramenta que</p><p>parecia promissora e de uma hora para</p><p>outra esta simplesmente para no tempo,</p><p>você acaba sentindo-se perdido, sem saber</p><p>como vai poder tocar seus projetos com</p><p>uma ferramenta que pode ter sido</p><p>abandonada ou coisa parecida.</p><p>Um exemplo que ilustra bem esta</p><p>situação é de um compilador que poucos</p><p>conhecem por causa da brevidade de vida</p><p>útil que teve: o Rapid-Q BASIC, de Willian</p><p>Yu. Quando surgiu, o Rapid-Q pareceu</p><p>muito promissor. Suas características</p><p>denotavam esta qualidade: multi plataforma</p><p>(Windows, Linux, Solaris e HP-UX),</p><p>facilidade de aprendizado (muito similar à</p><p>sintaxe do Visual Basic), excelente</p><p>legibilidade de código, parcialmente</p><p>orientado a objeto e razoável estabilidade.</p><p>O projeto foi iniciado no fim da década de</p><p>1990 e rapidamente ganhou muitos</p><p>adeptos que ansiavam por uma ferramenta</p><p>gratuita, fácil de usar e familiar (no caso em</p><p>referência ao Visual Basic). O projeto do</p><p>Rapid-Q seguiu, recebendo atualizações</p><p>até meados do ano 2000, quando</p><p>praticamente parou de ser atualizado. E</p><p>quase no final deste ano veio a bomba: seu</p><p>desenvolvedor vendeu o código fonte de</p><p>sua obra a uma empresa (Real Software)</p><p>para servir de base para um projeto</p><p>comercial de um ambiente com compilador</p><p>integrado baseado na linguagem BASIC –</p><p>Real Basic, muito popular entre os usuários</p><p>do Mac OS X (além deste ele roda também</p><p>no Linux e Windows). O endereço do</p><p>Rapid-Q na Internet foi tirado do ar e toda</p><p>comunidade, em polvorosa, manifestou-se</p><p>contra a atitude, pois sua principal</p><p>ferramenta de trabalho havia, do dia para</p><p>Tela do Rapid-Q IDE.</p><p>Mudança de filosofia deixou toda uma comunidade órfã.</p><p>REPORTAGEM 12</p><p>noite, de software gratuito, tornado-se um</p><p>ambiente comercial – uma mudança radical</p><p>de filosofia.</p><p>A contra-gosto da Real Software, a</p><p>comunidade resolveu manter um espelho</p><p>do antigo endereço do Rapid-Q e ainda</p><p>hoje encontramos uma comunidade bas-</p><p>tante ativa, com pelo menos dois fóruns de</p><p>discussão com mais de 2.000 usuários.</p><p>Apesar de todo esforço o Rapid-Q continua</p><p>parado no tempo, sem receber nenhuma</p><p>atualização desde 2000. Seu futuro é</p><p>incerto o suficiente para desencorajar qual-</p><p>quer um a não embarcar</p><p>em um projeto de</p><p>longa vida com esta ferramenta.</p><p>Mas será que o futuro do Free</p><p>Pascal não poderia ser o mesmo do Rapid-</p><p>Q? É muito improvável que isto aconteça.</p><p>Apesar de ter sido fruto do trabalho de uma</p><p>única pessoa (Florian Klaëmpfl), o Free</p><p>Pascal atualmente é resultado do trabalho</p><p>conjunto de toda uma comunidade. Alem</p><p>disso, o Free Pascal foi amarrado a uma</p><p>licença GPL, que garante a gratuidade do</p><p>software. Alem de contar com uma</p><p>comunidade de milhares de usuários pelo</p><p>mundo, o Free Pascal é um projeto ativo,</p><p>que recebe constantes atualizações,</p><p>mostrando que está sob contínua evolução,</p><p>ou seja, uma escolha natural para os</p><p>entusiastas da linguagem Pascal.</p><p>Agora que sabemos que o Free</p><p>Pascal é uma ferramenta capaz de</p><p>competir em pé de igualdade com outras</p><p>baseadas em C surge a dúvida: porque</p><p>não se vê tantos projetos baseados neste</p><p>compilador? Talvez porque somente em</p><p>2003 (versão 1.0.10) o Free Pascal tenha</p><p>atingido um grau de estabilidade apurado o</p><p>suficiente para ser considerado. Ou porque</p><p>somente a partir das versões 1.9.x o modo</p><p>de compatibilidade com Delphi tenha sido</p><p>aperfeiçoado. Não sabemos ao certo, mas</p><p>tudo indica que o Free Pascal está no início</p><p>de sua carreira (em se tratando das</p><p>versões estáveis) e por isso poucos ainda</p><p>tenham cogitado a mesma como fer-</p><p>ramenta principal de trabalho. E ainda tem</p><p>a estigma de linguagem de uso acadêmico,</p><p>que Pascal carrega desde seu nascimento.</p><p>Seja o que for, o fato é que o compilador</p><p>Free Pascal é uma ferramenta poderosa e</p><p>está a disposição a praticamente todos os</p><p>microcomputadores do planeta. Estou</p><p>falando das plataformas mais usadas,</p><p>como Windows, Mac OS/X, Linux etc.</p><p>Exemplos de softwares consagrados</p><p>desenvolvidos em Free Pascal ajudariam</p><p>muito. Concordo plenamente. Para come-</p><p>çar o Lazarus é um excelente exemplo e</p><p>ainda nem saiu da versão beta. O Lazarus,</p><p>projeto de uma IDE baseada em Free</p><p>Pascal para ser clone do Delphi, aproveita-</p><p>se do poder do Free Pascal e de sua</p><p>capacidade multi plataforma (apesar de ter</p><p>sido restringido aos três mais usados</p><p>sistemas operacionais da atualidade). As</p><p>últimas versões do Lazarus estão se</p><p>mostrando eficientes o bastante para serem</p><p>usadas por diversos programadores em</p><p>projetos de pequeno e médio porte.</p><p>Além do Lazarus, há também um</p><p>programa de edição de imagens que</p><p>tornou-se muito famoso recentemente: o</p><p>Pixel Image Editor, desenvolvido por Pavel</p><p>Kanzelsberger, um jovem programador da</p><p>REPORTAGEM 13</p><p>Eslováquia (junto com a República Tcheca,</p><p>fazia parte da antiga Tchecoslováquia).</p><p>Também conhecido como Pixel32, este</p><p>editor vem ganhando notoriedade não por</p><p>ter sido desenvolvido em Free Pascal, mas</p><p>por concorrer com pesos-pesados como o</p><p>Adobe Photoshop. De longe é a aplicação</p><p>mais incrível já feita em Free Pascal, não</p><p>só pelo seu visual limpo e equilibrado</p><p>(seguindo o padrão do Photoshop) como</p><p>também por estar disponível em mais de 10</p><p>plataformas, até mesmo MS-DOS e outras</p><p>ainda mais exóticas. Apesar de ser um</p><p>software comercial, o Pixel32 custa muito</p><p>barato (38 dólares atualmente), um preço</p><p>ínfimo, acreditem, devido aos recursos que</p><p>ele oferece. O Pixel32 pode ser visualizado</p><p>em pelo menos 17 idiomas diferentes,</p><p>incluindo português brasileiro.</p><p>FANZINE.PAS entrou em contato</p><p>com Pavel Kanzelsberger e ele nos</p><p>concedeu uma pequena entrevista e contou</p><p>porque o Free Pascal foi escolhido em seu</p><p>projeto e quão grande é o potencial que</p><p>este compilador pode oferecer. Confira.</p><p>Entrevista concedida em 09/10/2006</p><p>: Caro Sr. Kanzelsberger, co-</p><p>mo vai? Poderia nos falar um pouco de si?</p><p>Onde o Sr. Vive? Sua formação acadê-</p><p>mica e qualquer coisa que ache relevante.</p><p>P. Kanzelsberger: Eu tenho 29 anos e</p><p>vivo com minha esposa e filho de 6 meses.</p><p>Nós somos da Eslováquia, na Europa. Fui</p><p>estudante de Sistemas de Informações</p><p>Geográficas (GIS), mas deixei o curso e</p><p>concentrei-me em programação, incluindo</p><p>o Pixel.</p><p>: A quanto tempo o Sr. está</p><p>envolvido com Pascal? Quais versões?</p><p>P. Kanzelsberger: Estou envolvido com o</p><p>Free Pascal desde seu início, e mudei para</p><p>este novo compilador a partir do antigo</p><p>Turbo Pascal. Mudei para o Free Pascal</p><p>desde que ele ofereceu suporte a 32bits e</p><p>portabilidade real. Também fui auxiliado</p><p>pela primeira versão do Free Pascal para</p><p>BeOS.</p><p>: O Sr. desenvolveu outros</p><p>programas em Pascal?</p><p>P. Kanzelsberger: Na realidade, não.</p><p>Meus outros projetos eram e ainda são na</p><p>maioria sistemas baseados em arquitetura</p><p>cliente/servidor, usualmente escritos em</p><p>PHP/SQL.</p><p>: Porque o Sr. escolheu o</p><p>Free Pascal para desenvolver o Pixel32?</p><p>Outra linguagem foi usada neste</p><p>programa?</p><p>P. Kanzelsberger: Em tempo porque era</p><p>a primeira versão de um compilador Pascal</p><p>de 32bits e desde que eu gostei muito da</p><p>sintaxe de Pascal não utilizei mais C ou</p><p>C++. Pixel é escrito em sua maior parte em</p><p>Pascal, mas há algumas partes críticas em</p><p>em Assembly e umas poucas bibliotecas</p><p>externas de ligação em linguagem C.</p><p>: Pode nos falar um pouco</p><p>da história do desenvolvimento do Pixel32?</p><p>P. Kanzelsberger: Começou por volta de</p><p>1997 em um antigo PC XT. Meu plano era</p><p>de fazer jogos e havia uma escassez de</p><p>editores de imagens decentes que</p><p>rodassem em DOS e computadores XT</p><p>(não existia nenhum). Tinha visto alguns</p><p>editores legais rodando no Macintosh em</p><p>algumas revistas e tive idéia de criar algo</p><p>para mim mesmo.</p><p>Acho que o Pixel foi o primeiro editor</p><p>de imagens para DOS a ter interface gráfica</p><p>amigável e suporte a plugins e mais tarde,</p><p>quando o Windows tornou-se mais popular,</p><p>reescrevi o Pixel pela primeira vez para</p><p>este sistema. Pouco tempo depois a Be</p><p>Inc. me contatou e pediu a versão para</p><p>BeOS. Novamente, depois de algum tempo,</p><p>reescrevi o Pixel para que rodasse em</p><p>outras plataformas, incluindo QNX, Linux</p><p>etc.</p><p>A versão atual tem entre 3 e 4 anos</p><p>de idade e um modelo de portabilidade</p><p>muito bom.</p><p>: E quanto ao retorno</p><p>financeiro? O Sr. pode afirmar que o</p><p>Pixel32 é um sucesso?</p><p>P. Kanzelsberger: Sim, posso confirmar</p><p>que é um sucesso, ele é a única coisa na</p><p>REPORTAGEM 14</p><p>Tela do Pixel Image Editor para Windows.</p><p>Mais de uma dezena de sistemas operacionais suportados e interface similar ao Photoshop.</p><p>qual tenho trabalhado desde então.</p><p>: Há novos projetos basea-</p><p>dos em Free Pascal?</p><p>P. Kanzelsberger: Penso que se o</p><p>desenvolvimento do Free Pascal continuar</p><p>tão rápido como anda atualmente, poderei</p><p>contar com este compilador em outros</p><p>projetos. Talvez um editor vetorial.</p><p>: O Sr. considerou o Lazarus</p><p>como ferramenta para seus projetos?</p><p>P. Kanzelsberger: Ainda não. Ele precisa</p><p>amadurecer um pouco mais e no futuro</p><p>será uma ótima ferramenta para desen-</p><p>volvedores. No momento prefiro escrever</p><p>tudo eu mesmo em um editor de textos,</p><p>evitando ferramentas RAD, para conseguir</p><p>um programa tão rápido e pequeno quanto</p><p>seja possível.</p><p>Uma desvantagem atual do Lazarus</p><p>é usar bibliotecas gráficas como GTK ou</p><p>Qt e não gosto de nenhuma destas. E</p><p>pelas diversas versões de Linux ainda</p><p>sentimos falta de uma biblioteca gráfica</p><p>padrão. Acredito que o Lazarus deva ter um</p><p>futuro mais brilhante no Windows e no</p><p>MacOS X, através do suporte nativo à</p><p>interface gráfica.</p><p>: Quanto ao futuro do Free</p><p>Pascal, o que o Sr. poderia comentar?</p><p>P. Kanzelsberger: É um grande compila-</p><p>dor, comparável com outros como gcc.</p><p>Para o futuro, ele necessita de desenvolvi-</p><p>mento rápido e melhor divulgação. Acho</p><p>que o Free Pascal começaria melhor se</p><p>mais projetos de código aberto o</p><p>utilizassem como ferramenta de desenvolvi-</p><p>mento.</p><p>: O que o Sr. poderia dizer</p><p>aos novatos que estão pensando em</p><p>utilizar o Free Pascal</p><p>como ferramenta</p><p>profissional?</p><p>P. Kanzelsberger: Free Pascal já é uma</p><p>ferramenta profissional. Você pode confiar</p><p>nele sem problemas. Ele roda em diversas</p><p>plataformas e quando o seu sistema opera-</p><p>REPORTAGEM 15</p><p>cional exótico morrer você pode mudar</p><p>para outro sem ter de aprender uma nova</p><p>linguagem. █</p><p>Depois de um depoimento de um</p><p>especialista deste porte não podemos mais</p><p>duvidar do poder do Free Pascal. Como</p><p>podem ver Pavel Kanzelsberger preferiu</p><p>utilizar o Free Pascal puro ao invés do</p><p>Lazarus, de modo a ter controle total do</p><p>visual do programa e conseguir desem-</p><p>penho máximo (primordial para uma</p><p>aplicação de edição de imagens). Mas</p><p>mesmo assim ele acredita no futuro deste</p><p>ambiente, principalmente nas plataformas</p><p>Windows e Mac OS X. Lembrem-se, o</p><p>Lazarus ainda está em versão beta.</p><p>Um detalhe que deixa muitos</p><p>desenvolvedores com a pulga atrás da</p><p>orelha na hora de portar uma aplicação de</p><p>uma plataforma para outra é a interface</p><p>gráfica. Devido a falta de padronização da</p><p>interface gráfica entre os diversos sistemas</p><p>operacionais, perde-se muito tempo</p><p>ajustando a interface entre uma e outra</p><p>plataforma. Porém para os abençoados</p><p>usuários do Free Pascal existe uma saída</p><p>muito interessante, se abdicarem do modo</p><p>gráfico. Sim, sem modo gráfico, mas não</p><p>significa que vamos abdicar de uma</p><p>interface amigável. Quem prover esta saída</p><p>é a Free Vision, uma biblioteca (framework</p><p>seria mais adequado) que fornece ao</p><p>programador, facilidade de criação de</p><p>interfaces amigáveis em modo texto. Na</p><p>Tela do Free Pascal IDE.</p><p>Interface amigável construída</p><p>a partir do Free Vision.</p><p>realidade ela é versão gratuita da Turbo</p><p>Vision, criada pela Borland e usada em</p><p>seus últimos pacotes (Turbo C e Pascal)</p><p>para MSDOS. Uma ótima solução para</p><p>quem precisar de uma aplicação robusta e</p><p>fácil de operar. Um desenvolvedor poderia</p><p>facilmente implementar um sistema</p><p>amigável que rodasse em um servidor</p><p>Linux, através de um terminal seguro</p><p>(SSH) usando um banco de dados como</p><p>MySQL ou PostgreSQL, viabilizando, com</p><p>segurança, até mesmo o acesso remoto</p><p>através de conexões de baixa velocidade,</p><p>como Internet via linha discada. A própria</p><p>IDE do Free Pascal foi construída com o</p><p>Free Vision. Mas isto será palco para a</p><p>próxima FANZINE.PAS. █</p><p>Referências bibliográficas</p><p>1. http://en.wikipedia.org/wiki/RapidQ</p><p>2. http://pt.wikipedia.org/wiki/Lazarus</p><p>3. http://www.kanzelsberger.com/</p><p>4. http://en.wikipedia.org/wiki/Pixel32</p><p>http://www.lazarus.freepascal.org/</p><p>http://www.lazarus.freepascal.org/</p><p>http://www.lazarus.freepascal.org/</p><p>http://www.lazarus.freepascal.org/</p><p>PROGRAMAÇÃO - JOGOS 16</p><p>SNAKE</p><p>O JOGO DA</p><p>COBRA</p><p>Aprenda técnicas</p><p>simples de programação</p><p>através de um clássico</p><p>dos computadores e</p><p>celulares</p><p>Por Ericson Benjamim</p><p>Quantas versões não foram criadas</p><p>deste pequeno jogo? Só em BASIC devo</p><p>ter visto dezenas. Celulares? Houve uma</p><p>geração inteira desses aparelhos com pelo</p><p>menos uma versão ou outra deste jogo. O</p><p>jogo da cobra é um ótimo exercício para</p><p>quem estar iniciando no mundo da</p><p>programação e deseja afiar os conheci-</p><p>mentos. É uma excelente oportunidade</p><p>para treinar a utilização de vetores, trata-</p><p>mento de entrada via teclado e, nesta versão, fazer uma breve introdução ao mundo da</p><p>orientação a objetos.</p><p>O jogo, para quem não conhece, é muito simples: você comanda uma cobra</p><p>caçando ratos. A cada rato comido a cobra cresce um segmento. Tenha cuidado para que</p><p>a cobra não acerte seus próprios segmentos ou os limites da área do jogo. O jogo foi feito</p><p>em modo texto, e deve ser compilado sem problemas em qualquer versão do Free Pascal</p><p>a partir da 1.0.6, tanto no Windows como no Linux. Deve funcionar também no Turbo</p><p>Pascal 7.0.</p><p>LISTAGEM DO JOGO</p><p>{</p><p>Jogo da Cobra em modo texto</p><p>Utiliza orientação a objetos</p><p>Desenvolvido em Free Pascal</p><p>por Ericson Benjamim, maio/2005</p><p>ericsonbenjamim arroba yahoo ponto com ponto br</p><p>}</p><p>program Jogo_da_Cobra;</p><p>uses crt, sysutils;</p><p>const ArUp = #72;</p><p>ArDn = #80;</p><p>ArLf = #75;</p><p>PROGRAMAÇÃO - JOGOS 17</p><p>ArRt = #77;</p><p>Enter = #13;</p><p>Esc = #27;</p><p>type TCobraObj = ^CobraObj;</p><p>TSegObj = ^SegObj;</p><p>{ Objeto Cobra }</p><p>CobraObj = object</p><p>{ Propriedades }</p><p>ByteX, ByteY: Byte; { Coordenada atual }</p><p>ByteOldX, ByteOldY: Byte; { Coordenada anterior }</p><p>ByteIncremento: Byte; { Incremento que faz a cobra se mover }</p><p>WordSegmentos: Word; { Quantos segmentos a cobra tem }</p><p>WordRedesenho: Word; { Tempo para redesenho em milisegundos }</p><p>CharDirecao: Char; { Direcao na qual a cabeca segue:</p><p>L=LESTE, O=OESTE, S=SUL, N=NORTE }</p><p>BooColisao: Boolean; { Registra colisao entre os segmentos e a</p><p>cabeca }</p><p>PrimSegObj: TSegObj;</p><p>UltSegObj: TSegObj;</p><p>{ Metodos }</p><p>procedure Inicia; { Inicializa o objeto Cobra }</p><p>procedure Reinicia; { Reinicializa o objeto Cobra }</p><p>procedure Desenha; { Desenha a cobra e todos os seus segmentos }</p><p>procedure Move; { Move a cobra e todos os seus segmentos }</p><p>procedure AdSegmento; { Adiciona um segmento }</p><p>end;</p><p>{ Objeto Segmento }</p><p>SegObj = object</p><p>ByteX, ByteY: Byte; { Coordenada atual }</p><p>ByteOldX, ByteOldY: Byte; { Coordenada anterior }</p><p>AntSegObj: TSegObj; { Segmento anterior }</p><p>PrxSegObj: TSegObj; { Próximo segmento }</p><p>end;</p><p>{ Combina os comandos write e gotoxy }</p><p>procedure writeXY(ByteX, ByteY: Byte; Strg: String);</p><p>begin</p><p>gotoXY(ByteX, ByteY);</p><p>write(Strg);</p><p>end;</p><p>{ Inicializa o objeto Cobra }</p><p>procedure CobraObj.Inicia;</p><p>begin</p><p>CharDirecao := 'L';</p><p>ByteX := 10;</p><p>ByteY := 12;</p><p>WordRedesenho := 100;</p><p>ByteIncremento := 1;</p><p>WordSegmentos := 1;</p><p>BooColisao := false;</p><p>New(PrimSegObj);</p><p>PrimSegObj^.ByteX := ByteX - 1;</p><p>PrimSegObj^.ByteY := ByteY;</p><p>PrimSegObj^.AntSegObj := nil;</p><p>PrimSegObj^.PrxSegObj := nil;</p><p>UltSegObj := PrimSegObj;</p><p>end;</p><p>{ Reinicializa o objeto Cobra }</p><p>procedure CobraObj.Reinicia;</p><p>var ApagaSegObj: TSegObj;</p><p>BooFimSeg: Boolean;</p><p>begin</p><p>CharDirecao := 'L';</p><p>ByteX := 10;</p><p>ByteY := 12;</p><p>WordRedesenho := 100;</p><p>ByteIncremento := 1;</p><p>WordSegmentos := 1;</p><p>BooColisao := false;</p><p>BooFimSeg := false;</p><p>while not BooFimSeg do</p><p>if PrimSegObj <> UltSegObj then</p><p>begin</p><p>ApagaSegObj := UltSegObj;</p><p>UltSegObj := ApagaSegObj^.AntSegObj;</p><p>UltSegObj^.PrxSegObj := nil;</p><p>Dispose(ApagaSegObj);</p><p>end</p><p>else</p><p>begin</p><p>BooFimSeg := true;</p><p>end;</p><p>end;</p><p>PROGRAMAÇÃO - JOGOS 18</p><p>{ Metodo desenha a cobra e todos os seus segmentos }</p><p>procedure CobraObj.Desenha;</p><p>var DesSegObj: TSegObj;</p><p>BooFimSeg: Boolean;</p><p>begin</p><p>{ Desenha a cabeca }</p><p>writeXY(ByteX, ByteY, '@');</p><p>{ Desenha os segmentos }</p><p>DesSegObj := PrimSegObj;</p><p>BooFimSeg := false;</p><p>while not BooFimSeg do</p><p>begin</p><p>DesSegObj^.ByteOldX := DesSegObj^.ByteX;</p><p>DesSegObj^.ByteOldY := DesSegObj^.ByteY;</p><p>if DesSegObj^.AntSegObj = nil then</p><p>begin</p><p>{ Eh o primeiro segmento e pega a</p><p>coordenada anterior da cabeca }</p><p>DesSegObj^.ByteX := ByteOldX;</p><p>DesSegObj^.ByteY := ByteOldY;</p><p>end</p><p>else</p><p>begin</p><p>{ Nao eh o primeiro segmento e pega a</p><p>coordenada anterior do segmento anterior }</p><p>DesSegObj^.ByteX := DesSegObj^.AntSegObj^.ByteOldX;</p><p>DesSegObj^.ByteY := DesSegObj^.AntSegObj^.ByteOldY;</p><p>end;</p><p>{ Verifica se houve colisao }</p><p>if (DesSegObj^.ByteX = ByteX) and (DesSegObj^.ByteY = ByteY) then</p><p>BooColisao := true;</p><p>writeXY(DesSegObj^.ByteX, DesSegObj^.ByteY, 'O');</p><p>{ Verifica se eh o ultimo segmento }</p><p>if DesSegObj^.PrxSegObj <> nil then</p><p>begin</p><p>DesSegObj := DesSegObj^.PrxSegObj;</p><p>end</p><p>else</p><p>begin</p><p>BooFimSeg := true;</p><p>writeXY(DesSegObj^.ByteOldX, DesSegObj^.ByteOldY, ' ');</p><p>end;</p><p>end;</p><p>end;</p><p>{ Metodo move a Cobra }</p><p>procedure CobraObj.Move;</p><p>begin</p><p>{ Armazena a ultima coordenada da cabeca antes de mover }</p><p>ByteOldX := ByteX;</p><p>ByteOldY := ByteY;</p><p>{ Verifica em qual direcao a cobra esta se movimentando }</p><p>case CharDirecao of</p><p>'L': ByteX := ByteX + ByteIncremento;</p><p>'O': ByteX := ByteX - ByteIncremento;</p><p>'S': ByteY := ByteY + ByteIncremento;</p><p>'N': ByteY := ByteY - ByteIncremento;</p><p>end;</p><p>Desenha;</p><p>Delay(WordRedesenho);</p><p>end;</p><p>{ Metodo adiciona um segmento }</p><p>procedure CobraObj.AdSegmento;</p><p>var NewSegObj: TSegObj;</p><p>begin</p><p>New(NewSegObj);</p><p>NewSegObj^.AntSegObj := UltSegObj;</p><p>UltSegObj^.PrxSegObj := NewSegObj;</p><p>UltSegObj := NewSegObj;</p><p>UltSegObj^.PrxSegObj := nil;</p><p>UltSegObj^.ByteX := UltSegObj^.AntSegObj^.ByteOldX;</p><p>UltSegObj^.ByteY := UltSegObj^.AntSegObj^.ByteOldY;</p><p>Inc(WordSegmentos);</p><p>end;</p><p>var Cobra: TCobraObj;</p><p>BooJogar: Boolean;</p><p>ByteContaRatos: Byte;</p><p>LongIntPontos, LongIntJogoPtos: LongInt;</p><p>VetRato: array[3..78, 4..23] of Boolean;</p><p>{ Coloca os ratos na tela - armazena em um vetor }</p><p>procedure Ratos(ByteRatoCont: Byte);</p><p>var ByteRatoX, ByteRatoY, ByteCont, ByteRandomX, ByteRandomY: Byte;</p><p>BooFimCobraSeg, BooInSeg: Boolean;</p><p>CobraSegObj: TSegObj;</p><p>begin</p><p>TextColor(Yellow);</p><p>ByteCont := 0;</p><p>for ByteRatoX := 3 to 78 do</p><p>PROGRAMAÇÃO - JOGOS 19</p><p>for ByteRatoy := 4 to 23 do</p><p>VetRato[ByteRatoX, ByteRatoY] := false;</p><p>Randomize;</p><p>while (ByteCont < ByteRatoCont) do</p><p>begin</p><p>{ Gera aleatoriamente as coordenadas dos ratos }</p><p>ByteRandomX := Random(76) + 3;</p><p>ByteRandomY := Random(20) + 4;</p><p>{ Verifica se não vai criar os ratos</p><p>nas mesmas coordenadas da cobra }</p><p>if not VetRato[ByteRandomX, ByteRandomY] and</p><p>(ByteRandomX <> Cobra^.ByteX) and</p><p>(ByteRandomY <> Cobra^.ByteY) then</p><p>begin</p><p>BooFimCobraSeg := false;</p><p>BooInSeg := false;</p><p>CobraSegObj := Cobra^.PrimSegObj;</p><p>{ Verifica se não vai criar os ratos nas</p><p>mesmas coordenadas de cada segmento da cobra }</p><p>while not BooFimCobraSeg do</p><p>begin</p><p>if (ByteRandomX = CobraSegObj^.ByteX) and</p><p>(ByteRandomY = CobraSegObj^.ByteY) then</p><p>BooInSeg := true;</p><p>CobraSegObj := CobraSegObj^.PrxSegObj;</p><p>if CobraSegObj = nil then BooFimCobraSeg := true;</p><p>end;</p><p>if not BooInSeg then</p><p>begin</p><p>Inc(ByteCont);</p><p>writeXY(ByteRandomX, ByteRandomY, 'Q');</p><p>VetRato[ByteRandomX, ByteRandomY] := true;</p><p>end;</p><p>end;</p><p>end;</p><p>end;</p><p>{ Desenha o cenario }</p><p>procedure Cenario;</p><p>var WordX: Word;</p><p>begin</p><p>TextBackGround(Green);</p><p>ClrScr;</p><p>TextColor(Yellow);</p><p>writeXY( 5, 1, 'J o g o d a C o b r a');</p><p>writeXY(60, 1, 'Pontos:');</p><p>TextBackGround(LightBlue);</p><p>for WordX := 2 to 79 do</p><p>begin</p><p>writeXY(WordX, 3, ' ');</p><p>writeXY(WordX, 24, ' ');</p><p>if (WordX >= 3) and (WordX <= 24) then</p><p>begin</p><p>writeXY( 2, WordX, ' ');</p><p>writeXY(79, WordX, ' ');</p><p>end;</p><p>end;</p><p>TextBackGround(Green);</p><p>end;</p><p>{ Inicia o jogo e ao final retorna os pontos }</p><p>function Jogo: LongInt;</p><p>var BooJogo: Boolean;</p><p>ChTecla: Char;</p><p>ByteContRatos: Byte;</p><p>LongIntPtos: LongInt;</p><p>begin</p><p>LongIntPtos := 0;</p><p>ByteContRatos := 0;</p><p>BooJogo := true;</p><p>while BooJogo do</p><p>begin</p><p>if keypressed then ChTecla := Readkey;</p><p>case ChTecla of</p><p>ArRt: if Cobra^.CharDirecao = 'O' then</p><p>begin</p><p>BooJogo := false;</p><p>LongIntPtos := 0;</p><p>end</p><p>else</p><p>begin</p><p>Cobra^.CharDirecao := 'L';</p><p>end;</p><p>ArLf: if Cobra^.CharDirecao = 'L' then</p><p>begin</p><p>BooJogo := false;</p><p>LongIntPtos := 0;</p><p>end</p><p>else</p><p>PROGRAMAÇÃO - JOGOS 20</p><p>begin</p><p>Cobra^.CharDirecao := 'O';</p><p>end;</p><p>ArDn: if Cobra^.CharDirecao = 'N' then</p><p>begin</p><p>BooJogo := false;</p><p>LongIntPtos := 0;</p><p>end</p><p>else</p><p>begin</p><p>Cobra^.CharDirecao := 'S';</p><p>end;</p><p>ArUp: if Cobra^.CharDirecao = 'S' then</p><p>begin</p><p>BooJogo := false;</p><p>LongIntPtos := 0;</p><p>end</p><p>else</p><p>begin</p><p>Cobra^.CharDirecao := 'N';</p><p>end;</p><p>Enter: repeat until keypressed;</p><p>Esc : begin</p><p>BooJogo := false;</p><p>LongIntPtos := 0;</p><p>end;</p><p>end;</p><p>ChTecla := ' ';</p><p>TextColor(Black);</p><p>Cobra^.Move;</p><p>if (Cobra^.ByteX < 3) or (Cobra^.ByteX > 78) or</p><p>(Cobra^.ByteY < 4) or (Cobra^.ByteY > 23) or</p><p>Cobra^.BooColisao then</p><p>begin</p><p>BooJogo := false;</p><p>LongIntPtos := 0;</p><p>end;</p><p>if VetRato[Cobra^.ByteX, Cobra^.ByteY] then</p><p>begin</p><p>Cobra^.AdSegmento;</p><p>Inc(LongIntPtos);</p><p>Inc(ByteContRatos);</p><p>TextColor(White);</p><p>writeXY(68, 1, IntToStr(LongIntPtos));</p><p>VetRato[Cobra^.ByteX, Cobra^.ByteY] := false;</p><p>end;</p><p>if ByteContRatos = ByteContaRatos then BooJogo := false;</p><p>end;</p><p>Jogo := LongIntPtos;</p><p>end;</p><p>procedure Instrucoes;</p><p>begin</p><p>TextBackGround(Black);</p><p>TextColor(LightGreen);</p><p>ClrScr;</p><p>writeXY(6, 3, 'J o g o d a C o b r a');</p><p>writeXY(3, 5, 'Jogo feito em Free Pascal utilizando recursos de ' +</p><p>'orientacao a objetos e');</p><p>writeXY(3, 6, 'lista encadeada.');</p><p>writeXY(3, 8, 'Desenvolvido por Ericson Benjamim');</p><p>writeXY(3, 10, 'Email para contato: ericsonbenjamim@yahoo.com.br');</p><p>writeXY(3, 12, 'Data: 28 de Maio de 2005');</p><p>writeXY(3, 14, 'Utilize as setas para movimentar a cobra.');</p><p>writeXY(3, 15, 'Enter para pausar o jogo.');</p><p>writeXY(3, 16, 'Esc para sair.');</p><p>writeXY(3, 19, 'Pressione uma tecla para continuar...');</p><p>Readkey;</p><p>end;</p><p>procedure Parabens;</p><p>begin</p><p>TextBackGround(Black);</p><p>TextColor(LightGreen);</p><p>ClrScr;</p><p>writeXY(6, 3, 'J o g o d a C o b r a');</p><p>writeXY(3, 5, 'Parabens');</p><p>writeXY(3, 7, 'Você chegou ao ultimo nivel.');</p><p>writeXY(3, 10, 'Pressione uma tecla para continuar...');</p><p>Readkey;</p><p>end;</p><p>function BooContinuaJogo: Boolean;</p><p>var ChOpcao: Char;</p><p>begin</p><p>TextBackGround(Black);</p><p>TextColor(LightGreen);</p><p>ClrScr;</p><p>PROGRAMAÇÃO - JOGOS 21</p><p>writeXY(3, 3, 'J o g o d a C o b r a');</p><p>writeXY(3, 7, 'Seus pontos: ' + IntToStr(LongIntPontos));</p><p>writeXY(3, 9, 'Continuar jogando? [S] ou [N]');</p><p>ChOpcao := ' ';</p><p>while (UpCase(ChOpcao) <> 'S') and</p><p>(UpCase(ChOpcao) <> 'N') do ChOpcao := Readkey;</p><p>if UpCase(ChOpcao) = 'S' then</p><p>BooContinuaJogo := true</p><p>else</p><p>BooContinuaJogo := false;</p><p>end;</p><p>begin</p><p>CursorOff;</p><p>Instrucoes;</p><p>BooJogar := true;</p><p>New(Cobra);</p><p>Cobra^.Inicia;</p><p>LongIntPontos := 0;</p><p>ByteContaRatos := 10;</p><p>while BooJogar do</p><p>begin</p><p>Cenario;</p><p>Ratos(ByteContaRatos);</p><p>LongIntJogoPtos := Jogo;</p><p>if LongIntJogoPtos = 0 then</p><p>LongIntPontos := 0</p><p>else</p><p>LongIntPontos := LongIntPontos + LongIntJogoPtos;</p><p>BooJogar := BooContinuaJogo;</p><p>if BooJogar then</p><p>if LongIntPontos > 0 then</p><p>begin</p><p>if ByteContaRatos <= 240 then</p><p>begin</p><p>ByteContaRatos := ByteContaRatos + 10;</p><p>end</p><p>else</p><p>begin</p><p>Parabens;</p><p>ByteContaRatos := 10;</p><p>Cobra^.Reinicia;</p><p>end</p><p>end</p><p>else</p><p>begin</p><p>ByteContaRatos := 10;</p><p>Cobra^.Reinicia;</p><p>end;</p><p>end;</p><p>CursorOn;</p><p>end.</p><p>ANÁLISE DAS</p><p>ROTINAS</p><p>Nesta versão, o jogo da cobra foi implementado usando-se</p><p>dois objetos: a cobra (CobraObj) e seus segmentos (SegObj).</p><p>Vamos dissecar estes dois objetos para entender como funciona o</p><p>programa.</p><p>Vamos começar pelo objeto CobraObj e suas propriedades:</p><p>CobraObj - Propriedades</p><p>ByteX Coordenada X da cabeça da cobra</p><p>ByteY Coordenada Y da cabeça da cobra</p><p>ByteOldX Coordenada X anterior da cabeça da cobra (repas-</p><p>sada para o primeiro segmento)</p><p>ByteOldY Coordenada Y anterior da cabeça da cobra (repas-</p><p>sada para o primeiro segmento)</p><p>ByteIncremento Incremento que faz a cobra se mover</p><p>WordSegmentos Quantidade de segmentos da cobra</p><p>WordRedesenho Atraso temporal em milissegundos para controlar o</p><p>redesenho da cobra</p><p>CharDirecao Direção na qual a cabeça da cobra se move</p><p>BooColisao Registra a colisão entre os segmentos da cobra</p><p>PrimSegObj Primeiro segmento da cobra</p><p>UltSegObj Último segmento da cobra</p><p>PROGRAMAÇÃO - JOGOS 22</p><p>E agora seus métodos:</p><p>CobraObj - Métodos</p><p>Inicia Inicializa o objeto cobra</p><p>Reinicia Renicializa o objeto cobra</p><p>Desenha Desenha a cobra nas coorde-</p><p>nadas atuais</p><p>Move Move a cobra para as coorde-</p><p>nadas atuais considerando a</p><p>direção da mesma</p><p>AdSegmento Adiciona um segmento a cobra</p><p>SegObj - Propriedades</p><p>ByteX Coordenada X do segmento</p><p>ByteY Coordenada Y do segmento</p><p>ByteOldX Coordenada X anterior do seg-</p><p>mento (repassada para o primei-</p><p>ro segmento)</p><p>ByteOldY Coordenada Y anterior do seg-</p><p>mento (repassada para o primei-</p><p>ro segmento)</p><p>AntSegObj Segmento anterior</p><p>PrxSegObj Próximo segmento</p><p>Tela do Jogo da Cobra</p><p>O objeto SegObj é mais simples</p><p>ainda. Este objeto não passa de uma</p><p>aplicação de lista duplamente encadeada.</p><p>O método CobraObj.Inicia prepara o</p><p>objeto correspondente para rodar pela pri-</p><p>meira vez. Já o método CobraObj.Reinicia</p><p>inicializa o seu objeto após uma partida</p><p>realizada, onde, além de reiniciar as</p><p>propriedades do objeto CobraObj, ele</p><p>apaga qualquer segmento que tenha</p><p>sobrado da jogada anterior.</p><p>O método CobraObj.Desenha de-</p><p>senha a cabeça da cobra (representada</p><p>pelo caracter “@”) e todos os segmentos</p><p>dela (representados pelo caracter “O”). O</p><p>primeiro segmento é desenhado nas</p><p>coordenadas anteriores da cabeça. O</p><p>segundo segmento é desenhado nas coor-</p><p>denadas anteriores do primeiro e assim</p><p>sucessivamente. Um laço WHILE varre a</p><p>lista duplamente encadeada que representa</p><p>os segmentos da cobra. O método</p><p>CobraObj.Desenha é usado pelo método</p><p>CobraObj.Move , o qual mantem a cobra</p><p>em movimento incrementando ou decre-</p><p>mentando as coordenadas (ByteX e ByteY)</p><p>da cabeça da cobra. Este método também</p><p>mantém atualizadas as coordenadas</p><p>utilizadas anteriormente pela cabeça</p><p>(ByteOldX e ByteOldY), as quais são</p><p>repassadas aos segmentos. A variável</p><p>CharDirecao controla a direção da cabeça</p><p>da cobra, indicando como deve ser o</p><p>incremento ou decremento das coordena-</p><p>das desta. E por fim o tempo de redesenho</p><p>da cobra também é controlado aqui</p><p>(WordRedesenho), de modo que o jogo não</p><p>fique rápido demais para o usuário.</p><p>Agora que conhecemos todos os</p><p>objetos do programa, podemos analisar o</p><p>programa principal. Este é muito pequeno,</p><p>PROGRAMAÇÃO - JOGOS 23</p><p>englobando apenas 38 linhas de código.</p><p>Esta mágica deve muito ao código enca-</p><p>psulado nos objetos do programa, que</p><p>facilita a manipulação dos elementos ne-</p><p>cessários ao funcionamento do jogo.</p><p>O programa principal contem, logo</p><p>após uma breve inicialização de variáveis,</p><p>um laço que roda em seqüência, diversas</p><p>rotinas. A primeira é o procedimento cená-</p><p>rio. Em seguida o procedimento Ratos</p><p>coloca aleatoriamente os roedores na tela,</p><p>sempre tomando o cuidado para que</p><p>nenhum rato seja sobreposto a outro. Um</p><p>vetor bidimensional (VetRato) abrange toda</p><p>a área onde é possível aparecer um rato.</p><p>Uma vez inseridos todos os ratos a rodada</p><p>é iniciada pela função Jogo, que retorna</p><p>quantos pontos o jogador fez. Esta função</p><p>realiza o controle do teclado dentro de um</p><p>laço WHILE, usando duas funções bem</p><p>conhecidas no Turbo Pascal: Keypressed,</p><p>e Readkey. A primeira indica se alguma</p><p>tecla foi pressionada e a segunda verifica o</p><p>código desta tecla. Admito que estas</p><p>funções não são exatamente as melhores</p><p>opções para leitura do estado do teclado,</p><p>mas a portabilidade deste par é maior entre</p><p>os diversos compiladores que tomaram o</p><p>conjunto de instruções do Turbo Pascal. Se</p><p>você usa o Free Pascal então pode contar</p><p>com a unidade keyboard, a qual conta com</p><p>um amplo arsenal de rotinas para tratar os</p><p>eventos gerados pelo teclado, como</p><p>pressionamento de múltiplas teclas, uso de</p><p>combinações de teclas (SHIFT, ALT) etc.</p><p>Consulte o Run-Time Library (RTL): Refe-</p><p>rence guide para maiores detalhes.</p><p>Voltando ao código do jogo verificamos a</p><p>tecla pressionada e de acordo com a tecla</p><p>enviamos a cabeça da cobra para a</p><p>direção correta ou, dependendo do caso,</p><p>para o fim do jogo, se o jogador fizer um</p><p>movimento errado, por exemplo. Uma vez</p><p>tratado o teclado, se o jogador fizer o</p><p>movimento correto, então é verificado se a</p><p>cabeça da cobra passa por cima de algum</p><p>rato. Caso passe, este é eliminado do vetor</p><p>VetRato e um segmento é adicionado a</p><p>cobra, através do método AdSegmento, do</p><p>objeto CobraObj, alem de incrementar a</p><p>pontuação do jogador. Caso o jogador faça</p><p>um movimento errado ou apanhe todos os</p><p>ratos da tela, a rodada é finalizada e uma</p><p>tela questiona o jogador se deseja</p><p>continuar jogando.</p><p>A cada rodada o jogo incrementa o</p><p>número de ratos em dez, aumentando cada</p><p>vez mais a dificuldade do jogo, pois a cobra</p><p>vai ficando imensa e se torna um desafio</p><p>espetacular desviar das paredes do cenário</p><p>e dos segmentos da própria cobra. Bem no</p><p>estilo dos jogos do Atari VCS 2600.</p><p>Bem, espero que este código possa</p><p>ajudá-los como ponto de partida para o</p><p>mundo da orientação a objetos ou sirva de</p><p>exemplo de aplicação prática de lista</p><p>duplamente encadeada. Senão, pelo me-</p><p>nos, que possa diverti-los. █</p><p>PROGRAMAÇÃO - JOGOS 24</p><p>PEDRA,</p><p>PAPEL E</p><p>TESOURA</p><p>Um programa simples</p><p>que abusa de tipos e</p><p>conjuntos (sets) que</p><p>tornam Pascal a mais</p><p>elegante das</p><p>linguagens.</p><p>Por Ericson Benjamim</p><p>O jogo Pedra, Papel e Tesoura</p><p>(conhecido também como Jankenpo) não é</p><p>tradicional no Brasil mas é um ótimo</p><p>exemplo para exibir as características mais</p><p>elegantes da linguagem Pascal. Nesta</p><p>versão o programa não incorpora os</p><p>recursos avançados dos últimos compila-</p><p>dores Pascal. Ao contrário, ele usa</p><p>recursos simples, encontrados na maioria</p><p>dos compiladores já criados. Ele foi testado</p><p>no Turbo Pascal 5.5 e no Free Pascal 2.0.4</p><p>com sucesso e deve funcionar muito bem</p><p>em outros compiladores como o GNU</p><p>Pascal, praticamente sem nenhuma</p><p>alteração.</p><p>COMO FUNCIONA</p><p>Acredito que todos devam conhecer</p><p>as regras do jogo. Vou explicar</p><p>rapidamente: papel vence pedra, pedra</p><p>vence tesoura e tesoura vence papel. Mais</p><p>detalhes na referência bibliográfica do final</p><p>deste artigo. Como podem ver a</p><p>probabilidade de ganhar é de exatamente</p><p>50 por cento para cada jogador. Mas na</p><p>prática um jogador humano não é o ideal</p><p>de aleatoriedade nas jogadas executadas.</p><p>Isto porque a mente humana é um péssimo</p><p>gerador de comportamento randômico e</p><p>tende a seguir, mesmo subconscientemen-</p><p>te, um padrão rastreável (na maioria das</p><p>vezes). O computador avalia um possível</p><p>padrão criado pelo jogador humano nas</p><p>últimas cinco jogadas e a partir desse tenta</p><p>prever as suas jogadas, aumentando ainda</p><p>mais a possibilidade de ganhar. O</p><p>vencedor será aquele que ganhar 50</p><p>rodadas. O histórico do jogo é armazenado</p><p>em um simples vetor bidimensional, que</p><p>grava cada jogada dos participantes,</p><p>computador e humano. O programa abusa</p><p>de estruturas que tornaram a linguagem</p><p>Pascal muito</p><p>elegante: conjuntos (sets) e</p><p>pode servir de exemplo para iniciantes,</p><p>mostrando como é fácil criar e fazer uso</p><p>Houve um empate nesta rodada</p><p>* * * Pontuacao * * *</p><p>Computador: 11</p><p>Humano: 6</p><p>---------------</p><p>Empate(s): 9</p><p>Qual eh sua jogada: pEdra, Papel ou Tesoura? e</p><p>Voce escolheu Pedra</p><p>Eu escolhi Papel</p><p>Papel vence Pedra</p><p>* * * Pontuacao * * *</p><p>Computador: 12</p><p>Humano: 6</p><p>---------------</p><p>Empate(s): 9</p><p>Qual eh sua jogada: pEdra, Papel ou Tesoura?</p><p>destas estruturas, além de funções e</p><p>procedimentos.</p><p>PROGRAMAÇÃO - JOGOS 25</p><p>program Pedra_Papel_e_Tesoura;</p><p>{</p><p>Jogo Pedra, Papel e Tesoura</p><p>Adaptado do original de Bob Mackay</p><p>Practical Computing, setembro/1983</p><p>por Ericson Benjamim, maio/2007</p><p>ericsonbenjamim arroba yahoo ponto com ponto br</p><p>}</p><p>type</p><p>Objeto = (Pedra, Papel, Tesoura);</p><p>Jogador = (Computador, Humano);</p><p>const</p><p>{ maior valor da sequencia a procurar }</p><p>ComprimentoMaximo = 5;</p><p>var</p><p>{ Registro de todas as rodadas }</p><p>Historico: Array [Computador..Humano, 1..100] of Objeto;</p><p>{ Pontuacao dos Jogadores }</p><p>Pontos: Array [Computador..Humano] of Integer;</p><p>{ Minha Jogada, sua reposta}</p><p>Jogada, Resposta: Objeto;</p><p>{ Totais das jogadas usuais da sequencia mais recente }</p><p>TotPedra, TotPapel, TotTesoura, TotEmpate: Integer;</p><p>{ Variaveis de controle }</p><p>Comprimento, SemRodadas: Integer;</p><p>Decidido: Boolean;</p><p>NomeObjeto: Array[Pedra..Tesoura] of String;</p><p>procedure MessagemIntroducao;</p><p>{ Exibe a mensagem de introducao }</p><p>begin</p><p>writeln('Este programa roda o jogo Pedra, Papel e Tesoura.');</p><p>writeln;</p><p>writeln('Cada um de nos deve pensar em um dos tres objetos.');</p><p>writeln;</p><p>writeln('A regra eh que tesoura vence papel, papel vence');</p><p>writeln('pedra e pedra vence tesoura!');</p><p>writeln;</p><p>writeln('Eu aposto que consigo vencer voce no maximo em 50 rodadas.');</p><p>writeln;</p><p>writeln('Eu ja fiz a minha escolha. Pressione ENTER quando voce');</p><p>writeln('tiver feito a sua.');</p><p>writeln;</p><p>writeln;</p><p>end;</p><p>procedure ExibeMinhaJogada;</p><p>{ Informa ao jogador sobre minha jogada }</p><p>begin</p><p>writeln('Eu escolhi ', NomeObjeto[Jogada]);</p><p>writeln;</p><p>end;</p><p>procedure RecebeResposta;</p><p>{ Recebe a resposta do jogador }</p><p>var</p><p>RespostaJogador: char;</p><p>OK: Boolean;</p><p>begin</p><p>repeat</p><p>OK := true;</p><p>write('Qual eh sua jogada: pEdra, Papel ou Tesoura? ');</p><p>readln(RespostaJogador);</p><p>case RespostaJogador of</p><p>'e', 'E': Resposta := Pedra;</p><p>'p', 'P': Resposta := Papel;</p><p>'t', 'T': Resposta := Tesoura;</p><p>else OK := false;</p><p>end;</p><p>until OK;</p><p>writeln;</p><p>writeln('Voce escolheu ', NomeObjeto[Resposta]);</p><p>end;</p><p>procedure ExibePontuacao;</p><p>{ Exibe a pontuacao }</p><p>begin</p><p>writeln('* * * Pontuacao * * *');</p><p>writeln;</p><p>writeln('Computador: ', Pontos[Computador]);</p><p>writeln('Humano: ', Pontos[Humano]);</p><p>writeln('---------------');</p><p>writeln('Empate(s): ', TotEmpate);</p><p>writeln;</p><p>end;</p><p>procedure MensagemVitoria;</p><p>{ Anuncia quem ganhou }</p><p>begin</p><p>write('Parece que ');</p><p>if Pontos[Computador] > Pontos[Humano] then</p><p>writeln('eu, o Computador, ganhei!')</p><p>else</p><p>if Pontos[Computador] = Pontos[Humano] then</p><p>writeln('houve um empate!')</p><p>else</p><p>writeln('você, Humano, ganhou!');</p><p>writeln('Obrigado por jogar.');</p><p>end;</p><p>PROGRAMAÇÃO - JOGOS 26</p><p>function JogadaAleatoria: Objeto;</p><p>{</p><p>Esta funcao eh chamada quando um numero</p><p>particular de um padrao eh detectado.</p><p>Um objeto aleatorio eh retornado.</p><p>}</p><p>begin</p><p>{</p><p>"RANDOM(253) + 3" deve retornar um</p><p>inteiro aleatorio entre 3 e 255</p><p>}</p><p>case ((RANDOM(253) + 3) MOD 3) of</p><p>0: JogadaAleatoria := Pedra;</p><p>1: JogadaAleatoria := Papel;</p><p>2: JogadaAleatoria := Tesoura;</p><p>end;</p><p>end;</p><p>function EscolheJogada: Objeto;</p><p>{</p><p>Ve se alguma resposta tem a maioridade</p><p>limpa e escolhe a correspondente jogada</p><p>}</p><p>begin</p><p>Decidido := true;</p><p>if (TotPapel > TotTesoura) and</p><p>(TotPapel > TotPedra)</p><p>then EscolheJogada := Tesoura</p><p>else</p><p>if (TotTesoura > TotPapel) and</p><p>(TotTesoura > TotPedra)</p><p>then EscolheJogada := Pedra</p><p>else</p><p>if (TotPedra > TotPapel) and</p><p>(TotPedra > TotTesoura)</p><p>then EscolheJogada := Papel</p><p>else</p><p>begin</p><p>EscolheJogada := JogadaAleatoria;</p><p>Decidido := false;</p><p>end;</p><p>end;</p><p>function Combina(X, Y, Comprimento: Integer): Boolean;</p><p>{</p><p>Compara as sequencias historicas em</p><p>X e Y sobre o comprimento informado</p><p>}</p><p>var</p><p>I: Integer;</p><p>begin</p><p>I := 0;</p><p>while</p><p>(I < Comprimento) and</p><p>(Historico[Computador, X + 1] = Historico[Computador, Y + 1]) and</p><p>(Historico[Humano, X + 1] = Historico[Humano, Y + 1])</p><p>do</p><p>I := I + 1;</p><p>Combina := (I = Comprimento);</p><p>end;</p><p>procedure Procura(Comprimento: Integer);</p><p>{</p><p>Procura pela sua proxima jogada apos cada</p><p>combinacao bem sucedida de comprimento espeficado</p><p>}</p><p>var</p><p>B, T: Integer;</p><p>begin</p><p>TotPedra := 0;</p><p>TotPapel := 0;</p><p>TotTesoura := 0;</p><p>{ Ultima Sequencia }</p><p>T := SemRodadas - Comprimento;</p><p>{ Para cada sequencia mais proxima do inicio faca }</p><p>for B := 1 to T - 1 do</p><p>if Combina(B, T, Comprimento) then</p><p>{ Grava a proxima resposta executada }</p><p>case Historico[Humano, B + Comprimento] of</p><p>Pedra : TotPedra := TotPedra + 1;</p><p>Papel : TotPapel := TotPapel + 1;</p><p>Tesoura: TotTesoura := TotTesoura + 1;</p><p>end;</p><p>end;</p><p>procedure AtualizaPontuacao;</p><p>{ Decide quem ganhou nesta rodada }</p><p>var PontosAnteriores: Array [Computador..Humano] of Integer;</p><p>begin</p><p>PontosAnteriores[Humano] := Pontos[Humano];</p><p>PontosAnteriores[Computador] := Pontos[Computador];</p><p>case Jogada of</p><p>Pedra:</p><p>case Resposta of</p><p>Pedra : TotEmpate := TotEmpate + 1;</p><p>Papel : Pontos[Humano] := Pontos[Humano] + 1;</p><p>Tesoura: Pontos[Computador] := Pontos[Computador] + 1;</p><p>end;</p><p>Papel:</p><p>case Resposta of</p><p>Pedra : Pontos[Computador] := Pontos[Computador] + 1;</p><p>Papel : TotEmpate := TotEmpate + 1;</p><p>Tesoura: Pontos[Humano] := Pontos[Humano] + 1;</p><p>end;</p><p>Tesoura:</p><p>case Resposta of</p><p>Pedra : Pontos[Humano] := Pontos[Humano] + 1;</p><p>Papel : Pontos[Computador] := Pontos[Computador] + 1;</p><p>PROGRAMAÇÃO - JOGOS 27</p><p>Tesoura: TotEmpate := TotEmpate + 1;</p><p>end;</p><p>end;</p><p>if Pontos[Humano] > PontosAnteriores[Humano] then</p><p>writeln(NomeObjeto[Resposta], ' vence ', NomeObjeto[Jogada])</p><p>else</p><p>if Pontos[Computador] > PontosAnteriores[Computador] then</p><p>writeln(NomeObjeto[Jogada], ' vence ', NomeObjeto[Resposta])</p><p>else</p><p>writeln('Houve um empate nesta rodada');</p><p>writeln;</p><p>end;</p><p>function PontuacaoNecessaria: Boolean;</p><p>{ Avalia condicoes para terminar o jogo }</p><p>begin</p><p>PontuacaoNecessaria := ((Pontos[Computador] >= 50) or</p><p>(Pontos[Humano] >= 50)) and</p><p>(ABS(Pontos[Computador] - Pontos[Humano]) > 1);</p><p>end;</p><p>begin</p><p>{ Programa principal }</p><p>MessagemIntroducao;</p><p>NomeObjeto[Pedra] := 'Pedra';</p><p>NomeObjeto[Papel] := 'Papel';</p><p>NomeObjeto[Tesoura] := 'Tesoura';</p><p>TotEmpate := 0;</p><p>SemRodadas := 0;</p><p>Pontos[Computador] := 0;</p><p>Pontos[Humano] := 0;</p><p>write('Pronto?');</p><p>readln;</p><p>writeln;</p><p>repeat</p><p>SemRodadas := SemRodadas + 1;</p><p>Comprimento := ComprimentoMaximo;</p><p>Decidido := false;</p><p>repeat</p><p>Procura(Comprimento);</p><p>Jogada := EscolheJogada;</p><p>Comprimento := Comprimento - 1;</p><p>until (Decidido) or (Comprimento = 0);</p><p>RecebeResposta;</p><p>ExibeMinhaJogada;</p><p>Historico[Computador, SemRodadas] := Jogada;</p><p>Historico[Humano, SemRodadas] := Resposta;</p><p>AtualizaPontuacao;</p><p>ExibePontuacao;</p><p>until PontuacaoNecessaria;</p><p>MensagemVitoria;</p><p>end.</p><p>E que tal conferir a versão para Lazarus? Para construir</p><p>uma aplicação realmente gráfica é necessário fazer alguns ajustes</p><p>no programa anterior e adequar as rotinas pelos eventos dos</p><p>componentes visuais. Apesar de transformar as rotinas em parte</p><p>integrante do form, este programa não foi escrito à luz da</p><p>orientação a objeto. Ele deve funcionar bem em qualquer versão</p><p>do Lazarus (Linux, Mac OS X ou Windows), bem como no</p><p>Delphi</p><p>também.</p><p>Vamos lá! Primeiro, utilizando a IDE do Lazarus, desenhe o</p><p>form abaixo:</p><p>Não se preocupe com a posição exata dos componentes, o</p><p>código vai cuidar disto. Mas cuide para que os componentes</p><p>tenham o mesmo nome dos que estão no form acima.</p><p>Primeiro vamos às rotinas específicas do jogo. Antes de</p><p>inserir qualquer evento deixe o código inicial do projeto da</p><p>seguinte maneira:</p><p>PROGRAMAÇÃO - JOGOS 28</p><p>unit PedraPapelTesoura_Unit1;</p><p>{$mode objfpc}{$H+}</p><p>{Acrescenta icone ao programa}</p><p>{$R tesouraicone.res}</p><p>interface</p><p>uses</p><p>Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,</p><p>ExtCtrls,</p><p>StdCtrls, Buttons;</p><p>type</p><p>Objeto = (Pedra, Papel, Tesoura);</p><p>Jogador = (Computador, Humano);</p><p>{ TForm1 }</p><p>TForm1 = class(TForm)</p><p>Button1: TButton;</p><p>Button2: TButton;</p><p>Image1: TImage;</p><p>Image2: TImage;</p><p>Image3: TImage;</p><p>Image4: TImage;</p><p>Image5: TImage;</p><p>Label1: TLabel;</p><p>Label2: TLabel;</p><p>Label3: TLabel;</p><p>Label4: TLabel;</p><p>Label5: TLabel;</p><p>Label6: TLabel;</p><p>Memo1: TMemo;</p><p>procedure Button1Click(Sender: TObject);</p><p>procedure Button2Click(Sender: TObject);</p><p>procedure FormCreate(Sender: TObject);</p><p>procedure Image3Click(Sender: TObject);</p><p>procedure Image4Click(Sender: TObject);</p><p>procedure Image5Click(Sender: TObject);</p><p>private</p><p>{ private declarations }</p><p>procedure MessagemIntroducao;</p><p>procedure ExibeMinhaJogada;</p><p>procedure RecebeResposta;</p><p>procedure ExibePontuacao;</p><p>procedure MensagemVitoria;</p><p>function JogadaAleatoria: Objeto;</p><p>function EscolheJogada: Objeto;</p><p>function Combina(X, Y, Comprimento: Integer): Boolean;</p><p>procedure Procura(Comprimento: Integer);</p><p>procedure AtualizaPontuacao;</p><p>function PontuacaoNecessaria: Boolean;</p><p>procedure RodaJogo;</p><p>procedure ImagemEscolha(ObjetoEscolhido: Objeto);</p><p>public</p><p>{ public declarations }</p><p>end;</p><p>const</p><p>{ maior valor da sequencia a procurar }</p><p>ComprimentoMaximo = 5;</p><p>var</p><p>Form1: TForm1;</p><p>{ Registro de todas as rodadas }</p><p>Historico: Array [Computador..Humano, 1..100] of Objeto;</p><p>{ Pontuacao dos Jogadores }</p><p>Pontos: Array [Computador..Humano] of Integer;</p><p>{ Minha Jogada, sua reposta}</p><p>Jogada, Resposta: Objeto;</p><p>{ Totais das jogadas usuais da sequencia mais recente }</p><p>TotPedra, TotPapel, TotTesoura, TotEmpate: Integer;</p><p>{ Variaveis de controle }</p><p>Comprimento, SemRodadas: Integer;</p><p>Decidido, FimDeJogo: Boolean;</p><p>NomeObjeto: Array[Pedra..Tesoura] of String;</p><p>implementation</p><p>{ TForm1 }</p><p>procedure TForm1.MessagemIntroducao;</p><p>{ Exibe a mensagem de introducao }</p><p>begin</p><p>Memo1.Clear;</p><p>Memo1.Lines.Add('Este programa roda o jogo Pedra, Papel e Tesoura. ' +</p><p>'Cada um de nós deve pensar em um dos três objetos.');</p><p>Memo1.Lines.Add('');</p><p>Memo1.Lines.Add('A regra é que tesoura vence papel, papel vence ' +</p><p>'pedra e pedra vence tesoura! Eu aposto que consigo');</p><p>Memo1.Lines.Add('vencer voce no máximo em 50 rodadas.');</p><p>Memo1.Lines.Add('');</p><p>Memo1.Lines.Add('Eu já fiz minha escolha. Clique em uma das três ' +</p><p>'imagens abaixo para fazer a sua.');</p><p>Memo1.Lines.Add('Qual é sua jogada: Pedra, Papel ou Tesoura? ');</p><p>Image1.Picture.Clear;</p><p>Image2.Picture.Clear;</p><p>Label2.Caption := '0 ponto';</p><p>Label4.Caption := '0 ponto';</p><p>Label6.Caption := '0';</p><p>PROGRAMAÇÃO - JOGOS 29</p><p>TotEmpate := 0;</p><p>SemRodadas := 0;</p><p>Pontos[Computador] := 0;</p><p>Pontos[Humano] := 0;</p><p>FimDeJogo := false;</p><p>end;</p><p>procedure TForm1.ExibeMinhaJogada;</p><p>{ Informa ao jogador sobre minha jogada }</p><p>begin</p><p>Memo1.Lines.Add('Eu escolhi ' + NomeObjeto[Jogada] + '.');</p><p>Memo1.Lines.Add('');</p><p>end;</p><p>procedure TForm1.RecebeResposta;</p><p>{ Recebe a resposta do jogador }</p><p>begin</p><p>Memo1.Lines.Add('Qual eh sua jogada: Pedra, Papel ou Tesoura? ');</p><p>Memo1.Lines.Add('');</p><p>end;</p><p>procedure TForm1.ExibePontuacao;</p><p>{ Exibe a pontuacao }</p><p>begin</p><p>Label2.Caption := IntToStr(Pontos[Computador]) + ' ponto';</p><p>if Pontos[Computador] > 1 then Label2.Caption := Label2.Caption + 's';</p><p>Label4.Caption := IntToStr(Pontos[Humano]) + ' ponto';</p><p>if Pontos[Humano] > 1 then Label4.Caption := Label4.Caption + 's';</p><p>Label6.Caption := IntToStr(TotEmpate);</p><p>end;</p><p>procedure TForm1.MensagemVitoria;</p><p>{ Anuncia quem ganhou }</p><p>var</p><p>StrJogador: String;</p><p>begin</p><p>if Pontos[Computador] > Pontos[Humano] then</p><p>StrJogador := 'eu, o Computador, ganhei!'</p><p>else</p><p>if Pontos[Computador] = Pontos[Humano] then</p><p>StrJogador := 'houve um empate!'</p><p>else</p><p>StrJogador := 'você, Humano, ganhou!';</p><p>Memo1.Lines.Add('Parece que ' + StrJogador);</p><p>Memo1.Lines.Add('');</p><p>Memo1.Lines.Add('Obrigado por jogar.');</p><p>FimDeJogo := true;</p><p>end;</p><p>function TForm1.JogadaAleatoria: Objeto;</p><p>{ Esta funcao eh chamada quando um numero</p><p>particular de um padrao eh detectado.</p><p>Um objeto aleatorio eh retornado.}</p><p>begin</p><p>{</p><p>"RANDOM(253) + 3" deve retornar um</p><p>inteiro aleatorio entre 3 e 255</p><p>}</p><p>case ((RANDOM(253) + 3) MOD 3) of</p><p>0: JogadaAleatoria := Pedra;</p><p>1: JogadaAleatoria := Papel;</p><p>2: JogadaAleatoria := Tesoura;</p><p>end;</p><p>end;</p><p>function TForm1.EscolheJogada: Objeto;</p><p>{</p><p>Ve se alguma resposta tem a maioridade</p><p>limpa e escolhe a correspondente jogada</p><p>}</p><p>begin</p><p>Decidido := true;</p><p>if (TotPapel > TotTesoura) and</p><p>(TotPapel > TotPedra)</p><p>then EscolheJogada := Tesoura</p><p>else</p><p>if (TotTesoura > TotPapel) and</p><p>(TotTesoura > TotPedra)</p><p>then EscolheJogada := Pedra</p><p>else</p><p>if (TotPedra > TotPapel) and</p><p>(TotPedra > TotTesoura)</p><p>then EscolheJogada := Papel</p><p>else</p><p>begin</p><p>EscolheJogada := JogadaAleatoria;</p><p>Decidido := false;</p><p>end;</p><p>case EscolheJogada of</p><p>Pedra: Image1.Picture.LoadFromFile('pedra.xpm');</p><p>Papel: Image1.Picture.LoadFromFile('papel.xpm');</p><p>Tesoura: Image1.Picture.LoadFromFile('tesoura.xpm');</p><p>end;</p><p>end;</p><p>function TForm1.Combina(X, Y, Comprimento: Integer): Boolean;</p><p>{</p><p>Compara as sequencias historicas em</p><p>X e Y sobre o comprimento informado</p><p>}</p><p>var</p><p>I: Integer;</p><p>begin</p><p>I := 0;</p><p>while</p><p>(I < Comprimento) and</p><p>(Historico[Computador, X + 1] = Historico[Computador, Y + 1]) and</p><p>(Historico[Humano, X + 1] = Historico[Humano, Y + 1])</p><p>PROGRAMAÇÃO - JOGOS 30</p><p>do</p><p>I := I + 1;</p><p>Combina := (I = Comprimento);</p><p>end;</p><p>procedure TForm1.Procura(Comprimento: Integer);</p><p>{</p><p>Procura pela sua proxima jogada apos cada</p><p>combinacao bem sucedida de comprimento espeficado</p><p>}</p><p>var</p><p>B, T: Integer;</p><p>begin</p><p>TotPedra := 0;</p><p>TotPapel := 0;</p><p>TotTesoura := 0;</p><p>{ Ultima Sequencia }</p><p>T := SemRodadas - Comprimento;</p><p>{ Para cada sequencia mais proxima do inicio faca }</p><p>for B := 1 to T - 1 do</p><p>if Combina(B, T, Comprimento) then</p><p>{ Grava a proxima resposta executada }</p><p>case Historico[Humano, B + Comprimento] of</p><p>Pedra : TotPedra := TotPedra + 1;</p><p>Papel : TotPapel := TotPapel + 1;</p><p>Tesoura: TotTesoura := TotTesoura + 1;</p><p>end;</p><p>end;</p><p>procedure TForm1.AtualizaPontuacao;</p><p>{ Decide quem ganhou nesta rodada }</p><p>var PontosAnteriores: Array [Computador..Humano] of Integer;</p><p>begin</p><p>PontosAnteriores[Humano] := Pontos[Humano];</p><p>PontosAnteriores[Computador] := Pontos[Computador];</p><p>case Jogada of</p><p>Pedra:</p><p>case Resposta of</p><p>Pedra : TotEmpate := TotEmpate + 1;</p><p>Papel : Pontos[Humano] := Pontos[Humano] + 1;</p><p>Tesoura: Pontos[Computador] := Pontos[Computador] + 1;</p><p>end;</p><p>Papel:</p><p>case Resposta of</p><p>Pedra : Pontos[Computador] := Pontos[Computador] + 1;</p><p>Papel : TotEmpate := TotEmpate + 1;</p><p>Tesoura: Pontos[Humano] := Pontos[Humano] + 1;</p><p>end;</p><p>Tesoura:</p><p>case Resposta of</p><p>Pedra : Pontos[Humano] := Pontos[Humano] + 1;</p><p>Papel : Pontos[Computador] := Pontos[Computador] + 1;</p><p>Tesoura: TotEmpate := TotEmpate + 1;</p><p>end;</p><p>end;</p><p>if Pontos[Humano] > PontosAnteriores[Humano] then</p><p>Memo1.Lines.Add(NomeObjeto[Resposta] + ' vence ' +</p><p>NomeObjeto[Jogada] + '.')</p><p>else</p><p>if Pontos[Computador] > PontosAnteriores[Computador]</p>

Mais conteúdos dessa disciplina