Olá, Antônio!
> O lance anterior se refere, em uma rodada, ao lance do adversário ou ao lance do próprio jogador na rodada anterior?
As rodadas são completamente independentes umas das outras, então nenhuma informação da rodada anterior - excetuadas as pontuações - é utilizada na rodada atual. A finalidade do parâmetro lanceanterior na função jogada é garantir que o segundo jogador daquela rodada não repita o lance dado pelo primeiro jogador. Por isso o enunciado sugere que na chamada da função jogada para o primeiro jogador seja passado o valor lanceanterior=-1, o que na prática não impõe restrições adicionais ao lance do primeiro jogador (apenas a restrição 0<=lance<=N-1).
> É obrigatório que as mensagens do programa sejam exatamente iguais às do executável?
Sim, essa é a primeira frase da especificação: "Seu programa em Python deve se comportar exatamente como o executável disponível no PACA."
Há boas razões para isso, para além de facilitar o emprego de corretores automáticos: fazer uma especificação com todos os detalhes da implementação a ponto de não deixar espaço para nenhuma dúvida ou ambiguidade custaria muitas dezenas de páginas de enunciado, o que seria sofrível para nós todos. O executável permite responder facilmente várias dúvidas que surjam, como a próxima:
> Se o humano quiser continuar o jogo, o N atual deve ser mantido ou o humano deverá digitar algum N de novo?
Se você rodar o executável, verá que o N só é perguntado no início, bem como a frase "Aguarde enquanto envieso a roleta...", que está associada à geração da distribuição enviesada através da chamada da função distribuição. A ideia é que cada execução do programa está associada a uma única roleta enviesada, gerada antes da primeira rodada, e que será usada até o usuário desistir de jogar.
> É permitido usar alguma função para arredondar valores, conforme o que aparentemente foi feito no executável?
No executável não foi usada nenhuma função para arredondar valores, como round(), floor() ou ceil(), se foi essa a sua pergunta. Todas as variáveis e expressões aritméticas são inteiras. Nós vimos em aula a função int() que converte um float para inteiro através de truncamento da parte fracionária, por isso se x>=0 seria permitido usar int(x) para obter "floor(x)" e int(x+0.5) para obter "round(x)", mas nem mesmo a função int() foi usada no executável com essa finalidade (ela só é usada quando há um input() de um valor inteiro).
Se a sua pergunta se refere à operação de "descascar dígitos decimais", nesse caso o uso da divisão inteira "//" dispensa uma operação de arredondamento, já que o resultado dessa operação é sempre inteiro. Por outro lado, se a sua pergunta se refere aos valores fracionários truncados em 3 casas decimais que aparecem na função bônus, ali o que foi feito foi uma formatação da saída:
>>> print("{0:2.3f}".format(2**0.5))
1.414
> A tabela gerada pela função bônus precisa estar totalmente alinhada?
Como essa pergunta é uma variação da sua segunda pergunta, vou responder então a uma outra pergunta: "como alinhar valores impressos na forma de uma tabela?". A resposta é: garantindo que os valores numéricos possuem largura fixa (ver a formatação acima). Embora isso seja suficiente para permitir a escrita alinhada daquela tabela, um outro truque de formatação útil é usar o caractere TAB "\t" entre valores, pois isso alinha o valor seguinte a uma certa "coluna" da saída, compensando pequenas diferenças na largura dos números que vêm antes:
>>> for i in range(11): print(i,"\t",i**2,"\t",i**3,"\t",i**4)
...
0 0 0 0
1 1 1 1
2 4 8 16
3 9 27 81
4 16 64 256
5 25 125 625
6 36 216 1296
7 49 343 2401
8 64 512 4096
9 81 729 6561
10 100 1000 10000
Abraços,
Marcelo