Program from a book not working?

Monado_III

Well-Known Member
OP
Member
Joined
Feb 8, 2015
Messages
722
Trophies
0
Location
/dev/null
XP
1,443
Country
Canada
So I'm gradually learning C from this: http://www.amazon.com/Beginning-From-Novice-Professional/dp/1590597354 but there's an example that fails to work (on Linux) even when I straight copy it from the book. The problem occurs as soon as the random input is shown, so I as soon as I press enter nothing appear and thus it is an impossible game as it never showed me the string of digits I'm supposed to repeat. I'd try and figure it out but for all I know, what this book says is outdated.


Code:
/* Program 4.12 Simple Simon */

#include <stdio.h>                     /* For input and output   */
#include <ctype.h>                     /* For toupper() function */
#include <stdbool.h>                   /* For bool, true, false  */
#include <stdlib.h>                    /* For rand() and srand() */
#include <time.h>                      /* For time() and clock() */

int main(void)
{
  /* Records if another game is to be played */
  char another_game = 'Y';

  /* true if correct sequence entered, false otherwise */
  int correct = false;

  /* Number of sequences entered successfully          */
  int counter = 0;

  int sequence_length = 0;     /* Number of digits in a sequence        */
  time_t seed = 0;             /* Seed value for random number sequence */
  int number = 0;              /* Stores an input digit                 */

  time_t now = 0;            /* Stores current time - seed for random values  */
  int time_taken = 0;        /* Time taken for game in seconds                */

  /* Describe how the game is played */
  printf("\nTo play Simple Simon, ");
  printf("watch the screen for a sequence of digits.");
  printf("\nWatch carefully, as the digits are only displayed"
                                                " for a second! ");
  printf("\nThe computer will remove them, and then prompt you ");
  printf("to enter the same sequence.");
  printf("\nWhen you do, you must put spaces between the digits. \n");
  printf("\nGood Luck!\nPress Enter to play\n");
  scanf("%c", &another_game);

  /* One outer loop iteration is one game */
  do
  {
    correct = true;         /* By default indicates correct sequence entered */
    counter = 0;            /* Initialize count of number of successful tries*/
    sequence_length = 2;    /* Initial length of a digit sequence            */
    time_taken = clock();  /* Record current time at start of game       */

    /* Inner loop continues as long as sequences are entered correctly */
    while(correct)
    {
      /* On every third successful try, increase the sequence length */
      sequence_length += counter++%3 == 0;

      /* Set seed to be the number of seconds since Jan 1,1970  */
      seed = time(NULL);

      now = clock();                  /* record start time for sequence  */

      /* Generate a sequence of numbers and display the number */
      srand((unsigned int)seed);      /* Initialize the random sequence */
      for(int i = 1; i <= sequence_length; i++)
        printf("%d ", rand() % 10);    /* Output a random digit          */

      /* Wait one second */
      for( ;clock() - now < CLOCKS_PER_SEC; );

      /* Now overwrite the digit sequence */
      printf("\r");                   /* go to beginning of the line */
      for(int i = 1; i <= sequence_length; i++)
        printf("  ");                 /* Output two spaces */

      if(counter == 1)           /* Only output message for the first try */
        printf("\nNow you enter the sequence  - don't forget"
                                               " the spaces\n");
      else
        printf("\r");                /* Back to the beginning of the line */

      /* Check the input sequence of digits against the original */
      srand((unsigned int)seed);     /* Restart the random sequence    */
      for(int i = 1; i <= sequence_length; i++)
      {
        scanf("%d", &number);         /* Read an input number         */
        if(number != rand() % 10)     /* Compare against random digit */
        {
          correct = false;            /* Incorrect entry             */
          break;                      /* No need to check further... */
        }
      }
      printf("%s\n", correct? "Correct!" : "Wrong!");
    }

    /* Calculate total time to play the game in seconds)*/
    time_taken = (clock() - time_taken) / CLOCKS_PER_SEC;

    /* Output the game score */
    printf("\n\n Your score is %d", --counter * 100 / time_taken);

    fflush(stdin);

    /* Check if new game required*/
    printf("\nDo you want to play again (y/n)? ");
    scanf("%c", &another_game);

  }while(toupper(another_game) == 'Y');
  return 0;
}
 
Last edited by Monado_III,

zoogie

playing around in the end of life
Developer
Joined
Nov 30, 2014
Messages
8,560
Trophies
2
XP
15,000
Country
Micronesia, Federated States of
are you on linux? If so how are you running it? Terminal won't display the digits and skips the 'press y to play again part' altogether.
nope windows, hence the .exe output.

--------------------- MERGED ---------------------------

rename the attached file and try it.
i have a theory why it didn't work.
 

Attachments

  • simon.txt
    4 KB · Views: 240

zoogie

playing around in the end of life
Developer
Joined
Nov 30, 2014
Messages
8,560
Trophies
2
XP
15,000
Country
Micronesia, Federated States of
what? pls explain, How did that save like 100 bytes? From what I can tell based off of google results that would've only affected a few bytes.
There's about 100 lines of 2 chars in the win version, so you go to one char per line ending in a unix text file and save 100 bytes. Sounds right 2 me. :P

Anyway. Put a getch(); after the
printf("%s\n", correct? "Correct!" : "Wrong!");

it's hacky but may fix the issue.
 
  • Like
Reactions: Monado_III

cdoty

Well-Known Member
Member
Joined
Sep 14, 2009
Messages
329
Trophies
0
Website
www.rastersoft.net
XP
352
Country
United States
So I'm gradually learning C from this: http://www.amazon.com/Beginning-From-Novice-Professional/dp/1590597354 but there's an example that fails to work (on Linux) even when I straight copy it from the book. The problem occurs as soon as the random input is shown, so I as soon as I press enter nothing appear and thus it is an impossible game as it never showed me the string of digits I'm supposed to repeat. I'd try and figure it out but for all I know, what this book says is outdated.

Replace this:

Code:
/* Now overwrite the digit sequence */
printf("\r"); /* go to beginning of the line */
for(int i = 1; i <= sequence_length; i++)
printf(" "); /* Output two spaces */

With this:
Code:
/* Now overwrite the digit sequence */
#if 0
printf("\r"); /* go to beginning of the line */
for(int i = 1; i <= sequence_length; i++)
printf(" "); /* Output two spaces */
#endif

And see if it shows the result.

It's designed to hide the sequence after 1 second.

The correct way to write this for loop:
Code:
for( ;clock() - now < CLOCKS_PER_SEC; );

is:

Code:
for ( ;clock() - now < CLOCKS_PER_SEC; )
{
}

Many compilers will generate a warning on the original version, because it it a common programming error to put a semicolon at the end of for or while loops.

This should probably be a while loop also.
Code:
while (clock() - now < CLOCKS_PER_SEC)
{
}
 
  • Like
Reactions: Monado_III

Monado_III

Well-Known Member
OP
Member
Joined
Feb 8, 2015
Messages
722
Trophies
0
Location
/dev/null
XP
1,443
Country
Canada
Replace this:

/* Now overwrite the digit sequence */
printf("\r"); /* go to beginning of the line */
for(int i = 1; i <= sequence_length; i++)
printf(" "); /* Output two spaces */

With this:
/* Now overwrite the digit sequence */
#if 0
printf("\r"); /* go to beginning of the line */
for(int i = 1; i <= sequence_length; i++)
printf(" "); /* Output two spaces */
#endif

And see if it shows the result.

It's designed to hide the sequence after 1 second.

The correct way to write this for loop:
for( ;clock() - now < CLOCKS_PER_SEC; );

is:

for ( ;clock() - now < CLOCKS_PER_SEC; )
{
}

Many compilers will generate a warning on the original version, because it it a common programming error to put a semicolon at the end of for or while loops.

This should probably be a while loop also.
while (clock() - now < CLOCKS_PER_SEC)
{
}
What do the hashtags do for #if and #endif
 

cdoty

Well-Known Member
Member
Joined
Sep 14, 2009
Messages
329
Trophies
0
Website
www.rastersoft.net
XP
352
Country
United States
They are compiler directives.

In this case, it removes the code between #if 0 and #endif from the program. It's a way to conditionally compile sections of code.

You'll usually see it used in something like this

#if defined Win32
... code for Windows
#elif defined OSX
... code for Macs
#elif defined LINUX
... code for Linux
#endif

or:
#if defined DEBUG
.,. code only included in Debug builds
#endif
 
  • Like
Reactions: Monado_III

Cyan

GBATemp's lurking knight
Former Staff
Joined
Oct 27, 2002
Messages
23,749
Trophies
4
Age
46
Location
Engine room, learning
XP
15,662
Country
France
unrelated to the issue, I have a question:
Code:
sequence_length += counter++%3 == 0;
Shouldn't the right side comparison returns TRUE instead of 1 ?
sequence_length += true; is strange.

1 is true, but true is not 1.
By default a comparison returns 1 instead of true?
that's why sometime there are dual reverse to get true instead of 1?
!!( counter++%3 == 0) always returns true or false

i would have write
Code:
if(counter++%3 == 0)
    sequence_length++;

but if it returns 1 then I suppose inline is better, it uses less cycles.
 

tj_cool

Site dev
Supervisor
Joined
Jan 7, 2009
Messages
10,064
Trophies
2
Location
This planet
XP
3,107
Country
Belgium
unrelated to the issue, I have a question:
Code:
sequence_length += counter++%3 == 0;
Shouldn't the right side comparison returns TRUE instead of 1 ?
sequence_length += true; is strange.

1 is true, but true is not 1.
By default a comparison returns 1 instead of true?
that's why sometime there are dual reverse to get true instead of 1?
!!( counter++%3 == 0) always returns true or false

i would have write
Code:
if(counter++%3 == 0)
    sequence_length++;

but if it returns 1 then I suppose inline is better, it uses less cycles.
Booleans don't really exist in C. "FALSE" is represented by the integer 0 and "TRUE" by any other integer (standardized as 1).

The C open standard actually mentions it:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int.
 
  • Like
Reactions: Cyan

cdoty

Well-Known Member
Member
Joined
Sep 14, 2009
Messages
329
Trophies
0
Website
www.rastersoft.net
XP
352
Country
United States
It displays the digits now (and it looks like the rest of the program works), but then how would I go about getting the digits to disappear after 1 second?

I am surprised the original code doesn't work. You may try replacing it with:

for ( ;clock() - now < CLOCKS_PER_SEC * 3; )
{
}

to give it a three second delay. and see if that works. My guess is clock() may not work correctly on new systems.
 
Last edited by cdoty,

Monado_III

Well-Known Member
OP
Member
Joined
Feb 8, 2015
Messages
722
Trophies
0
Location
/dev/null
XP
1,443
Country
Canada
I surprised the original code doesn't work. You may try replacing it with:

for ( ;clock() - now < CLOCKS_PER_SEC * 3; )
{
}

to give it a three second delay. and see if that works. My guess is clock() may not work correctly on new systems.
Tried it and it still didn't work, this is what the program should look like right?
 

Attachments

  • program4_12.txt
    4.2 KB · Views: 261

zoogie

playing around in the end of life
Developer
Joined
Nov 30, 2014
Messages
8,560
Trophies
2
XP
15,000
Country
Micronesia, Federated States of
Tried it and it still didn't work, this is what the program should look like right?
Honestly, you should move on with your book.
A single demo program not working is insignificant compared with the rest of your learning.
Allocate your time wisely.

Besides, once you have a grasp of the language, you will be better equiped to debug issues like this rather than get others to figure it out.
 

Monado_III

Well-Known Member
OP
Member
Joined
Feb 8, 2015
Messages
722
Trophies
0
Location
/dev/null
XP
1,443
Country
Canada
Honestly, you should move on with your book.
A single demo program not working is insignificant compared with the rest of your learning.
Allocate your time wisely.
I would, but that's the end of the chapter and sone of the exercises requires me to modify the program and do some other stuff with time.
Although I might do that if no one comes up with solution by the end of of today.
 

sarkwalvein

There's hope for a Xenosaga port.
Member
Joined
Jun 29, 2007
Messages
8,514
Trophies
2
Age
41
Location
Niedersachsen
XP
11,264
Country
Germany
I would, but that's the end of the chapter and sone of the exercises requires me to modify the program and do some other stuff with time.
Although I might do that if no one comes up with solution by the end of of today.

Don't be dirty!
Flush the output!

Code:
/* Program 4.12 Simple Simon */
#include <stdio.h>                     /* For input and output   */
#include <ctype.h>                     /* For toupper() function */
#include <stdbool.h>                   /* For bool, true, false  */
#include <stdlib.h>                    /* For rand() and srand() */
#include <time.h>                      /* For time() and clock() */

int main(void)
{
  /* Records if another game is to be played */
  char another_game = 'Y';

  /* true if correct sequence entered, false otherwise */
  int correct = false;

  /* Number of sequences entered successfully          */
  int counter = 0;

  int sequence_length = 0;     /* Number of digits in a sequence        */
  time_t seed = 0;             /* Seed value for random number sequence */
  int number = 0;              /* Stores an input digit                 */

  time_t now = 0;            /* Stores current time - seed for random values  */
  int time_taken = 0;        /* Time taken for game in seconds                */

  /* Describe how the game is played */
  printf("\nTo play Simple Simon, ");
  printf("watch the screen for a sequence of digits.");
  printf("\nWatch carefully, as the digits are only displayed"
                                                " for a second! ");
  printf("\nThe computer will remove them, and then prompt you ");
  printf("to enter the same sequence.");
  printf("\nWhen you do, you must put spaces between the digits. \n");
  printf("\nGood Luck!\nPress Enter to play\n");
  scanf("%c", &another_game);

  /* One outer loop iteration is one game */
  do
  {
    correct = true;         /* By default indicates correct sequence entered */
    counter = 0;            /* Initialize count of number of successful tries*/
    sequence_length = 2;    /* Initial length of a digit sequence            */
    time_taken = clock();  /* Record current time at start of game       */

    /* Inner loop continues as long as sequences are entered correctly */
    while(correct)
    {
      /* On every third successful try, increase the sequence length */
      sequence_length += counter++%3 == 0;

      /* Set seed to be the number of seconds since Jan 1,1970  */
      seed = time(NULL);

      now = clock();                  /* record start time for sequence  */

      /* Generate a sequence of numbers and display the number */
      srand((unsigned int)seed);      /* Initialize the random sequence */
      for(int i = 1; i <= sequence_length; i++)
        printf("%d ", rand() % 10);    /* Output a random digit          */

     // (!) Flush the text OUTPUT!!!
     // Otherwise the buffered output waits for a new line (\n) to print data
     fflush(stdout);

      /* Wait one second */
      for(;clock() - now < CLOCKS_PER_SEC*3;);

      /* Now overwrite the digit sequence */
      printf("\r");                   /* go to beginning of the line */
      for(int i = 1; i <= sequence_length; i++)
      printf("  ");                 /* Output two spaces */

     // (!) Flush the text OUTPUT!!!
     // Otherwise the buffered output waits for a new line (\n) to print data
     fflush(stdout);

      if(counter == 1)           /* Only output message for the first try */
        printf("\nNow you enter the sequence  - don't forget"
                                               " the spaces\n");
      else
        printf("\r");                /* Back to the beginning of the line */

      /* Check the input sequence of digits against the original */
      srand((unsigned int)seed);     /* Restart the random sequence    */
      for(int i = 1; i <= sequence_length; i++)
      {
        scanf("%d", &number);         /* Read an input number         */
        if(number != rand() % 10)     /* Compare against random digit */
        {
          correct = false;            /* Incorrect entry             */
          break;                      /* No need to check further... */
        }
      }
      printf("%s\n", correct? "Correct!" : "Wrong!");
    }

    /* Calculate total time to play the game in seconds)*/
    time_taken = (clock() - time_taken) / CLOCKS_PER_SEC;

    /* Output the game score */
    printf("\n\n Your score is %d", --counter * 100 / time_taken);

    fflush(stdin);

    /* Check if new game required*/
    printf("\nDo you want to play again (y/n)? ");
    scanf("%c", &another_game);

  }while(toupper(another_game) == 'Y');
  return 0;
}
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • AncientBoi @ AncientBoi:
    ooowwww a new way for me to beat NFS 510 :D @SylverReZ
    +1
  • SylverReZ @ SylverReZ:
    @AncientBoi, Yeah, believe you can do PSP games as well. But a Pi5 is much powerful in comparison.
    +2
  • Psionic Roshambo @ Psionic Roshambo:
    Not sure about other models of Pi4 but the Pi 4 B with 8GBs OCed to 2Ghz handles PSP really great except like 1 game I found and it is playable it just looks bad lol Motor Storm Arctic something or other.
  • Psionic Roshambo @ Psionic Roshambo:
    Other games I can have turned up to like 2X and all kinds of enhancements, Motorstorm hmmm nope 1X and no enhancements lol
  • Veho @ Veho:
    Waiting for Anbernic's rg[whatever]SP price announcement, gimme.
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    I will admit that one does seem more interesting than the usual Ambernic ones, and I already liked those.
  • Veho @ Veho:
    I dread the price point.
    +1
  • Veho @ Veho:
    This looks like one of their premium models, so... $150 :glare:
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    To me that seems reasonable.
  • Psionic Roshambo @ Psionic Roshambo:
    I mean since basically all the games are errmmm free lol
  • Veho @ Veho:
    I mean yeah sure but the specs are the same as a $50 model, it's just those pesky "quality of life" things driving up the price, like an actually working speaker, or buttons that don't melt, and stuff like that.
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    I think all in my Pi 4 was well north of 200 bucks 150ish for the Pi 4 the case the fancy cooler, then like 70 for the 500GB MicroSD then like 70 for the Xbox controller. But honestly it's a nice set up I really enjoy and to me was worth every penny. (even bought more controllers for 2 or 4 player games.) hmmm have never played any 2 player games yet :(
  • Veho @ Veho:
    Yeah that's what I hate about the RPi, it's supposedly $30 or something but it takes an additional $200 of accessories to actually turn it into a working something.
  • Psionic Roshambo @ Psionic Roshambo:
    yes that's the expensive part lol
  • Veho @ Veho:
    I mean sure it's flexible and stuff but so is uremum but it's fiddly.
  • Psionic Roshambo @ Psionic Roshambo:
    Yeah a lot of it I consider a hobby, using Batocera I am constantly adjusting the collection adding and removing stuff, scraping the artwork. Haven't even started on some music for the theme... Also way down the road I am considering attempting to do a WiiFlow knock off lol
  • Veho @ Veho:
    I want everything served on a plate plz ktnx, "work" is too much work for me.
  • Veho @ Veho:
    Hmm, with that in mind, maybe a complete out-the-box solution with all the games collected, pacthed and optimized for me would be worth $150 :unsure:
  • Psionic Roshambo @ Psionic Roshambo:
    Yeah it's all choice and that's a good thing :)
  • Bunjolio @ Bunjolio:
    animal crossing new leaf 11pm music
  • Bunjolio @ Bunjolio:
    avatars-kKKZnC8XiW7HEUw0-KdJMsw-t1080x1080.jpg
    wokey d pronouns
  • SylverReZ @ SylverReZ:
    What its like to do online shopping in 1998: https://www.youtube.com/watch?v=vwag5XE8oJo
    SylverReZ @ SylverReZ: What its like to do online shopping in 1998: https://www.youtube.com/watch?v=vwag5XE8oJo