12  Modelando um problema maior

Nessa aula vamos modelar um jogo bem conhecido, o 21, ou BlackJack. Nele os jogadores devem tentar chegar mais perto da soma de cartas 21, sem estourar. Quem chegar mais perto ganha.

Cada jogador começa com duas cartas, sendo que as cartas tem o seu valor nominal, as figuras (J, Q, K), que valem 10. Além disso, o Ás, pode valer 1 ou 11. O que for mais vantajoso para o jogador.

Para começar vamos fazer uma simulação com um baralho, ou seja 52 cartas. Já que] para o jogo, não importa o naipe da carta, vamos supor que existem quatro cartas de cada. Para isso, vamos criar duas funções, uma que cria um baralho e o guarda em um vetor, e uma segunda que pega uma carta do baralho. Nessa segunda função temos que “retirar” a carta do vetor. Caso já não exista a carta do tipo desejado, temos que sortear uma nova carta.

function criaBaralho()
  cards = zeros(Int8, 13)
  i = 1
  while i < 14
    cards[i] = 4
    i += 1
  end
  return cards
end

function pegarCarta(cards)
  sorteio = rand(1:13)
  while cards[sorteio] == 0
    sorteio = rand(1:13)
  end
  cards[sorteio] -= 1
  if sorteio > 10  # se a carta for figura, ela vale 10
    sorteio = 10
  end  
  return sorteio
end
pegarCarta (generic function with 1 method)

De posse dessas duas funções, podemos criar outras que simulam o comportamento dos jogadores. Vamos usar algumas estratégias simples, como o jogador que fica com as duas cartas que recebeu.

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, ou seja o jogador fica pegando 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 no caso dele ter um Ás, a conta tem que 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)

De posse do soma cartas, 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.