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; 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)); // de 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.