Jump to content

Jogo Simon Says


PsySc0rpi0n
 Share

Recommended Posts

Boas...

Andava aqui a tentar implementar este jogo mas depois é para adaptar para sistemas embebidos..

De qualquer maneira o que queria era pedir ajuda para descobrir porque é que o código que já tenho não está a funcionar.

O jogo consiste em o cpu gerar uma sequência aleatória de algarismos, mostrar essa sequência e depois o jogador é suposto repetir essa sequência.

Esta é a ideia básica. Agora os pormenores.

O jogo vai subindo de dificuldade consoante as tentativas acertadas, ou seja, no nível 1, a sequência de números é apenas um número. No nível 2, a sequência tem 2 algarismos, no nível 3, tem 3 números e por aí adiante.

O jogo deve correr mais ou menos assim:

começa o jogo

1ª sequência aleatória - nível 1 - apenas um algarismo

espera pela introdução da sequência por parte do jogador

verifica se a sequência introduzida pelo jogador é igual à gerada pelo cpu

se acertou, sobe de nível (2)

gera seqência com 2 números

etc

etc

etc.

No código que tenho, apenas ainda criei uma função que gera números aleatoriamente consoante o nível de jogo e os guarda numa variável e uma outra função que mostra a sequência gerada.

Mas por alguma razão, a coisa não está a funcionar!

Aqui fica o code para me darem pistas do que está errado

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
void random_sequence (uint8_t game_level, uint8_t *rand_sequence){

   for (uint8_t i = 0x00; i < game_level; i++)
    *(rand_sequence + i) = rand () % game_level + 0x01;
}
void print_cpu_random_sequence (uint8_t game_level, uint8_t *rand_sequence){
   uint8_t index = 0x00;
   while (index < game_level) {
    putchar (*rand_sequence++);
    putchar ('\n');
    index++;
   }
}
uint16_t main (int argc, char **argv){
   uint8_t //*player_sequence,
	    //*tmp_sequence,
	    game_level = 0x00;

   srand (time (NULL));

   while (0x01){
    printf ("Ready to play?\n");
    getchar ();
    game_level++;
    printf ("Game Level %d:\n", game_level);
    uint8_t rand_sequence [game_level];
    random_sequence (game_level, rand_sequence);
    print_cpu_random_sequence (game_level, rand_sequence);
    if (game_level == 5)
	    break;
   }
   return 0x00;
}

Para não estar a estragar a identação do code, não vou eidtar o post anterior.

A compilação não dá erros que eu não saiba o que são, mas acho que algo deve estar mal nas duas funções que tenho criadas!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

void random_sequence (uint8_t game_level, uint8_t *rand_sequence) {
   for (uint8_t i = 0x00; i < game_level; i++)
       *(rand_sequence + i) = (rand () % 10) + '0'; // queres um dígito entre 0 e 9
}

void print_cpu_random_sequence (uint8_t game_level, uint8_t *rand_sequence) {
   uint8_t index = 0x00;
   while (index < game_level) {
       putchar (*rand_sequence++);
       index++;
   }
   putchar ('\n'); // fim de linha só depois de apresentar toda a sequência
}

uint16_t main (int argc, char **argv) {
   uint8_t game_level = 0x00;

   srand (time (NULL));

   while (0x01){
       printf ("Ready to play?\n");
       getchar ();

       game_level++;

       printf ("Game Level %d:\n", game_level);
       uint8_t rand_sequence[game_level];
       random_sequence (game_level, rand_sequence);
       print_cpu_random_sequence (game_level, rand_sequence);

       // TODO : pedir a sequencia ao utilizador
       // TODO : comparar com a sequencia gerada

       if (game_level == 5)
           break;
   }

   return 0x00;
}

edit : corrgido

Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Boas...

Bem o code está a funcionar quase bem, fora 2 pormenores...

1 - O nível de jogo está a saltar de 2 em 2 em vez de ir aumentando 1 a 1.

2 - Se o utilizador, quando estiver a introduzir a sequência de algarismos, carregar no enter antes de terminar a sequência completa, na consola, o cursor desce uma linha e continua a pedir o resto dos algarismos e entretanto, se o nível já estiver em 5 ou mais, se calhar o jogador acaba por se perder e não saber quantos algarismos ainda faltam para terminar a sequência.

Mas em primeiro queria tentar descobrir porque é que a variável "game_level" está a ser incrmentada 2 vezes em cada loop.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>

#define WRONG_SEQUENCE   0x00
#define CORRECT_SEQUENCE 0x01

#define CLRSCREEN puts ("\x1b[H\x1b[2J")

void random_sequence (uint8_t game_level, uint8_t *cpu_rand_sequence){
   for (uint8_t i = 0x00; i < game_level; i++)
       *(cpu_rand_sequence + i) = (rand () % 0x0A) + '0';
}

void print_cpu_random_sequence (uint8_t game_level, uint8_t *cpu_rand_sequence){
   uint8_t index = 0x00;
   while (index < game_level) {
       putchar (*cpu_rand_sequence++);
       index++;
   }
   putchar ('\n');
}

uint8_t check_player_sequence (uint8_t game_level, uint8_t *player_sequence, uint8_t *cpu_rand_sequence) {
   uint8_t index = 0x00;
   while (index < game_level) {
       if (*(player_sequence + index) == *(cpu_rand_sequence + index))
           index++;
       else {
           return WRONG_SEQUENCE;
       }
   }
   return CORRECT_SEQUENCE;
}

void memorize_waiting_time (uint8_t game_level) {
   /*for (uint16_t i = 0x00; i < 0xFFFF; i++)
       for (uint8_t j = 0x00; j < 0xFF; j++)
           for (uint8_t k = 0x00; k < 0xFF; k++);*/
   uint16_t wait_time;

   wait_time = time (0x00) + (game_level * 0x02);
       while (time (0x00) < wait_time);
}

uint16_t main (int argc, char **argv){
   uint8_t game_level = 0x00,
           ok;

   srand (time (NULL));

   while (0x01){
       printf ("Ready to play?\n");
       getchar ();

       game_level++;

       printf ("Game Level %d:\n", game_level);
       uint8_t cpu_rand_sequence [game_level];
       uint8_t player_sequence [game_level];
       random_sequence (game_level, cpu_rand_sequence);
       print_cpu_random_sequence (game_level, cpu_rand_sequence);

       /*waiting time to player memorize cpu_rand_sequence*/
       memorize_waiting_time (game_level);
       getchar ();
       CLRSCREEN;

       printf ("Enter the correct sequence:\n");
       for (uint8_t i = 0x00; i < game_level; i++)
           fscanf (stdin, " %c", (player_sequence + i));

       ok = check_player_sequence (game_level, player_sequence, cpu_rand_sequence);
       if (ok == WRONG_SEQUENCE){
           printf ("Wrong Sequence!\nGame Over\n");
           printf ("Corect sequence was: ");
           print_cpu_random_sequence (game_level, cpu_rand_sequence);
           putchar ('\n');
           exit (WRONG_SEQUENCE);
       }
   }
   return 0x00;
}

Fonix, já percebi a questão do game_level! lol

Mas preciso é de fazer a função que espera que o jogador memorize a sequência porque o que acho que tenho, não está a funcionar!

Que posso tentar fazer?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

Bem, tentei aqui usar o malloc e o realloc para ir alterando a dimensão das duas arrays mas agora está-me a dar um segmentation fault onde antes não havia problemas.

Se alguém me puder ajudar, a descobrir onde está o problema, agradecia.

Coloquei uns printfs para ver onde acontecia o erro e é imediatamente a seguir ao printf do 'B'

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define WRONG_SEQUENCE   0x00
#define CORRECT_SEQUENCE 0x01
#define MEM_ERROR	    0x02
#define MEM_RERROR	   0x03#define CLRSCREEN puts ("\x1b[H\x1b[2J")
void random_sequence (uint8_t game_level, uint8_t *cpu_rand_sequence){
   for (uint8_t i = 0x00; i < game_level; i++)
    *(cpu_rand_sequence + i) = (rand () % 0x0A) + '0';
   printf ("E\n");
}void print_cpu_random_sequence (uint8_t game_level, uint8_t *cpu_rand_sequence){
   uint8_t index = 0x00;
   while (index < game_level) {
    putchar (*cpu_rand_sequence++);
    index++;
   }
   putchar ('\n');
}
uint8_t check_player_sequence (uint8_t game_level, uint8_t *player_sequence, uint8_t *cpu_rand_sequence) {
   uint8_t index = 0x00;
   while (index < game_level) {
    if (*(player_sequence + index) == *(cpu_rand_sequence + index))
	    index++;
    else {
	    return WRONG_SEQUENCE;
    }
   }
   return CORRECT_SEQUENCE;
}void memorize_waiting_time (uint8_t game_level) {
   uint16_t wait_time;

   wait_time = time (0x00) + (game_level + 0x02);
    while (time (0x00) < wait_time);
}
void array_memory_realloc (uint8_t *str) {
   uint8_t str_length = sizeof (str);


   if ((realloc (str, str_length + 0x01)) == NULL){
    perror ("Memory reallocation error");
    exit (MEM_RERROR);
   }
}void array_memory_alloc (uint8_t *str) {
   if ((str = malloc (sizeof (uint8_t))) == NULL){
    perror ("Memory allocation error");
    exit (MEM_ERROR);
   }
}
int main (void){
   uint8_t *cpu_rand_sequence = NULL,
	    *player_sequence   = NULL,
	    game_level = 0x01,
	    ok;

   srand (time (NULL));

   array_memory_alloc (cpu_rand_sequence);
   array_memory_alloc (player_sequence);
   printf ("A\n");

   while (0x01){
    printf ("Ready to play?\n");
    getchar ();

    printf ("Game Level %d:\n", game_level);
    /*uint8_t cpu_rand_sequence [game_level];
    uint8_t player_sequence [game_level];*/
    printf ("B\n");
    random_sequence (game_level, cpu_rand_sequence);
    printf ("C\n");
    print_cpu_random_sequence (game_level, cpu_rand_sequence);
    printf ("D\n");

    /*waiting time to player memorize cpu_rand_sequence*/
    memorize_waiting_time (game_level);
    /*getchar ();*/
    CLRSCREEN;

    printf ("Enter the correct sequence:\n");
    for (uint8_t i = 0x00; i < game_level; i++)
	    fscanf (stdin, " %c", (player_sequence + i));

    ok = check_player_sequence (game_level, player_sequence, cpu_rand_sequence);
    if (ok == WRONG_SEQUENCE){
	    printf ("Wrong Sequence!\nGame Over\n");
	    printf ("Corect sequence was: ");
	    print_cpu_random_sequence (game_level, cpu_rand_sequence);
	    putchar ('\n');
	    exit (WRONG_SEQUENCE);
    } else
	    game_level++;
	    array_memory_realloc (cpu_rand_sequence);
	    array_memory_realloc (player_sequence);
   }
   free (cpu_rand_sequence);
   free (player_sequence);
   return 0x00;
}

Após criar duas funções, uma para alocar espaço e outra para realocar espaço nas duas arrays que tenho cpu_rand_sequence e player_sequence, dá o tal sementation fault.

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

Estive a experimentar o seguinte. Não dá erro mas também não dá o resultado que eu esperava e não percebi porquê:

#include <stdio.h>
#include <stdlib.h>
int main (void) {
   int *str = NULL,
    size = 0x00;

   if ((str = malloc (sizeof (int)*10)) == NULL) {
    perror ("Memory Error");
    exit (0x01);
   }

   size = sizeof (str);
   printf ("Size = %d\n", size);

   return 0x00;
}

Não deveria estar criada uma variável com 80 elementos? Sendo sizeof(int) igual a 8 e depoois multiplicando por 10, seriam 80 elementos... Não percebo porque é que está a dar sempre 8.

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

como disse, o problema é usares o sizeof sobre um ponteiro

sizeof de um ponteiro dá sempre 8 (ou 4 dependendo de uma máquina 32 ou 64 bits)

se queres saber o tamanho de uma região de memória alocada dentro de uma outra função, tens de não só passar o ponteiro mas tambem o tamanho tem de ir atrás

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Então como posso fazer para ir incrementando o número de elementos das duas variáveis consoante o nível do jogo vai aumentado?

Ou seja, no primeiro nível, as duas variáveis contém apenas um elemento. Quando se passa para o nível 2, essas mesmas variáveis devem ter 2 elementos e por aí fora.

Como posso fazer isto com o code que tenho?

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

str = malloc (sizeof (int)*10))

Não deveria estar criada uma variável com 80 elementos? Sendo sizeof(int) igual a 8 e depoois multiplicando por 10, seriam 80 elementos...

Deveria estar a dar 10 elementos, não 80. E o sizeof retorna 8 mas não 10 pelo motivo indicado pelo @Happy.

Então como posso fazer para ir incrementando o número de elementos das duas variáveis consoante o nível do jogo vai aumentado?

Ou seja, no primeiro nível, as duas variáveis contém apenas um elemento. Quando se passa para o nível 2, essas mesmas variáveis devem ter 2 elementos e por aí fora.

se queres saber o tamanho de uma região de memória alocada dentro de uma outra função, tens de não só passar o ponteiro mas tambem o tamanho tem de ir atrás

Edited by thoga31

Knowledge is free!

Link to comment
Share on other sites

Deveria estar a dar 10 elementos, não 80. E o sizeof retorna 8 mas não 10 pelo motivo indicado pelo @Happy.

Como 10 elementos? "sizeof (int)" não retorna 4 ou 8 dependendo da arquitectura do PC onde está a ser executado? Se retorna 4 ou 8, multiplicando por 10, como é que pode estar a dar 10 elementos e não 40 ou 80?

se queres saber o tamanho de uma região de memória alocada dentro de uma outra função, tens de não só passar o ponteiro mas tambem o tamanho tem de ir atrás

Mas isso é um pouco contraditório. Então se eu não sei o tamanho, como é que vou enviar para a outra função o tamanho???

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

Como 10 elementos? "sizeof (int)" não retorna 4 ou 8 dependendo da arquitectura do PC onde está a ser executado? Se retorna 4 ou 8, multiplicando por 10, como é que pode estar a dar 10 elementos e não 40 ou 80?

void* malloc (size_t size);

Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.

in http://www.cplusplus.com/reference/cstdlib/malloc/

Tu estás a indicar à função malloc que deve alocar 8*10=80 bytes de memória, não elementos.

Independentemente da arquitectura do PC, essa instrução criará sempre um array de 10 elementos.

Caso contrário, nem faria sentido usar o sizeof no malloc - não seria uma forma elegante de mostrar conhecimento.

Mas isso é um pouco contraditório. Então se eu não sei o tamanho, como é que vou enviar para a outra função o tamanho???

#include <stdio.h>

int thesize(int *v) {
   return sizeof v / sizeof v[0];
}

int main(void) {
   int v[] = {1,2,3,4};
   printf("%d vs %d", sizeof v /sizeof v[0], thesize(v));
   return 0;
}

4 vs 1

Quando envias um array por argumento, na verdade estás a passar um ponteiro. Portanto, o sizeof vai devolver o tamanho desse ponteiro.

Não tens grande alternativa se não conceber um método de passar o tamanho do array por argumento.

Edited by thoga31
  • Vote 1

Knowledge is free!

Link to comment
Share on other sites

Ok, realmente estava a fazer confusão com o malloc e com o sizeof quanto ao número de elementos criados eespaço ocupado por esses elementos.

Eu sei que aqui há uns tempos o HappyHippyHippo vez um code que fazia precisamente isso. Alterava o tamanho de uma variável dinamicamente e acho que não andava a passar o tamanho da variável por parâmetro... Mas já não sei em que circunstancia foi nem em que post isso andará agora.

Vou ver o que consigo engendrar!

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.