Ir ao conteúdo

Posts recomendados

Postado

Ola a todos. 

Eu estou desenvolvendo um trabalho de Algoritmos e programação e tenho um problema no código. A função do trabalho é criar um caça palavras em c++ que lei 20 palavras. 

Cada palavra deve ter de 5 a 10 letras. Após isso, as palavra devem ser passadas para uma função externa que deve sortear a posição e Direcção da palavra dentro de uma matriz de 16x16. Alem de sortear a Direcção, o programa deve impedir que as palavras saiam da matriz ou sejam colocadas sobre outras ja existentes. 

Abaixo vai o código:

 

<

#include<stdio.h>
#include<locale.h>
#include<string.h>
#include<stdlib.h>
/*Trabalho de programaçao. */
char boas_vindas(){//Dá boas vindas.
printf("Olá, isso é um CAÇA-PALAVRAS em c++.\nVocê deverá informar 20 palavras para compor o quadro\n\nElas deverão ter de 5 a 10 letras.\n\n\n");}

struct palavras{
char pala[10];
double situacao;};

char esconder(char *q){
char letras[26] = {"abcdefghijklmnopqrstuvxwyz"};
int i, j, n, a, t;
i=0;
while(i<256){
n=rand()%26;
if(*q!='\0' && *q=='$'){*q=letras[n];} i++; q++;}}

char colocar_palavra(int l, char palavra[10], char p[16][16], char *n){
int posj, posi, pi, pj, dir, i, j, a, b;
int x, y, o, t, s;

a=0;
while(a==0){
posi=rand()%16;
posj=rand()%16;
b=0; o=0;
while(b==0 || o<36){
dir=rand()%6;
i=posi; j=posj;
t=0;
//=====Verificaçao 1====== {Se esta dentro dos limites da matriz}
if(dir!=0){
if(dir==1){/*Direita*/ j=j+l-1;} else {
if(dir==2){/*Esquerda*/ j=j-l+1;} else {
if(dir==3){/*Cima*/ i=i-l+1;} else {
if(dir==4){/*Baixo*/ i=i+l-1;} else {
if(dir==5){/*Diagonal Cima*/ i=i-l+1; j=j-l+1;} else {
if(dir==6){/*Diagonal Baixo*/ i=i+l-1; j=j+l-1;}}}}}}
//========================
//======Verificaçao 2======
if(j>=0 && j<=15 && i>=0 && i<=15){
if(dir==1){for(x=0, pi=posi, pj=posj, t=0; x!=l; x++){if(p[pi][pj] == palavra[x]){t++;} pj++;}} else {
if(dir==2){for(x=0, pi=posi, pj=posj, t=0; x!=l; x++){if(p[pi][pj] == palavra[x]){t++;} posj--;}} else {
if(dir==3){for(x=0, pi=posi, pj=posj, t=0; x!=l; x++){if(p[pi][pj] == palavra[x]){t++;} posi--;}} else {
if(dir==4){for(x=0, pi=posi, pj=posj, t=0; x!=l; x++){if(p[pi][pj] == palavra[x]){t++;} posi++;}} else {
if(dir==5){for(x=0, pi=posi, pj=posj, t=0; x!=l; x++){if(p[pi][pj] == palavra[x]){t++;} posi--; posj--;}} else {
if(dir==6){for(x=0, pi=posi, pj=posj, t=0; x!=l; x++){if(p[pi][pj] == palavra[x]){t++;} posi++; posj++;}}}}}}}
if(t<=1){b=1;} else {b=0;}
} else {b=0;}} else {b=0;}
o++;}if(b==1){a=1;} else {a=0;}}
//======Coloca a palavra========
if(dir==1){for(x=0; x!=l; x++){p[posi][posj]=palavra[x]; posj++;}} else {
if(dir==2){for(x=0; x!=l; x++){p[posi][posj]=palavra[x]; posj--;}} else {
if(dir==3){for(x=0; x!=l; x++){p[posi][posj]=palavra[x]; posi--;}} else {
if(dir==4){for(x=0; x!=l; x++){p[posi][posj]=palavra[x]; posi++;}} else {
if(dir==5){for(x=0; x!=l; x++){p[posi][posj]=palavra[x]; posi--; posj--;}} else {
if(dir==6){for(x=0; x!=l; x++){p[posi][posj]=palavra[x]; posi++; posj++;}}}}}}}
//printf("%d\n", dir);
//==============================
printf("\n\n");
for(i=0; i<16; i++){for(j=0; j<16; j++){printf("%c ", p[i][j]);} printf("\n");}
//=====Retorno==================
for(i=0; i<16; i++){for(j=0; j<16; j++){*n=p[i][j]; n++;}}}

main(){
char p[16][16], palavra[10], *t, dir[15];
int i, j, l, q, c;
struct palavras n[20];
srand((unsigned)time(NULL));
// -----------------Limpador ----------------
t=&p; i=(int) t +257;
for( ; t<i; t++){*t='$';}
// ------------------------------------------
boas_vindas();
//--------------Recebe a palavra-------------
for(q=0; q<20; q++){printf("\nInforme a palavra %d:", q+1);
l=0;
while(l<5 || l>10){gets(palavra);
for(l=0; palavra[l]!='\0'; l++);
if(l<5 || l>10){printf("\nOpps, tente outra:");}}
colocar_palavra(l, palavra, p, p);
//=====Armazena palavra=======
strcpy(n[q].pala, palavra);
n[q].situacao=0;
l=0;}
//=======Esconde==========
if(p[0][0]=='\n'){p[0][0]='$';}
esconder(p);
printf("\n\n\n");
for(i=0; i<16; i++){
for(j=0; j<16; j++){printf("%c ", p[i][j]);} printf("\n");}
printf("\n\n Palavras a serem procuradas:\n");
for(q=0; q<20; q++){printf("%s ", n[q].pala); if(q%4==0 && q!=0){printf("\n");}}

printf("\n\nVamos procurar. voce deve informar a palavra, direcao e posicao:\n");
while(q>=0){
printf("Informe a palavra:");
gets(palavra);
printf("Informe a direcao (cima, baixo, esquerda, direita, diagonal cima, diagonal baixo):");
gets(dir);
printf("Informe posicao (L) (C) [Ex: 12 0]:");
scanf("%d %d", &l, &c);

if(i==0){printf("Nao encontrado.");} else {q--;}
}


}

>

 

O problema é que o código que verifica as colisões (======Verificação 2=======) ano funciona correctamente, sendo que as colisões continuam acontecendo. Foi feito de tudo e não foi possível achar a falha. Peço a ajuda de vocês para achar o problema. 

Muito obrigado e um ótimo ano novo para todos. 

 

Codigo.txt

  • Amei 1
Postado

@Filipe S. Kaizer     seu código não está compilando , apresenta erro nessas linhas aqui :

// -----------------Limpador ----------------
t = &p; 
i = (int) t + 257;
for( ; t<i; t++ )
{ 
    *t = '$';
}
// ------------------------------------------

você precisa mesmo usar ponteiro para inserir caracteres nessa matriz ?  ,  ou pode ser do modo tradicional mesmo ?  usando dois Loop's um dentro do outro e colocando o caractere nas posições apontados pela variáveis de controle dos dois Loop's ?  ,  mais ou menos assim  :

for(int _x=0; _x<16; _x++)
    for(int _y=0; _y<16; _y++)
        p[_x][_y} = '$';

 

  • Curtir 1
Postado
Em 09/01/2021 às 20:43, Filipe S. Kaizer disse:

A função do trabalho é criar um caça palavras em c++ que lei 20 palavras

 

Em C++? Mas postou um programa em C. Qual a linguagem que precisa usar?

Vai mesmo obrigar quem for usar o programa --- e você mesmo ao testar --- a digitar VINTE palavras a cada vez? Ou 5? É muito ch@t0 e demora demais. Faça o simples: use um arquivo com as palavras. É muito mais fácil. Pra todos. 

 

O botão "code"

 

image.png.64c7902973e308d37ef1cdf9733cf96f.pngTalvez a legenda do forum não seja muito feliz. Isso é um botão que você usa e abre um formulário onde você cola o seu código. Não é para você colocar um '<' e um '>' depois do seu código. Veja o efeito em outros programas aqui no forum e compare com o que fez...

 

De volta ao programa
 

Seu programa está muito complicado. Não é um problema trivial e a maneira como escreveu não vai ajudar. Escreva seu programa em torno dos dados e terá muito menos trabalho. Seus dados são as palavras e o tabuleiro. E o controle do jogo.
 

Isso abaixo foi a maior parte do que usou:

 

struct palavras {
	char pala[10];
	double situacao;
};

char p[16][16], palavra[10], *t, dir[15];
int i, j, l, q, c;
struct palavras n[20];

 

  • que pretende com double 'situacao'? 
  • não declare mais que uma variável por linha. As linhas são grátis.
  • não misture ponteiros no meio das declarações. Qual o tipo de 't'? 't' é char* então declare como tal. Como está começando é uma oportunidade de evitar esses vícios comuns.
     
  • essa construção é supérflua:
     
    	// -----------------Limpador ----------------
    	t = &p; i = (int)t + 257;
    	for (; t < i; t++) { *t = '$'; }


    Use memset(). Muito mais simples:
     

    	memset(p, '$', sizeof(p) / sizeof(char));

     

Sim, pode escrever direto o tamanho, claro:
 

	memset(p, '$', 256);

 

mas o primeiro caso é genérico, calcula o tamanho sozinho.

E mesmo que precisasse usar essa construção nunca declare assim. Desde o final dos anos 80 não se faz isso. Use
 

	for (int i = 0; i < 256; i++) *(&p[0][0] + i) = '$';

 

Que faz exatamente a mesma coisa. Não há razão para usar outro ponteiro, o 't'. E declare a variável de controle DENTRO do for. Só fica mais difícil de ler e vai ficar com essa variável t 'viva' durante todo o programa.

 

14 horas atrás, devair1010 disse:

usando dois Loop's um dentro do outro e colocando o caractere nas posições apontados pela variáveis de controle dos dois Loop's ?  ,  mais ou menos assim  :


for(int _x=0; _x<16; _x++)
    for(int _y=0; _y<16; _y++)
        p[_x][_y} = '$';

 

Pois é: não precisa nem disso, @devair1010. Basta um loop como acima. Ou o normal: use memset() que foi escrita para isso.

 

Exemplo:

Considere uma estrutura como essa:
 

typedef struct
{
	char nTotal; // total de palavras: 20?
	char nEnc; // ja encontradas
	char palavras[20][10]; // palavras
	char pos[20]; // as posições
	char quadro[16][16]; // quadro

} Jogo;

 

Ao declarar um jogo você lê as palavras, prepara o tabuleiro e coloca as palavras. Não parece mais simples?

E pode ter vários jogos ao mesmo empo. Multiplayer ;) E na tabela já estão as posiçoes de cada palavra assim não precisa mais testar durante o jogo.

 

"esconder"

 

Colocar as palavras no grid pode ser mais fácil se sortear primeiro a direção e depois partir do tamanho da palavra, porque isso vai dar os limites do quadro onde ela cabe... Algo simples como 0..5 para a direção e depois considere o tamanho da palavra e define a origem dela e com a direção coloque as letras. 

Antes de tudo preencha o grid com letras. É mais fácil. 

Use maiúsculas para o tabuleiro. É mais fácil de ler e é o tradicional das revistas....

 

  • não use gets(). Nunca. É marcada como obsoleta há décadas e proibida em todo lugar. E não ajuda em nada.
  • leia o retorno de scanf(). Sempre.
  • leia a palavra e a direção numa linha só. É chato digitar duas vezes para cada jogada numa coisa tão simples.
  • mantenha na tela uma lista das palavras já localizadas. Numa versão 'plus' faça como os jogos e MARQUE no quadro as palavras já encontradas, o tempo já gasto e o número de palavras ainda a encontrar.

 

 

 

Num programa desses a primeira função que você escreve é uma que mostra o tabuleiro... Porque não?

  • Curtir 1
  • Obrigado 1
Postado

Voltando a esse problema...

Vários jogos de palavras podem ser implementados assim.

 

Com até 20 palavras numa grade 16x16 pode ser até difícil encaixar todas as palavras.

 

Uma maneira comum de tratar a colisão é usar um bitmask. As palavras tem uma origem, um comprimento e um sentido: a definição matemática de vetor afinal: módulo, direção e sentido. Vou mostrar uma maneira de escrever isso. Numa certa posição podem ter palavras passando em 8 direções. Pode ser interessante permitir que palavras se cruzem em direções diferentes, em geral nos problemas que vem em revistas pode. 

 

Algo assim com ANEL, CLUBE e AZUL por exemplo [1]
 

                           C
                           L
                     A  Z  U  L
                        N  B
                           E
                              L

 

Para as direções podemos usar o óbvio: os pontos cardeais conhecidos há milênios: Norte, Sul, Leste, Oeste, Sudeste, Sudoeste, Nordeste e Noroeste não são assim novidades. Só que isso já inclui a direção e o sentido e é melhor separar no programa porque afinal CLUBE para o leste seria EBULC para o oeste :) 

 

As direções podem ser horizontal, vertical, diagonal principal e secundária (4), como em:
 

    03 01 04
    02 XX 02
    04 01 03

 

E colocando um sentido
 

	NO   N   NE
	OE  XXX  LE
	SO   S   SE

 

E assim fica fácil. Usando um bit para cada um:
 

     1 - 0 para vazio, 1 para ocupado
     2 - vertical
     4 - diagonal principal
     8 - horizontal
    16 - diagonal secundária
    32 - 0 para direita 1 para esquerda

 

Assim pode tratar todos os cruzamentos dependendo do jogo e da regra. Colocando os valores para as direções aqui
 

    48  02 04   
    40  XX 08
    36  34 16 

 

Para o exemplo [1] o 'U' teria o valor 10, 2+8 e o 'E' teria o valor 6, 2 + 4. Isso sem aceitar duas palavras em sentidos opostos, como seria aceitar CLUBEVENTO ou CLUBESET para CLUBE e EVENTO e CLUBE e TESE. Para esse caso teria que mudar a representação.

 

Uma estrutura assim serviria para o jogo

typedef struct
{
	uint8_t nTotal;	// total de palavras: 20?
	uint8_t nEnc;	// ja encontradas
	char	palavras[20][10];	// palavras
	char	pos[20][3];			// as posições
	char	quadro[16][16];		// quadro
	uint8_t status[16][16];		// mapa de uso 

} Jogo;

 

Com o conteúdo óbvio: o quadro com as letras, o status com os valores. pos com as posições das palavras para facilitar.

 

E o quadro?

image.png.470dd0db9f7fd3c3c16f69a55c7f9e45.png

 

antes de tudo tem que ter uma representação do grid, e uma notação como a das planilhas não seria assim desconhecida para ninguém.

 

Pode ajudar no jogo afinal, aceitando B12 por exemplo como uma "jogada" é bem melhor que ficar perguntando linha e coluna e para ver na tela as posições fica mais rápido. E em algumas revistas é assim mesmo. E no Excel ;) 

 

E é fácil de escrever. Veja um exemplo que mostra essa a partir da struct de exemplo:
 

int		mostra(Jogo* J, const char* mensagem)
{
	printf("\n\t%s\n\n", mensagem);
	printf("\t\
A   B   C   D   E   F   G   H   \
I   J   K   L   M   N   O   P\n\t\
--------------------------------\
-----------------------------\n");
	for (int i = 0; i < 16; i += 1)
	{
		printf("%2d   |  ", 1 + i);
		for (int j = 0; j < 16; j += 1)
			printf("%c   ", J->quadro[i][j]);
		printf("|  %2d\n\n", 1 + i);
	};
	printf("\t\
--------------------------------\
-----------------------------\n\
	A   B   C   D   E   F   G   H   \
I   J   K   L   M   N   O   P\n");

	printf("\nTotal de palavras: %d. Encontradas: %d\n",
           J->nTotal, J->nEnc);
	return 0;
};

 

 

 

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!