Jokenpô

Faala rede!

Na faculdade essa semana tivemos aula sobre laços de repetição e um pequeno trecho de código em Python que demonstra seu funcionamento.

O objetivo não é adentrar em conceitos de laços de repetição e seu fluxo, mas mostrar aqui na prática o desafio para determinar a condição de termino do laço e que um pequeno trecho de código pode ser desafiador.

Show me the code.

Precisamos declarar um vetor que receba os valores (nesse caso os únicos válidos para o jokenpô).

# Variables definition
options = ["pedra", "papel", "tesoura"]

Depois, precisamos definir a lógica do jogo. Somente com condições podemos definir quem ganha a rodada e quem perde. No jokenpô a regra é clara:

  • Pedra quebra tesoura
  • Tesoura corta papel
  • Papel embrulha pedra

Então podemos definir o seguinte trecho:

# Condition game and start.
    player = input("Escolha (pedra/papel/tesoura): ").lower()
    if player not in options:
        print("Opção inválida!")
    elif player == computer:
        print("Empate")
    elif (player == "pedra" and computer == "tesoura" or player == "papel" and computer == "pedra" or
    player == "tesoura" and computer == "papel"):
        print("Você ganhou!")
        player_points += 1
    else:
        print("Bot ganhou!")
        computer_points += 1

Considere então que:

  • O valor digitado pelo usuário deve ser igual um dos valores que tem no vetor, caso contrário: opção inválida!
  • Caso a escolha do usuário com a definida do bot pelo módulo random estejam iguais: empate!
  • Em seguida, a definição da condição com operadores lógicos que faz o jogador ganhar um ponto.

Mas, se estamos falando de um jogo, ele precisa ser “fácil”. Você como desenvolvedor precisa estimular o jogador (user) a jogar mais e tentar ganhar. Somente com um trecho da lógica do jogo você não consegue definir um placar e condição de vitória. É ai que entra o laço de repetição.

While

Não queria que o jogo durasse eternamente, ou entrasse em um loop, mas também não queria definir um limite de jogadas, e sim, que independente da quantidade de rodadas houvesse um vencedor conforme o número de pontos limite que eu defini (nesse caso: 5). Utilizei então o while. Esse laço permite que eu passe uma condição e com base nela repeta tudo que eu defini dentro do escopo até que a condição que eu passei seja atendida.

O primeiro pensamento foi: se quero que, quem completar primeiro 5 pontos seja o vencedor então um ou outro que completar 5 pontos primeiro vence. Tendo assim:

while player_points != 5 or computer_points != 5:

Mas compilando o código percebi que a condição que eu passei (no caso a que eu planejava) não estava sendo atendida. O laço repetia independente da quantidade de pontos totais que o jogador ou o bot completava.

Foi pensando lógicamente que entendi que, na verdade, os operadores lógicos or e != não faziam sentido nenhum na minha condição. Explicando:

  1. Uma porquê, enquanto houvesse uma condição sendo verdade (True) o laço ainda ia continuar a repetir.
  2. O número total de pontos sendo diferente de 5 nunca é satisfeito. Ou melhor, muito difícil chegar em um resultado 5 x 5 para assim sair do laço.

Mesmo que jogador completasse 5, se o bot não estivesse com a quantidade de pontos igual a 5 o jogo iria continuar, consequentemente, a condição nunca é satisfeita.

Para resolver o problema em questão:

while player_points < 5 and computer_points < 5:

Agora quem completa primeiro os cinco pontos, é o vencedor. Ou seja, quando uma das condições não for verdade, o laço não se repetirá.

Conclusão

É necessário ter bem fundamentado quando e qual operador lógico utilizar. Nunca pensar pelo sentido literal da palavra (como eu me equivoquei com o operador OR) mas, como ela vai atuar dentro da condição.

O código se encontra no meu repositório do GitHub.

Agradecimentos ao professor de POO Fernando Domeneghetti que me auxilou no desenvolvimento e me ajuda nos estudos da matéria.