14  Continuando a modelagem

No capítulo anterior ficamos com uma partida, mas sem a verificação do vencedor, ou seja o 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 rotinha 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 1 method)

Como a função tem um parâmetro novo, temos que acertar 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)