08/10/2008 Programação II Primeiro Trabalho Prof.: Flávio Miguel Varejão Leia atentamente TODO o enunciado do trabalho (a especificação do problema e os detalhes sobre a confecção, submissão e avaliação do trabalho). Uma leitura inapropriada do enunciado pode ser extremamente danosa a sua nota. A Jogos de Sorte Ltda., uma empresa que desenvolve jogos computacionais, te contratou para fazer um programa em C que implemente um jogo de cartas conhecido como 21 (também chamado de blackjack). Os participantes do jogo são o jogador (representado pelo usuário do programa) e a banca (representada pelo programa computacional). Inicialmente o jogador recebe 1000 pontos. Em cada rodada, ele pode apostar a quantidade de pontos que quiser (limitado apenas pela quantidade de pontos que tiver no momento da aposta). Se o jogador vence, recebe os pontos que apostou em dobro; se ele perde, perde os pontos que apostou. O jogo se encerra quando: (a) o jogador decide parar de jogar; (b) o jogador não tem mais pontos para apostar; ou (c) quando o jogador quebra a banca (isto é, o jogador atinge 10.000 ou mais pontos). Neste jogo de cartas se utilizam 52 cartas do baralho excluindo as cartas coringa. São utilizadas as cartas Ás (representada pelo número 1), 2 a 10 (representadas pelo próprio valor), Valete (representada pelo número 11), Dama (representada pelo número 12) e Rei (representada pelo número 13) nos quatro naipes (Ouros, Paus, Copas e Espadas). No jogo de 21, as cartas numéricas valem o seu próprio número (por exemplo, a carta 7 tem valor 7); as cartas Valete, Dama e Rei valem sempre 10 e a carta Ás vale 1 ou 11, dependendo da situação do jogo. O objetivo do jogo é formar um conjunto de cartas cujos valores somados se aproximem ao máximo de 21. Jogador e banca têm oportunidade de juntar cartas em cada rodada. Quem formar um conjunto de cartas mais próximo de 21 vence. A banca sempre joga depois do jogador, ou seja, em uma rodada, a banca só começa a jogar depois que o jogador completou a seleção de todas as suas cartas. A banca sempre tenta atingir um valor mais próximo de 21. Se conseguir, ela vence. No entanto, se juntar um conjunto de cartas cujo valor supere 21, ela perde. Em dois casos a banca não chega a jogar em uma rodada: (a) quando o conjunto formado pelo jogador excede a 21 neste caso, a banca vence a rodada sem jogar; e (b) quando o conjunto formado pelo jogador vale exatamente 21 neste caso, a banca perde a rodada sem jogar. No início de cada rodada, o jogador deve cortar o baralho (isto é escolher um número inteiro no intervalo entre 1 e 52). Este número é importante pois determinará a sequência de cartas selecionadas. A partir daí o jogador começa a jogar retirando cartas do baralho e acumulando valores. Após retirar uma carta o jogador pode encerrar sua jogada mantendo os valores acumulados. Se ao retirar uma carta, os valores acumulados superam 21, ele perde a rodada. Ao fim da jogada do jogador, a banca começa a jogar retirando cartas do baralho. A banca encerra sua jogada quando acumula valores superiores aos obtidos pelo
jogador (neste caso, a banca vence a rodada) ou quando os valores acumulados superam 21 (neste caso, a banca perde a rodada). O Ás é uma carta especial porque inicialmente o seu valor é considerado como 11. No entanto, se o conjunto de cartas que contém o Ás excede 21, o valor do Ás passa a ser considerado 1. Por exemplo, considere a seguinte seqüência de cartas recebidas pelo jogador: 2 3 Ás 2 7 Ás 5. Quando o jogador recebe o primeiro Ás, ele recebe 11 pontos, acumulando 16 (2 + 3 + 11 = 16) no total. Em seguida, ele recebe a carta 2 e depois a carta 7, estourando o limite de 21 (2 + 3 + 11 + 2 + 7 = 25). Como a carta Ás também pode valer 1, o total acumulado deve ser corrigido substituindo o valor 11 pelo valor 1. Assim, o novo total acumulado passa a ser 15 (2 + 3 + 1 + 2 + 7 = 15). Ao pedir nova carta, ele recebe um novo Ás. O novo total passa a ser 26 (2 + 3 + 1 + 2 + 7 + 11 = 26). Como novamente o total ultrapassa 21, o valor do novo Ás deve ser corrigido para 1, passando o total acumulado para 16 (2 + 3 + 1 + 2 + 7 + 1 = 16). O jogador pede nova carta e recebe um 5, totalizando 21 (2 + 3 + 1 + 2 + 7 + 1 + 5 = 21) e vencendo a rodada. No jogo de 21 com um único baralho, como é o nosso caso, em uma rodada, uma carta só pode ser repetida 4 vezes (por exemplo, podem ser sorteados o 2 de ouros, o 2 de paus, o 2 de copas e o 2 de espadas). Para simplificar a implementação do programa, em geral, não será necessário assegurar que isso ocorra (isto é, no nosso jogo pode ocorrer que, em uma rodada, sejam retirados mais que quatro cartas 2, por exemplo). A única exceção a essa regra é a carta Ás, que tem de ser restrita a um máximo de quatro ases em cada rodada. Em caso de serem retirados mais de quatro ases em uma rodada, os ases excedentes devem ser desconsiderados e uma nova carta deve ser retirada do baralho. Neste caso, a substituição deve ser transparente ao usuário (isto é, não deve ser mostrada na interface de execução que o ás foi escolhido, apenas deve aparecer a carta que foi escolhida em substituição). O processo de retirada de carta do baralho funcionará da seguinte maneira: o valor escolhido para corte do baralho (entre 1 e 52), chamado de n, será usado como parâmetro de entrada para a função srand, responsável por gerar uma sequência de números, baseada no valor inicial de n. Para cada valor diferente de n, a função srand irá gerar uma sequência diferente de valores. Assim, para a geração de cada sequência de cartas de uma rodada, o seguinte trecho de código deveria ser inserido no seu programa: printf("corte o baralho (forneca um valor entre 1 e 52): "); scanf("%d", &n); srand(n); Em seguida, usa-se a função rand para escolher aleatoriamente um número desta seqüência, representando a escolha de uma carta de forma aleatória, dentre todas as disponíveis na jogada.. Desta forma, para gerar um valor aleatório entre 1 e 13 (representando os 13 diferentes tipos de cartas do baralho), deve-se inserir no seu programa o seguinte trecho de código: c = rand()%13 + 1; De acordo com a carta escolhida, deve-se calcular o número de pontos correspondente, seguindo as regras de pontuação já descritas. Esse procedimento deve ser repetido enquanto forem retiradas cartas em uma rodada. Na rodada seguinte, deve ser feito um novo corte do baralho e o processo se repete. Saiba que as funções srand e rand pertencem a biblioteca padrão do C stdlib.h.
Seu programa deve tratar ainda as seguintes condições de entrada de dados: 1. Se o valor da aposta está no intervalo entre 1 e o total de pontos disponível pelo jogador. 2. Se o valor de corte está no intervalo entre 1 e 52. 3. Se a resposta à pergunta de retirada de carta é o caractere 's' ou S ou 'n' ou N. 4. Se a resposta à pergunta de continuação do jogo é o caractere 's' ou S ou 'n' ou N. Sempre que alguma dessas condições não for satisfeita o jogador deve ser avisado do seu erro e deve poder repetir a entrada de dados. Para uniformidade dos trabalhos e facilidade de correção, os dados devem ser fornecidos pelo usuário na seguinte ordem: <aposta do jogador> <corte do baralho> <respostas sobre novas cartas do jogador> <resposta sobre nova rodada do jogo> Lembre-se de levar em conta que, para cada dado fornecido pelo usuário, é preciso verificar se a resposta é válida. Em caso negativo, um novo dado do mesmo tipo deve ser fornecido pelo usuário naquele instante da execução. Apresenta-se, a seguir, um exemplo ilustrativo fictício de entrada de dados do programa. O exemplo é fictício porque as cartas não foram geradas usando as funções rand e srand, como deve ser feito no seu programa. Logo, se você tentar executar o seu programa com os dados deste exemplo, os resultados obtidos não serão os mesmos (de fato, é muito provável que a seqüência de dados fornecidos não possa ser essa). Seguem os dados: 100 37 s n s 1300 300 13 s n n Para esse exemplo, a execução do programa geraria a seguinte saída no terminal: Jogo de 21 Sua aposta (forneca um valor entre 1 e 1000): 100 Corte o baralho (forneca um valor entre 1 e 52): 37 A sua primeira carta e 7 (pontos acumulados = 7) Retirar uma carta (s/n)? s A sua nova carta e Valete (pontos acumulados = 17) Retirar uma carta (s/n)? n Pontos na rodada do jogador = 17 Primeira carta da banca e 3 (pontos acumulados = 3) Nova carta da banca e As (pontos acumulados = 14) Nova carta da banca e 6 (pontos acumulados = 20) Pontos na rodada da banca = 20 A banca vence!!! Pontos do jogador = 900 Deseja continuar (s/n)? s Sua aposta (forneca um valor entre 1 e 900): 1300 Valor indisponivel. Corrija a aposta!!! Sua aposta (forneca um valor entre 1 e 900): 300 Corte o baralho (forneca um valor entre 1 e 52): 13 A sua primeira carta e 10 (pontos acumulados = 10)
Retirar uma carta (s/n)? s A sua nova carta e 8 (pontos acumulados = 18) Retirar uma carta (s/n)? n Pontos na rodada do jogador = 18 Primeira carta da banca e 9 (pontos acumulados = 9) Nova carta da banca e 4 (pontos acumulados = 13) Nova carta da banca e As (pontos acumulados = 14) Nova carta da banca e Dama (pontos acumulados = 24) Pontos na rodada da banca = 24 A banca perde!!! Pontos do jogador = 1200 Deseja continuar (s/n)? n Pontos finais do jogador = 1200 Obrigado por jogar 21. Ate a proxima. Em caso de dúvidas sobre como funciona esse jogo, é possível ter uma noção jogando em http://www.jogosweb.net/jogos_online/207/21.html. Note que essa versão do jogo não é exatamente igual a que você deve implementar, mas serve para o propósito de orientá-lo inicialmente sobre como é o jogo de 21. Data de Entrega: O trabalho deverá ser entregue até às 23:59 horas do dia 30/10/2008 (quinta-feira). Forma de Entrega: 1. Compacte o arquivos texto (o nome do arquivo DEVE ser blackjack.c) com o código fonte do programa do seu trabalho e envie o arquivo compactado para o e-mail flaviovarejao@yahoo.com.br. 2. O assunto do e-mail deverá ser o seguinte (somente o que está entre aspas duplas): "prog2:trab1:nome:". Substitua nome pelo seu primeiro nome e último sobrenome, separados por espaços. 3. Compacte o arquivo fonte utilizando o formato.tar.gz e envie o arquivo compactado em anexo. Para isso, execute o seguinte comando no terminal, no diretório onde estiver o seu trabalho: tar -zcvf trab1.tar.gz * O arquivo trab1.tar.gz deverá conter apenas o arquivo com o código fonte do programa de seu trabalho (não pode ter arquivos.o ou executáveis ou qualquer outro arquivo). 4. Siga as instruções à risca pois algum erro na submissão pode inviabilizar a entrega do seu trabalho. Não deixe para enviar seu trabalho nos momentos finais de seu prazo. É comum a ocorrência de problemas em virtude de erros na submissão. Logo, enviem com algumas horas de antecedência para que haja tempo hábil para eventuais correções.
Veja abaixo um exemplo de um e-mail de envio do trabalho: Para: flaviovarejao@yahoo.com.br De: Joao da Silva e Ana Pereira Assunto: prog2:trab1:joao Silva: Anexo: trab1.tar.gz ATENÇÃO: a. No assunto, a disciplina (prog2) e a identificação do trabalho (trab1) devem ser escritos todos em letras MINÚSCULAS. b. NÃO escreva o seu nome com caracteres estendidos (ã, ç, etc). Outras Observações Importantes: 1. O trabalho é INDIVIDUAL. 2. Os trabalhos serão verificados automaticamente por uma ferramenta de detecção de plágio. Em caso de detecção de cópia (parcial ou integral), todos os envolvidos recebem nota ZERO. Em outras palavras, tanto os alunos que copiaram quanto o que deixou copiar recebem ZERO. Portanto, não deixem seus colegas copiarem ou mesmo verem seus trabalhos. 3. Enviem o trabalho no prazo especificado e no formato especificado. Trabalhos recebidos fora do prazo ou em formato inadequado recebem nota ZERO. Como dica, sugerimos não deixar para fazer o trabalho na última semana. Existe uma grande possibilidade de não conseguir cumprir os prazos. 4. Não adianta enviar trabalhos para outros e-mails dos professores ou em formato diferente do especificados acima. Esses e-mails serão descartados sem sequer serem lidos. 5. Trabalho que não compila recebe nota ZERO. Não adianta nem submeter. 6. Os trabalhos serão compilados e verificados usando o compilador gcc no sistema operacional Linux. Recomendamos que o desenvolvimento do trabalho seja feito neste ambiente. No caso daqueles que insistirem em usar outro compilador no sistema operacional Windows, aconselhamos que testem seu trabalho no ambiente de verificação (gcc com Linux) antes de submeter o trabalho pois é MUITO COMUM acontecer de um programa aparentemente funcionar em um ambiente e NÃO compilar ou funcionar no outro. Aconselhamos ainda que o teste no ambiente Linux seja feito com antecedência para evitar que percam o prazo de entrega. 7. Os programas serão avaliados pela sua correção durante a execução e também pelo estilo de programação. Serão observados particularmente se os programas possuem os comentários apropriados, se usam nomes significativos para as variáveis e funções, se o código está indentado corretamente e se utilizam modularização sempre que possível e é apropriado. 8. Em momento algum, cabem contestações as regras estabelecidas nesta especificação de trabalho. Em outras palavras, se alguma dessas regras for violada, não adianta tentar qualquer argumentação pois sua nota NÃO será mudada. 9. Caso haja algum erro neste documento, serão divulgadas erratas. Portanto, fique atento às observações do professor durante as aulas e aos avisos na página do curso. BOM TRABALHO!!!