Conforme enunciado do exercício, já no primeiro lançamento dos dois dados é possível ganhar (soma igual a 7 ou 11) ou perder (soma igual a 2, 3 ou 12). Nas rodadas seguintes, perde-se com um 7 e ganha-se com a repetição de um "point" (resultado do primeiro lançamento quando diferente de 2, 3, 7, 11 ou 12).
Considerando que quando dois dados são lançados há maior probabilidade de a soma ser igual a 7, espera-se verificar maior quantidade de ganhadores já na primeira rodada e maior quantidade de perdedores nas jogadas seguintes.
import numpy as np
from itertools import product
import matplotlib.pyplot as plt
resultDados = list(product(range(1,7),repeat=2))
somaDados = [sum(i) for i in resultDados]
x = range(2,13) # a soma varia entre 2 e 12
y = []
y = [somaDados.count(j)/len(resultDados) for j in x]
plt.bar(x,y)

Para atender ao solicitado no exercício, foram criadas duas funções, uma para jogar os dados e outra para verificar o resultado de cada lançamento, conforme segue:
import numpy as np
from itertools import product
import matplotlib.pyplot as plt
def jogaDados():
'''
lançam-se dois dados que podem resultar em números de 1 a 6 com a mesma probabilidade
'''
dado1 = np.random.randint(1,7)
dado2 = np.random.randint(1,7)
soma = dado1+dado2
print((dado1, dado2)) # demonstra os resultado de cada dado
return(soma) # a função retorna a soma dos dados (jogada)
def resultadoJogadas(n_jogadas):
'''
Apresenta o resultado de cada jogada até que o jogador ganhe,
perca ou o número de jogadas (n_jogadas) se encerre;
A função retorna as jogadas (soma dos dados) até o fim do jogo,
a quantidade de jogadas necessárias para o fim do jogo,
bem como se o resultado foi positivo (ganhar=1) ou negativo (perder/chegar ao fim sem ganhar = 0).
'''
jogadas = []
for n in range(1,(n_jogadas+1)):
print(f'\n{n}ª jogada')
jogada = jogaDados()
if n == 1:
if (jogada==7) or (jogada==11):
print(f"Nossa, um {jogada} na primeira rodada, você ganhou!")
result = 1
jogadas.append(jogada)
break
elif (jogada==2) or (jogada==3) or (jogada==12):
print(f"Xii, um {jogada} na primeira rodada, você perdeu!")
result = 0
jogadas.append(jogada)
break
else:
point = jogada
print(f'Point: {jogada}')
jogadas.append(jogada)
elif n == n_jogadas and (jogada!=7) and (jogada != point):
print(f'Soma: {jogada}')
print('Não foi dessa vez!')
result = 0
jogadas.append(jogada)
else:
print(f'Soma: {jogada}')
if jogada==7:
print("Um 7, você perdeu!")
result = 0
jogadas.append(jogada)
break
elif jogada == point:
print(f"De novo um point {jogada}, você ganhou!")
result = 1
jogadas.append(jogada)
break
else:
jogadas.append(jogada)
print("Fim de jogo!\n")
return([jogadas,n,result])
No momento de chamar as funções, optou-se por simular uma amostra de 1000 jogadores lançando os dados em até 10 vezes para identificar o comportamento dos resultados:
if __name__=='__main__':
resultados = []
amostra = 1000
jogadores = 0
while jogadores < amostra:
print(f' ----- Jogador nº {jogadores+1} -----')
resultados.append(resultadoJogadas(10))
jogadores += 1
matriz = resultados
print(matriz) # A matriz retorna, ao final, os resultados de cada jogador,
# sendo o primeiro elemento uma lista com as jogadas (soma dos dados),
# o segundo elemento o número de jogadas por jogador até o fim do jogo,
# e o terceiro elemento representa so o jogador ganhou (1) ou perdeu o jogo (0).
Como já esperado, dentre todos os lançamentos dos 1000 jogadores, o resultado mais observado foi o 7, seguindo distribuição próxima da distribuição demonstrada anteriormente:
# list comprehension para consolidar apenas o primeiro elemento da matriz
# (resultados das jogadas por jogador)
resultadosJogadasPorJogador = [[row[i] for row in matriz] for i in range(3)][0]
# Gráfico indicando os resultados das jogadas (soma dos dados) das 1000 amostras de
# jogador
x = range(2,13) # a jogada varia entre 2 e 12
y = []
[[y.append(i) for i in lista] for lista in resultadosJogadasPorJogador]
y = [y.count(j) for j in x]
plt.bar(x,y)

Ao se identificar a quantidade total de jogadas necessárias para o fim do jogo, verificou-se que a maior parte dos jogos já se encerra no primeiro lançamento:
# list comprehension para consolidar o segundo elemento da matriz (número total de
#jogadas por jogador até o fim do jogo)
nJogadasPorJogador = [[row[i] for row in matriz] for i in range(3)][1]
x = range(1,11) # O número de jogadas pode variar entre 1 e 10
y = []
y = [nJogadasPorJogador.count(j) for j in x]
y
plt.bar(x,y)

Ainda que a maior parte dos jogos se encerre no primeiro lançamento (principalmente em função do 7), a maior parte dos jogadores saiu perdendo no jogo (também em função do 7 ter maior probabilidade de aparecer nas nove jogadas seguintes):
# list comprehension para consolidar o terceiro elemento da matriz (resultado do jogo
#por jogador, onde 1 = ganhar e 0 = perder)
resultadoJogoPorJogador = [[row[i] for row in matriz] for i in range(3)][2]
x = [0,1] # O número de jogadas pode variar entre 1 e 10
y = []
y = [resultadoJogoPorJogador.count(r) for r in x]
y
plt.bar(x, y,)
