Files
trucoPascal/bbbb.pas
T
Idalecio Schvartz Sobrinho 4e89157a46 Add files via upload
2026-05-31 12:19:27 -03:00

560 lines
16 KiB
ObjectPascal

program pzim;
uses crt;
type
TCarta = record
numero : integer;
naipe : integer; // naipes: 1 ouro, 2 espada, 3 copa, 4 pau ' > '
end;
TPilha = record //baralho
dados : array[1..40] of TCarta;
topo : integer;
end;
TFila = record // volta pro baralho
dados : array[1..40] of TCarta;
inicio : integer;
fim : integer;
total : integer;
end;
TLista = record // baralho em lista
dados : array[1..40] of TCarta;
qtde : integer;
end;
TPlacar = record
cpu : integer;
jogador : integer;
end;
// provavelmente vai ser inutil
// e é mesmo
{
TMaos = record
cpu : array [1..9] of TCarta;
jogador : array [1..3 of TCarta;
}
//takin esteve aqui
//takin aqui tbm
procedure pilha_iniciar(var p: TPilha);
begin
p.topo := 0;
end;
procedure pilha_adicionar(var p: TPilha; carta: TCarta);
begin
if p.topo < 40 then
begin
p.topo := p.topo + 1;
p.dados[p.topo] := carta;
end;
end;
procedure pilha_remover(var p: TPilha; var carta: TCarta);
begin
if p.topo > 0 then
begin
carta := p.dados[p.topo];
p.topo := p.topo - 1;
end;
end;
procedure fila_iniciar(var f: TFila);
begin
f.inicio := 1;
f.fim := 0;
f.total := 0;
end;
procedure fila_adicionar(var f: TFila; carta: TCarta);
begin
if f.total < 40 then
begin
f.fim := f.fim + 1;
f.dados[f.fim] := carta;
f.total := f.total + 1;
end;
end;
procedure fila_remover(var f: TFila; var carta: TCarta);
begin
if f.total > 0 then
begin
carta := f.dados[f.inicio];
f.inicio := f.inicio + 1;
f.total := f.total - 1;
end;
end;
procedure lista_iniciar(var l: TLista);
begin
l.qtde := 0;
end;
procedure lista_adicionar(var l: TLista; carta: TCarta);
begin
if l.qtde < 40 then
begin
l.qtde := l.qtde + 1;
l.dados[l.qtde] := carta;
end;
end;
procedure lista_remover_posicao(var l: TLista; pos: integer; var carta: TCarta);
var
i : integer;
begin
if (pos >= 1) and (pos <= l.qtde) then
begin
carta := l.dados[pos];
// joga geral pra esquerda
for i := pos to (l.qtde - 1) do
begin
l.dados[i] := l.dados[i + 1];
end;
l.qtde := l.qtde - 1;
end;
end;
function forca(carta: TCarta): integer;
begin // meio obvio oq ta rolando aqui ne?
case carta.numero of
4: forca := 1;
5: forca := 2;
6: forca := 3;
7: forca := 4;
10: forca := 5;
11: forca := 6;
12: forca := 7;
1: forca := 8;
2: forca := 9;
3: forca := 10;
else
forca := 0;
end;
end;
function nome_naipe(n: integer): string;
begin
case n of
1: nome_naipe := 'Ouro';
2: nome_naipe := 'Espada';
3: nome_naipe := 'Copa';
4: nome_naipe := 'Paus';
else
nome_naipe := 'OQ ROLOU?';
end;
end;
procedure mostrar_mao(mao: TLista);
var
i: integer;
begin
writeln('SUAS CARTAS:');
for i := 1 to mao.qtde do
writeln(i, ': ', mao.dados[i].numero, ' de ', nome_naipe(mao.dados[i].naipe));
// <id> <AS/2/3...> de <naipe>
end;
function compara_carta_jogada(carta1, carta2: TCarta; manilha: integer): integer;
var
f1 , f2 : integer;
begin
if (carta1.numero = manilha) and (carta2.numero <> manilha) then
compara_carta_jogada := 1 // esse é o de cima, se tu for burro
else if (carta1.numero <> manilha) and (carta2.numero = manilha) then
compara_carta_jogada := -1 // esse e o de cima compara se é carta normal e manilha, manilha ganha obvio
else if (carta1.numero = manilha) and (carta2.numero = manilha) then
begin // se ambos for manilha, compara naipe
if carta1.naipe > carta2.naipe then
compara_carta_jogada := 1
else if carta1.naipe < carta2.naipe then
compara_carta_jogada := -1
else
compara_carta_jogada := 0;
end
else
begin // se tudo for carta normal, pega a força
f1 := forca(carta1);
f2 := forca(carta2);
if f1 > f2 then
compara_carta_jogada := 1
else if f1 < f2 then
compara_carta_jogada := -1
else
compara_carta_jogada := 0;
end;
end;
function proximo_valor_trucar(valor_atual: integer): integer;
begin
if valor_atual = 1 then proximo_valor_trucar := 3
else if valor_atual = 3 then proximo_valor_trucar := 6
else if valor_atual = 6 then proximo_valor_trucar := 9
else proximo_valor_trucar := 12; //so vai incrementando o valor da rodada/mao
end;
function forca_truco(carta: TCarta; manilha: integer): integer;
begin
if carta.numero = manilha then //vai calcular a força das cartas da mao (inclui manilha, diferente da funcao forca normal)
forca_truco := 20
else
forca_truco := forca(carta);
end;
function soma_forca_mao(mao: TLista; manilha: integer): integer;
var
i,soma: integer;
begin
soma := 0;
for i := 1 to mao.qtde do
soma := soma + forca_truco(mao.dados[i], manilha); //calcula a força da mao, com a manilha (funcao acima)
soma_forca_mao := soma;
end;
function cpu_aceita_truco(mao: TLista; manilha: integer): boolean;
var
soma, i, maior: integer;
begin
soma := 0;
maior := 0;
for i := 1 to mao.qtde do
begin
soma := soma + forca_truco(mao.dados[i], manilha);
if forca_truco(mao.dados[i], manilha) > maior then
maior := forca_truco(mao.dados[i], manilha); //pega a força da carta masi forte
end;
if maior = 20 then //força da manilha é 20 no forca_truco, entao aceita se tiver manilha
cpu_aceita_truco := true
else if soma > 24 then
cpu_aceita_truco := true //se a soma de forca da mao >24, aceita pq sim
else if random(100) < 20 then
cpu_aceita_truco := true //blefar em 20% kkkkk
else
cpu_aceita_truco := false;
end;
procedure trucar(var valor_mao: integer; var resultado: integer; var mao_encerrada: boolean; mao_cpu: TLista; manilha: integer);
var
valor_proposto: integer;
begin
valor_proposto := proximo_valor_trucar(valor_mao);
if cpu_aceita_truco(mao_cpu, manilha) then
begin
valor_mao := valor_proposto;
writeln('CPU aceitou!');
end
else
begin
writeln('CPU correu!');
resultado := valor_mao;
mao_encerrada := true;
end;
end;
function escolher_carta_cpu(mao: TLista; carta_jogador: TCarta; manilha: integer): integer;
var
i, melhor_pos: integer;
begin
melhor_pos := 1;
//procura a carta mais forte que a que o jogador jogou, ou a primeira da mao.
// problemas: pega sempre a mais forte da mao, nao a mais fraca que já ganharia a rodada
for i := 1 to mao.qtde do
begin
if compara_carta_jogada(mao.dados[i], carta_jogador, manilha) = 1 then
begin
melhor_pos := i;
end;
end;
escolher_carta_cpu := melhor_pos;
end;
procedure gerar_baralho(var baralho: TLista);
var
i, j: integer;
carta: TCarta;
begin
lista_iniciar(baralho);
for i := 1 to 4 do //gera naipes
begin
for j := 1 to 10 do // gera numeros de 1 a 7 normal, se for 8,9,10, incrementa pra 10,11,12
begin
carta.naipe := i;
if j <= 7 then
carta.numero := j
else
carta.numero := j + 2;
lista_adicionar(baralho, carta);
end;
end;
end;
function proxima_carta(valor: integer): integer;
begin
case valor of
1: proxima_carta := 2;
2: proxima_carta := 3;
3: proxima_carta := 4;
4: proxima_carta := 5;
5: proxima_carta := 6;
6: proxima_carta := 7;
7: proxima_carta := 10;
10: proxima_carta := 11;
11: proxima_carta := 12;
12: proxima_carta := 1; //so calcula a proxima carta na ordem pulando msm, pq essa merda é confusa pro vira/manilha
else
proxima_carta := valor;
end;
end;
procedure escolher_manilha(carta_vira: TCarta; var manilha: integer);
begin
manilha := proxima_carta(carta_vira.numero); //meio obvcio
end;
procedure placar_atualizar(var placar: TPlacar; resultado: integer);
begin //recebe o resultado da mao, se for 1 jogador ganha, se for -1 cpu ganha, se for 0 ninguem ganha
case resultado of
1,3,6,12: placar.jogador := placar.jogador + abs(resultado);
-1,-3,-6,-12: placar.cpu := placar.cpu + abs(resultado); // se for -1, o cpu ganhou rodada valendo truco 1, se for -6, o cpu ganhou rodada valendo truco 6, etc
else
;
end;
end;
procedure resultado_mao(resultado: integer);
begin
if resultado > 0 then
writeln('Resultado da mao: Voce -> ', resultado)
else if resultado < 0 then
writeln('Resultado da mao: CPU -> ', abs(resultado))
else
writeln('Resultado da mao: Empate');
end;
procedure jogar(var mao_jogador: TLista; var mao_cpu: TLista; manilha: integer; var placar: TPlacar);
var
resultados: array [1..3] of integer;
c1, c2: TCarta;
i, escolha, pos_cpu: integer;
resultado, vitorias_jogador, vitorias_cpu, primeiro_vencedor: integer;
valor_mao: integer;
mao_encerrada: boolean;
opcao_truco: char;
begin
writeln('=========================================');
writeln(' NOVA MAO DISTRIBUIDA ');
valor_mao := 1;
mao_encerrada := false;
vitorias_jogador := 0;
vitorias_cpu := 0;
primeiro_vencedor := 0;
resultado := 0;
for i := 1 to 3 do // 3 jogadas por mao
begin
if not mao_encerrada then
begin
writeln('=========================================');
writeln('Rodada ', i);
//print bonitinho
mostrar_mao(mao_jogador);
if valor_mao < 12 then
begin
writeln('Quer pedir truco? (S/N)');
readln(opcao_truco);
if (opcao_truco = 'S') or (opcao_truco = 's') then
trucar(valor_mao, resultado, mao_encerrada, mao_cpu, manilha);
if mao_encerrada then //mao encerrada pq a cpu correu, entao so atualiza o placar
begin
placar_atualizar(placar, resultado);
resultado_mao(resultado);
writeln('=========================================');
end;
end;
if not mao_encerrada then //tudo isso pq nao pode usar break no if mao_encerrada de cima kkk
begin
writeln('Escolha sua carta:');
readln(escolha);
while (escolha < 1) or (escolha > mao_jogador.qtde) do //enquanto o burro digitar invalido, pede de novo
begin
writeln('Escolha invalida:');
readln(escolha);
end;
lista_remover_posicao(mao_jogador, escolha, c1); //tira a escolhida da mao e retorna a carta no C1 como TCarta
//cpu procura a maior carta pra ganhar msm
pos_cpu := escolher_carta_cpu(mao_cpu, c1, manilha);
lista_remover_posicao(mao_cpu, pos_cpu, c2); //tira e retorna no C2 como TCarta
writeln('Voce jogou: ', c1.numero, ' de ', nome_naipe(c1.naipe));
writeln('CPU respondeu com: ', c2.numero, ' de ', nome_naipe(c2.naipe));
resultados[i] := compara_carta_jogada(c1, c2, manilha);
// 1 = player ganhou
// -1 = cpu ganhou
// 0 = empate
if resultados[i] = 1 then
writeln('>> Voce ganhou a rodada')
else if resultados[i] = -1 then
writeln('>> CPU ganhou a rodada')
else
writeln('>> Empate');
if resultados[i] = 1 then
begin
vitorias_jogador := vitorias_jogador + 1;
if primeiro_vencedor = 0 then
primeiro_vencedor := 1;
end
else if resultados[i] = -1 then
begin
vitorias_cpu := vitorias_cpu + 1;
if primeiro_vencedor = 0 then
primeiro_vencedor := -1;
end;
end;
end;
end;
if not mao_encerrada then
begin
if vitorias_jogador > vitorias_cpu then
resultado := valor_mao // se player ganhou mais rodadas, ele ganha a mao
else if vitorias_cpu > vitorias_jogador then
resultado := -valor_mao // se cpu ganhou mais rodadas, ele ganha a mao
else if primeiro_vencedor <> 0 then
resultado := primeiro_vencedor * valor_mao // se empatou em vitorias, quem ganhou a primeira rodada ganha a mao
else
resultado := 0;
placar_atualizar(placar, resultado); //se for positivo jogador ganha, se for negativo cpu ganha, se for 0 ninguem ganha
writeln('R1: ', resultados[1], ' R2: ', resultados[2], ' R3: ', resultados[3]);
resultado_mao(resultado);
writeln('=========================================');
end;
end;
procedure embaralhar_baralho(var listacartas: TLista; var baralhopilha: TPilha);
var
posicaosorteada: integer;
cartasorteada: TCarta;
begin
pilha_iniciar(baralhopilha);
while listacartas.qtde > 0 do
begin
posicaosorteada := random(listacartas.qtde) + 1; //vai pegando posicao aleatoria da lista, remove e adiciona na pilha
lista_remover_posicao(listacartas, posicaosorteada, cartasorteada); //todo remover retorna a cartas pela ultima variavel TCarta
pilha_adicionar(baralhopilha, cartasorteada);
end;
end;
procedure distribuir_cartas(var baralho: TFila; var mao_cpu: TLista; var mao_jogador: TLista; var carta_vira : TCarta);
var
i: integer;
carta: TCarta;
begin
lista_iniciar(mao_cpu);
lista_iniciar(mao_jogador);
for i := 1 to 3 do
begin //como é fila, vai pegar a do topo e distribuir pra cada, (no remover, retonra no carta)
fila_remover(baralho, carta);
lista_adicionar(mao_jogador, carta);
fila_remover(baralho, carta);
lista_adicionar(mao_cpu, carta);
end;
fila_remover(baralho, carta_vira);
end;
procedure cortar_e_enfileirar(var baralho_pilha: TPilha; var baralho_fila: TFila);
var
carta: TCarta;
begin
fila_iniciar(baralho_fila);
// nao sei oq porra ta acontecendo, so tou transformando pilha em fila heh
while baralho_pilha.topo > 0 do
begin
pilha_remover(baralho_pilha, carta);
fila_adicionar(baralho_fila, carta);
end;
end;
// PROGRAMA PRINCIPAL
var
manilha: integer; // bosta
deck_lista : TLista;
deck_pilha : TPilha;
deck_fila : TFila;
mao_jogador : TLista;
mao_cpu : TLista;
vira: TCarta;
placar : TPlacar;
opcao : char;
continua : boolean;
begin
placar.jogador := 0;
placar.cpu := 0;
continua := true;
randomize; //deixa o random random msm, nao tira sprr
while (placar.jogador < 12) and (placar.cpu < 12) and continua do
begin
gerar_baralho(deck_lista);
embaralhar_baralho(deck_lista, deck_pilha);
cortar_e_enfileirar(deck_pilha, deck_fila);
distribuir_cartas(deck_fila, mao_cpu, mao_jogador, vira);
escolher_manilha(vira, manilha);
writeln('Carta vira: ', vira.numero, ' Naipe: ', nome_naipe(vira.naipe));
writeln('Manilha: ', manilha);
jogar(mao_jogador, mao_cpu, manilha, placar);
writeln('Placar -> Tu: ', placar.jogador, ' | Pc: ', placar.cpu);
writeln('C para continuar para proxima ou S pra SAIR');
readln(opcao);
if (opcao = 'S') or (opcao = 's') then
continua := false;
clrscr;
end;
writeln('Fim de jogo. Tu: ', placar.jogador, ' | Pc: ', placar.cpu);
end.