Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Continuando a modelagem

Authors
Affiliations
University of São Paulo
University of São Paulo
function jogador1(cards)
  carta1 = pegarCarta(cards)
  carta2 = pegarCarta(cards)
  if carta1 == 1 || carta2 == 1
    return carta1 + carta2 + 10
  else
    return carta1 + carta2
  end  
end
jogador1 (generic function with 1 method)

Notem que, acima, usamos a estratégia de usar o Ás da forma mais vantajosa.

Para os outros jogadores, vamos usar estratégias mais elaboradas: o jogador pega cartas enquanto não chegar a um valor pré-determinado, como, por exemplo, 21, 19, 17, 15 e 13.

Como cada jogador pode ter um número grande de cartas e, caso tenha um Ás, a conta precisa ser feita da maneira mais vantajosa, vamos usar uma função que recebe um vetor de cartas e calcula a soma.

function somaCartas(c)
  soma = 0
  temAz = false
  for i in c
    soma += i
    if c == 1 
      temAz = true
    end
  end
  if soma <= 11 && temAz
      return soma + 10
  else 
      return soma
  end
end
somaCartas (generic function with 1 method)

Com a função somaCartas pronta, podemos modelar os jogadores.

function jogador2(cards)
  cartas = []
  push!(cartas, pegarCarta(cards))
  push!(cartas, pegarCarta(cards))
  while somaCartas(cartas) < 21
    push!(cartas, pegarCarta(cards))
  end
  return somaCartas(cartas)
end

function jogador3(cards)
  cartas = []
  push!(cartas, pegarCarta(cards))
  push!(cartas, pegarCarta(cards))
  while somaCartas(cartas) < 19
    push!(cartas,pegarCarta(cards))
  end
  return somaCartas(cartas)
end

function jogador4(cards)
  cartas = []
  push!(cartas, pegarCarta(cards))
  push!(cartas, pegarCarta(cards))
  while somaCartas(cartas) < 17
    push!(cartas,pegarCarta(cards))
  end
  return somaCartas(cartas)
end

  function jogador5(cards)
    cartas = []
    push!(cartas, pegarCarta(cards))
    push!(cartas, pegarCarta(cards))
    while somaCartas(cartas) < 15
      push!(cartas,pegarCarta(cards))
    end
    return somaCartas(cartas)
  end

function jogador6(cards)
  cartas = []
  push!(cartas, pegarCarta(cards))
  push!(cartas, pegarCarta(cards))
  while somaCartas(cartas) < 13
    push!(cartas,pegarCarta(cards))
  end
  return somaCartas(cartas)
end
jogador6 (generic function with 1 method)

Agora que temos todos os jogadores, podemos modelar uma partida. Para isso, criamos um baralho e fazemos com que cada jogador siga a sua estratégia.

function partida()
  cards = criaBaralho()
  jogadores = zeros(Int8, 6)
  jogadores[1] = jogador1(cards)
  jogadores[2] = jogador2(cards)
  jogadores[3] = jogador3(cards)
  jogadores[4] = jogador4(cards)
  jogadores[5] = jogador5(cards)
  jogadores[6] = jogador6(cards)
end
partida (generic function with 1 method)

Não deu tempo de continuar, ficou para a próxima aula.

No capítulo anterior, ficamos com uma partida, mas sem a verificação do vencedor, ou seja, do jogador com o maior valor, menor ou igual a 21. Uma decisão de projeto é dizer que, no caso de empate, os jogadores com os maiores valores ganham e dividem o prêmio.

function partida()
  cards = criaBaralho()
  jogadores = zeros(Int8, 6)
  jogadores[1] = jogador1(cards)
  jogadores[2] = jogador2(cards)
  jogadores[3] = jogador3(cards)
  jogadores[4] = jogador4(cards)
  jogadores[5] = jogador5(cards)
  jogadores[6] = jogador6(cards)
  return jogadores
end
partida (generic function with 1 method)

Logo, a partida devolve a pontuação de cada jogador, para podermos verificar na rotina ganhador quem ganhou.

function ganhador(v)
    i = 1
    maximo = 0
    while i <= length(v)
        if v[i] > 21  # se estourou é como se tivesse o menor valor
            v[i] = 0
        end
        if v[i] > maximo
            maximo = v[i]  # encontra o vencedor
        end
        i = i + 1
    end
    result = zeros(Int64, length(v))
    i = 1
        while i <= length(v)
            if v[i] == maximo
                result[i] = 1
            end
            i = i + 1
        end
    return result
end
ganhador (generic function with 1 method)

A rotina ganhador devolve um vetor com os vencedores, com 1 na posição de quem ganhou e zero na posição dos perdedores.

Uma das vantagens de se usar um computador é que podemos ter milhares de partidas de 21 para encontrar qual seria a melhor estratégia.

function porcentagem()
    i = 1
    porc = zeros(Int64, 6)
    while i < 100000
        porc = porc + ganhador(partida())
        i = i + 1
    end
    println(porc)
end
porcentagem (generic function with 1 method)

Ao simularmos o jogo 10000 vezes, podemos encontrar qual é a melhor estratégia dentre as que foram apresentadas.

O código acima ficou relativamente grande, e uma das coisas que podemos notar é que há muita duplicação nos códigos dos Jogadores a partir do segundo. Um dos maiores problemas de código é a duplicação. No caso acima, podemos evitá-la adicionando um parâmetro à função Jogador, de forma que esse seja o limite a ser considerado no laço. A função jogador2 fica assim:

function jogador2(cards, valor)
    cartas = []
    push!(cartas, pegarCarta(cards))
    push!(cartas, pegarCarta(cards))
    while somaCartas(cartas) < valor
       push!(cartas, pegarCarta(cards))
    end
    return somaCartas(cartas)
end
jogador2 (generic function with 2 methods)

Como a função tem um parâmetro novo, temos que ajustar a partida. Mas agora podemos usar todos os valores.

function partida()
   cards = criaBaralho()
   jogadores = zeros(Int8, 6)
   jogadores[1] = jogador1(cards)
   jogadores[2] = jogador2(cards, 21)
   jogadores[3] = jogador2(cards, 20)
   jogadores[4] = jogador2(cards, 19)
   jogadores[5] = jogador2(cards, 18)
   jogadores[6] = jogador2(cards, 17)
   return jogadores
end
partida (generic function with 1 method)

Notem que não há mudança na função ganhador, que continua funcionando.

Para terminar, podemos ter agora uma versão interativa que permite que um jogador humano jogue com o computador.

function partidaComHumano()
    cards = criaBaralho()
    humano = []
    computador = jogador2(cards, 19)
    push!(humano, pegarCarta(cards))
    push!(humano, pegarCarta(cards))
    println("O humano tem ", humano, " e soma ", somaCartas(humano))
    println("O humano quer mais cartas (S/N)?")
    resp = readline()
    while resp == "S" || resp == "s"
         push!(humano, pegarCarta(cards))
         println("O computador tem ", computador, " e soma ", somaCartas(computador))
         println("O humano tem ", humano, " e soma ", somaCartas(humano))
         println("O humano quer mais cartas (S/N)?")
         resp = readline()
    end
    println("O computador tem ", computador, " e soma ", somaCartas(computador))
    if somaCartas(computador) <= 21 && somaCartas(humano) <= 21
         if somaCartas(computador) > somaCartas(humano)
             println("Humano Perdeu")
         elseif somaCartas(computador) == somaCartas(humano)
             println("Empate")
         else
             println("Humano ganhou")
         end
    elseif somaCartas(computador) > 21 && somaCartas(humano) > 21
         println("os dois perderam")
    elseif somaCartas(computador) > 21
         println("Humano ganhou")
    else
         println("Computador ganhou")
    end
end
partidaComHumano (generic function with 1 method)