Ir para conteúdo
Fórum Script Brasil
  • 0

Vetor para armazenar cartas de baralho


Jefers0n

Pergunta

Olá,

Estou iniciando meu trabalho final da cadeira de C, preciso fazer um jogo(que foi inventado pela profª - o jogo não existe) que ainda estou estudando como fazer as jogadas e tal, minha primeira dúvida é a seguinte:

Preciso armazenar as 52 cartas do baralho(temos que usar vetores), pensei em armazenar em um vetor os numeros de 1 a 13 com uma letra indicando o naipe, assim:

1c (ás de copas);

5e (cinco de espadas)...

Mas daí como eu armazenaria isso em um vetor, que tipo usaria?

Preciso saber como colocar as 52 cartas no vetor (13 cartas de cada naipe) e embaralhá-las.

Como poderia fazer para armazenar e embaralhar estas cartas???

[]'s

Jeferson Neves

Link para o comentário
Compartilhar em outros sites

11 respostass a esta questão

Posts Recomendados

  • 0

Você pode fazer um vetor de struct.

struct Carta {
    int numero; // 1 2 3 4 5 6 7 8 9 10 11 12 13 repreentando de A a K
    int naipe;    // 1 = Ouros, 2 = Espada, 3 = Copas, 4 = Paus
    //Se preferir, pode usar char * e colocar os nomes completos..
}

//e depois fazer.

struct Carta Baralho[52];

Baralho[0].letra = 1;  
Baralho[0].naipe = 1; 

//assim você guarda todas as cartas.

//Para embaralhar, você pode ser uma função geradora de pseudo-aleatórios, por exemplo srand, etc, pesquise sobre isso.
//Ai você gera um número aleatório entre 0 e 51 para pegar aleatoriamente as cartas.

Link para o comentário
Compartilhar em outros sites

  • 0

Você poderia criar dois vetores: um para o numero e outro para o naipe.

#include <stdlib.h>

int main(){
    int num [52], i, j, ai;
    char naipe [52], ac;

    for (i = 0; i < 52; i++) { //inicialização
        num[i] = i / 4 +1;
        
        switch (i%4) {
            case 0: naipe[i] = 'c';    break; //copas
            case 1: naipe[i] = 'e'; break; //espada
            case 2: naipe[i] = 'o'; break; //ouros
            case 3: naipe[i] = 'p'; break; //paus
        }
    }
    
    for (i = 0; i < 52; i++) { //embaralhar;
    
        do {
            j = rand()%52;
        } while (i == j);
        
        ai = num[i];
        num[i] = num[j];
        num[j] = ai;
        
        ac = naipe[i];
        naipe[i] = naipe[j];
        naipe[j] = ac;
    }
}

Na inicialização, ele pega as quatro primeiras cartas e pões numero 1, da quinta a oitava, 2, da nona até a 12, 3... até todas terem um número. No final, cada número terá quatro cartas (Haverá 4 cartas 13, 4 cartas 12...). Para cada uma dessas quatro cartas, ele põe um naipe. Se você colocar printf dentro desse loop, dá para ver como as cartas são "criadas".

Para embaralhar, usei a função rand. Ele pega cada poisção do vetor e troca por outra aleatória. Observe que o do..while, que garante que haverá exatamente 52 trocas.

Na verdade, o programa ficaria bem mais elegante se usasse struct, mas não sei podia usar...

Link para o comentário
Compartilhar em outros sites

  • 0
Você poderia criar dois vetores: um para o numero e outro para o naipe.

#include <stdlib.h>

int main(){
    int num [52], i, j, ai;
    char naipe [52], ac;

    for (i = 0; i < 52; i++) { //inicialização
        num[i] = i / 4 +1;
        
        switch (i%4) {
            case 0: naipe[i] = 'c';    break; //copas
            case 1: naipe[i] = 'e'; break; //espada
            case 2: naipe[i] = 'o'; break; //ouros
            case 3: naipe[i] = 'p'; break; //paus
        }
    }
    
    for (i = 0; i < 52; i++) { //embaralhar;
    
        do {
            j = rand()%52;
        } while (i == j);
        
        ai = num[i];
        num[i] = num[j];
        num[j] = ai;
        
        ac = naipe[i];
        naipe[i] = naipe[j];
        naipe[j] = ac;
    }
}
Na inicialização, ele pega as quatro primeiras cartas e pões numero 1, da quinta a oitava, 2, da nona até a 12, 3... até todas terem um número. No final, cada número terá quatro cartas (Haverá 4 cartas 13, 4 cartas 12...). Para cada uma dessas quatro cartas, ele põe um naipe. Se você colocar printf dentro desse loop, dá para ver como as cartas são "criadas". Para embaralhar, usei a função rand. Ele pega cada poisção do vetor e troca por outra aleatória. Observe que o do..while, que garante que haverá exatamente 52 trocas. Na verdade, o programa ficaria bem mais elegante se usasse struct, mas não sei podia usar...
Obrigado cara, Agora to no trabalho, mas vou dando uma olhada pra entender e vou tentando fazer durante a semana, struct não pode usar ainda não, só vetores, arquivo texto(para armazenar daods do jogo a serem mostrados no final), funções e procedimentos com passagem de parâmetros... []'s Jeferson Neves
Você pode fazer um vetor de struct.
struct Carta {
    int numero; // 1 2 3 4 5 6 7 8 9 10 11 12 13 repreentando de A a K
    int naipe;    // 1 = Ouros, 2 = Espada, 3 = Copas, 4 = Paus
    //Se preferir, pode usar char * e colocar os nomes completos..
}

//e depois fazer.

struct Carta Baralho[52];

Baralho[0].letra = 1;  
Baralho[0].naipe = 1; 

//assim você guarda todas as cartas.

//Para embaralhar, você pode ser uma função geradora de pseudo-aleatórios, por exemplo srand, etc, pesquise sobre isso.
//Ai você gera um número aleatório entre 0 e 51 para pegar aleatoriamente as cartas.

Muito obrigado pela atenção, mas não posso usar struct neste trabalho, mas mais uma vez obrigado, irei seguir a dica do amigo abaixo e posteriormente irei postando minhas dificuldades.

[]'s

Jeferson Neves.

Editado por Jefers0n
Link para o comentário
Compartilhar em outros sites

  • 0
Você poderia criar dois vetores: um para o numero e outro para o naipe.

#include <stdlib.h>

int main(){
    int num [52], i, j, ai;
    char naipe [52], ac;

    for (i = 0; i < 52; i++) { //inicialização
        num[i] = i / 4 +1;
        
        switch (i%4) {
            case 0: naipe[i] = 'c';    break; //copas
            case 1: naipe[i] = 'e'; break; //espada
            case 2: naipe[i] = 'o'; break; //ouros
            case 3: naipe[i] = 'p'; break; //paus
        }
    }
    
    for (i = 0; i < 52; i++) { //embaralhar;
    
        do {
            j = rand()%52;
        } while (i == j);
        
        ai = num[i];
        num[i] = num[j];
        num[j] = ai;
        
        ac = naipe[i];
        naipe[i] = naipe[j];
        naipe[j] = ac;
    }
}
Na inicialização, ele pega as quatro primeiras cartas e pões numero 1, da quinta a oitava, 2, da nona até a 12, 3... até todas terem um número. No final, cada número terá quatro cartas (Haverá 4 cartas 13, 4 cartas 12...). Para cada uma dessas quatro cartas, ele põe um naipe. Se você colocar printf dentro desse loop, dá para ver como as cartas são "criadas". Para embaralhar, usei a função rand. Ele pega cada poisção do vetor e troca por outra aleatória. Observe que o do..while, que garante que haverá exatamente 52 trocas. Na verdade, o programa ficaria bem mais elegante se usasse struct, mas não sei podia usar...
Dei uma lida e uma pensada, mas tive umas duvidas no teu codigo(não testei ainda...), só pra mim me ambientar e entender melhor, o que seriam as variáveis ai e ac(sei que tem a ver com o indice das cartas e ao naipe, mas to meio perdido) neste trecho abaixo não se poder tem problema de divisão por zero, na primeira passada, quando o i é zero? já aproveitando, não entendi bem como aqui ele ira atribuir 1 as priemiras quatro cartas, 2 para as proximas 4 cartas...Se puder me dar uma explicada do funcionamento do código te agradeço. A parte do switch achei interessante, entendi o funcionamento, mas nunca tinha usado ele assim com um mod ali...boa lógica!
for (i = 0; i < 52; i++) { //inicialização
        num[i] = i / 4 +1;

Se puder dar uma explicada na parte de embaralhar tb, pois ta meio confuso pra mim, to sendo chato assim pois terei de apresentar este trabalho e será cobrado o código, se eu não souber o que o codigo faz corro risco de redução da nota ou se eu me atrapalhar para explicar ao ponto de acharem que não foi eu quem fez anularem o trabalho :(

[]'s

Jeferson Neves

Link para o comentário
Compartilhar em outros sites

  • 0

É mais ou menos assim: quando você faz uma divisão inteira de um número x por um número y, se você analisar bem, ficam sempre y números repetidos, por exemplo:

f(x) = x/3:

se você começar a tabelar a partir de zero, fica assim:

0 -> 0

1 -> 0

2 -> 0

3 -> 1

4 -> 1

5 -> 1

6 -> 2

7 -> 2

8 -> 2

9 -> 3...

Nesse caso, ficam sempre 3 números iguais, porque estou dividindo por três

Aí eu me aproveitei disso para inicializar várias variáveis com o mesmo valor.

num[i] = i / 4 +1;
A parte de somar 1 serve para não inicializar cartas com o valor 0, pois como você viu no exemplo, as três primeiras começam com 0.
for (i = 0; i < 52; i++) { //embaralhar;
    
        do {
            j = rand()%52;
        } while (i == j);
        
        ai = num[i];
        num[i] = num[j];
        num[j] = ai;
        
        ac = naipe[i];
        naipe[i] = naipe[j];
        naipe[j] = ac;
    }
A função rand gera um valor aleatório entre 0 e (algum número grande). Só que eu quero números aleatórios entre 0 e 51, para isso eu peguei o resto de rand() por 52, pois os valores que essa conta pode dar estão entre 0 e 51. Eu ponho o loop controlado por i que vai de 0 a 51, ou seja, passando por todas as cartas do baralho. Eu pego um valor aleatório j entre 0 e 51, usando a função rand(), e troco os valores das variáveis que estão na posição i e j. Repetindo isso 52 vezes, o baralho fica bem embaralhado.
do {
            j = rand()%52;
        } while (i == j);

Sobre o trecho acima, existe a possibilidade de o valor aleatório j que eu pegar ser igual ao indíce i. Nesse caso, eu trocaria variáveis que estão na mesma posição, seria trocar 6 por meia dúzia. Aí essa repetição garante que eu vá pegar valores aleatórios distintos e efetivamente trocar 52 vezes.

Ah, não pode dar divisão por zero, pois isso só é um erro quando o 0 está na parte de baixo, mas o que está na parte de baixo é o 4.

Editado por Luiz Rodrigo
Link para o comentário
Compartilhar em outros sites

  • 0
É mais ou menos assim: quando você faz uma divisão inteira de um número x por um número y, se você analisar bem, ficam sempre y números repetidos, por exemplo:

f(x) = x/3:

se você começar a tabelar a partir de zero, fica assim:

0 -> 0

1 -> 0

2 -> 0

3 -> 1

4 -> 1

5 -> 1

6 -> 2

7 -> 2

8 -> 2

9 -> 3...

Nesse caso, ficam sempre 3 números iguais, porque estou dividindo por três

Aí eu me aproveitei disso para inicializar várias variáveis com o mesmo valor.

num[i] = i / 4 +1;
A parte de somar 1 serve para não inicializar cartas com o valor 0, pois como você viu no exemplo, as três primeiras começam com 0.
for (i = 0; i < 52; i++) { //embaralhar;
    
        do {
            j = rand()%52;
        } while (i == j);
        
        ai = num[i];
        num[i] = num[j];
        num[j] = ai;
        
        ac = naipe[i];
        naipe[i] = naipe[j];
        naipe[j] = ac;
    }
A função rand gera um valor aleatório entre 0 e (algum número grande). Só que eu quero números aleatórios entre 0 e 51, para isso eu peguei o resto de rand() por 52, pois os valores que essa conta pode dar estão entre 0 e 51. Eu ponho o loop controlado por i que vai de 0 a 51, ou seja, passando por todas as cartas do baralho. Eu pego um valor aleatório j entre 0 e 51, usando a função rand(), e troco os valores das variáveis que estão na posição i e j. Repetindo isso 52 vezes, o baralho fica bem embaralhado.
do {
            j = rand()%52;
        } while (i == j);
Sobre o trecho acima, existe a possibilidade de o valor aleatório j que eu pegar ser igual ao indíce i. Nesse caso, eu trocaria variáveis que estão na mesma posição, seria trocar 6 por meia dúzia. Aí essa repetição garante que eu vá pegar valores aleatórios distintos e efetivamente trocar 52 vezes. Ah, não pode dar divisão por zero, pois isso só é um erro quando o 0 está na parte de baixo, mas o que está na parte de baixo é o 4.
Bom dia, obrigado pela atenção. Testei seu código em casa(em windows) e funciona legal, so que ao embaralhar ta gerando algumas cartas 5 vezes(executei algumas vezes e vi por ex. 5 cartas 9, 5 cartas 11" uma carta com um naipe repetido"), mas gera 52 cartas. Coloquei o printf assim(veja se não foi eu que coloquei errado...)
for (i = 0; i < 52; i++) { //embaralhar;
    
        do {
            j = rand()%52;
        } while (i == j);

        ai = num[i];
        num[i] = num[j];
        num[j] = ai;
        
        ac = naipe[i];
        naipe[i] = naipe[j];
        naipe[j] = ac;

        printf("%d-%c\n", num[i], naipe[i]);
    }
    system("pause");
}

*** Coloquei o printf imprimindo num[j] e naipe[j](também imprimiu algumas cartas com um naipe repetido) também, mas depois coloquei como acima, que o valor de j vai para o i acho que ta certo assim como deixei acima, me corrija se estiver errado.

[]'s

Jeferson Neves

Editado por Jefers0n
Link para o comentário
Compartilhar em outros sites

  • 0

O programa está gerando as cartas corretamente, sem repetição, mas parece que o problema está na hora de embaralhar. Testei aqui e repetiu três vezes o 9c...vou dar uma olhada para ver se consigo resolver esse problema.

edit:

Na verdade, o "erro" estava em colocar o printf() dentro do loop que embaralha. É que usando esse método, eu não necessariamente troco cada carta uma vez, eu troco cada posição uma vez. Daí ele poderia escrever a carta agora, só que a carta poderia mudar de posição e mais a frente ele a escreveria de novo.

Por exemplo, imagine a seqüência de números abaixo:

1 2 3 4 5 6

Na segunda iteração, ele imprimiria 2. Mas imagine que trocássemos o dois pelo cinco:

1 5 3 4 2 6

Quando iterasse pela quinta vez, imprimiria o 2 de novo, e era isso que estava acontecendo.

Se você criar um outro loop para escrever as cartas, fora do bloco para embaralhar, você pode perceber que está funcionando normalmente.

Qualquer coisa, estamos aí! B)

Editado por Luiz Rodrigo
Link para o comentário
Compartilhar em outros sites

  • 0
O programa está gerando as cartas corretamente, sem repetição, mas parece que o problema está na hora de embaralhar. Testei aqui e repetiu três vezes o 9c...vou dar uma olhada para ver se consigo resolver esse problema.

edit:

Na verdade, o "erro" estava em colocar o printf() dentro do loop que embaralha. É que usando esse método, eu não necessariamente troco cada carta uma vez, eu troco cada posição uma vez. Daí ele poderia escrever a carta agora, só que a carta poderia mudar de posição e mais a frente ele a escreveria de novo.

Por exemplo, imagine a seqüência de números abaixo:

1 2 3 4 5 6

Na segunda iteração, ele imprimiria 2. Mas imagine que trocássemos o dois pelo cinco:

1 5 3 4 2 6

Quando iterasse pela quinta vez, imprimiria o 2 de novo, e era isso que estava acontecendo.

Se você criar um outro loop para escrever as cartas, fora do bloco para embaralhar, você pode perceber que está funcionando normalmente.

Qualquer coisa, estamos aí! B)

Valeu,

To nesse momento tentando fazer este trabalho, mas to sem compilador(só acesso a net), to fazendo na mão mesmo em um caderno, pois estou no meu estágio, e to com tempo, mas to "apanhando", entendi o que tu falaste, eu não tinha pensado nisso.

Amanhã em casa vou fazer isso e testar, agora to tentando fazer outra coisa e to meio atrapalhado, tenho todas as 52 cartas embaralhadas em um vetor e em outro os 52 naipes respectivos de cada carta do outro vetor, eu tenho que "dar cartas" para iniciar o jogo após ter cadastrado os dois jogadores(fiz uma função de cadastro) e a máquina ter escolhido aleatoriamente quem inicia(outra função que já fiz), mas daí pra dar as cartas, tenho que dar 5 cartas para cada jogador(a máquina dá as cartas) e estas tem que ser removidas do baralho(vetor das 52 cartas e do vetor dos naipes), pensei em fazer dois vetores de 5 posições, mas na hora de comprar uma carta ou juntar da mesa, não teria lugar, porisso a mão tem que ser um vetor de 6 posições(pra sempre ter uma sobrando), mas como fazer para dar as cartas, teoricamente tem que ir removendo uma posição do vetor de cartas e uma posição do vetor de naipes e colocar na primeira posição do vetor "mão1[]" e decrementar do vetor naipe e cartas, depois fazer isso para o vetor "mão2[]" p-ara que se inicie o jogo, mas como colocar isso numa função? to perdido nos parâmetros que vai ter que ter....Se puder me clarear as ideias agradeço....A manhã tenho aula vou tentar tirar mais duvidas também....

[]'s

Jeferson Neves

Link para o comentário
Compartilhar em outros sites

  • 0
[...]mas daí pra dar as cartas, tenho que dar 5 cartas para cada jogador(a máquina dá as cartas) e estas tem que ser removidas do baralho(vetor das 52 cartas e do vetor dos naipes), pensei em fazer dois vetores de 5 posições, mas na hora de comprar uma carta ou juntar da mesa, não teria lugar, porisso a mão tem que ser um vetor de 6 posições(pra sempre ter uma sobrando), mas como fazer para dar as cartas, teoricamente tem que ir removendo uma posição do vetor de cartas e uma posição do vetor de naipes e colocar na primeira posição do vetor "mão1[]" e decrementar do vetor naipe e cartas, depois fazer isso para o vetor "mão2[]" p-ara que se inicie o jogo, mas como colocar isso numa função? [...]

Em vez de "remover" as cartas do baralho, você poderia criar uma função que retornasse o valor da carta mais "no topo", ou mais "no fundo", tanto faz, e, depois de puxada, colocasse o número da carta como um 0 (ou qualquer outro valor à sua escolha). Daí, da próxima vez que você fosse pegar uma carta, deveria pegar a carta mais no topo que não fosse 0.

Na hora de puxar uma carta ou comprar, você não fica com 6 cartas na mão. Você primeiro vê se quer a carta, descarta uma da sua mão e puxa a carta desejada.

Você poderia perguntar a cada rodada se o jogador deseja puxar uma carta do baralho ou pegar a ultima carta descartada. Dai ele selecionava a carta que queria descartar e você trocava a carta (do baralho) pela carta que quer descartar.

Link para o comentário
Compartilhar em outros sites

  • 0
[...]mas daí pra dar as cartas, tenho que dar 5 cartas para cada jogador(a máquina dá as cartas) e estas tem que ser removidas do baralho(vetor das 52 cartas e do vetor dos naipes), pensei em fazer dois vetores de 5 posições, mas na hora de comprar uma carta ou juntar da mesa, não teria lugar, porisso a mão tem que ser um vetor de 6 posições(pra sempre ter uma sobrando), mas como fazer para dar as cartas, teoricamente tem que ir removendo uma posição do vetor de cartas e uma posição do vetor de naipes e colocar na primeira posição do vetor "mão1[]" e decrementar do vetor naipe e cartas, depois fazer isso para o vetor "mão2[]" p-ara que se inicie o jogo, mas como colocar isso numa função? [...]

Em vez de "remover" as cartas do baralho, você poderia criar uma função que retornasse o valor da carta mais "no topo", ou mais "no fundo", tanto faz, e, depois de puxada, colocasse o número da carta como um 0 (ou qualquer outro valor à sua escolha). Daí, da próxima vez que você fosse pegar uma carta, deveria pegar a carta mais no topo que não fosse 0.

Na hora de puxar uma carta ou comprar, você não fica com 6 cartas na mão. Você primeiro vê se quer a carta, descarta uma da sua mão e puxa a carta desejada.

Você poderia perguntar a cada rodada se o jogador deseja puxar uma carta do baralho ou pegar a ultima carta descartada. Dai ele selecionava a carta que queria descartar e você trocava a carta (do baralho) pela carta que quer descartar.

Entendi, mas uma outra coisa, a mão acho que precisa ter 6 posições, pois no enunciado informa que quando comprar do baralho tem que largar uma carta(ai funciona como você falou), mas quando juntar uma carta da mesa, não é obrigado a largar uma carta...(to meio perdido, se bem que se eu for juntar uma carta vai ser pra largar, pois o objetivo do jogo e somar treze(uma ou mais cartas da mão)e largar... ), bom vou tentando fazer e quando não sair mais nada peço ajuda... :)

Um abraço.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...