Menu

'Throwing the dice' problem

Kaas
2008-05-25
2012-09-26
  • Kaas

    Kaas - 2008-05-25

    I'm quite new to c/c++, and I'm following the tutorial in the help file. now, I'm doing the 'Throwing the dice'-bit, but the compiled program prints nothing but 'throw y/n?'. I need some help, since i can't understand it myself.

    Text:

    include <stdio.h>

    include <stdlib.h>

    int randn(int n)
    {
    return rand()%n + 1;
    }

    char getans()
    {
    int ans;

    printf("Throw y/n ?");
    ans = -1;
    while (ans == -1)
    {
    ans=getchar();
    }
    return ans;
    }

    void blines(int n)
    {
    int i;

    for(i=1 ; i&lt;=n ; i++) printf(&quot;\n&quot;);
    

    }
    void showone()
    {
    printf("\n * \n");
    }
    void showtwo()
    {
    printf(" * \n\n");
    printf(" * \n");
    }

    void showthree()
    {
    printf(" * \n");

    printf(&quot;  * \n&quot;);
    printf(&quot;   *\n&quot;);
    

    }

    void showfour()
    {
    printf(" * \n\n");
    printf(" *
    \n");
    }

    void showfive()
    {
    printf(" * \n");
    printf(" * \n");
    printf(" *
    \n");
    }

    void showsix()
    {
    int i;

    for(i=1 ; i&gt;=3 ; i++) printf(&quot; * * \n&quot;);
    

    }

    main()
    {
    int r;
    char ans;

    ans = getans();

    while(ans== 'y')
    {
    r = randn(6);

      blines(25);
      if (r==1) showone();
      if (r==2) showtwo();
      if (r==3) showthree();
      if (r==4) showfour();
      if (r==5) showfive();
      if (r==6) showsix();
      blines(21);
      ans = getans();
    }
    

    blines(2);
    system("pause");
    }


    compiler log:

    Compiler: Default compiler
    Building Makefile: "C:\Dev-Cpp\Makefile.win"
    Executing make...
    make.exe -f "C:\Dev-Cpp\Makefile.win" all
    g++.exe -c "../Documents and Settings/Nikolai/Mine dokumenter/dice.cpp" -o "../Documents and Settings/Nikolai/Mine dokumenter/dice.o" -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include"

    g++.exe "../Documents and Settings/Nikolai/Mine dokumenter/dice.o" -o "Prosjekt 3.exe" -L"C:/Dev-Cpp/lib"

    g++.exe "../Documents and Settings/Nikolai/Mine dokumenter/dice.o" -o "Prosjekt 3.exe" -L"C:/Dev-Cpp/lib"

    Execution terminated
    Compilation successful

     
    • cpns

      cpns - 2008-05-27

      > shouldn't the creators of dev-c++ be notified of the fault in the tutorial?

      I am sure they know. But the project is not in active development. There was talk once of someone rewriting it, but I was not convinced they were really qualified either. The text of the tutorial was 'donated' very early on in the project's life, I am not sure of teh terms of teh donation, but it may have prohibited changes.

      To be honest, it should be removed rather than fixed (but just ignoring it is easier). It may have made sense before always-on internet connections where accessing higher quality on-line resources is now trivial. It is not the job of an IDE to teach programming, and there are plenty of other, better, resources available. Moreover, it only refers to C, while Dev-C++ as its name suggests rather emphasises C++ development. I think there was once a plain Dev-C, and that is presumably when this tutorial was added.

      Get your information elsewhere, and learn C++ rather than C wouldbe my recommendation:

      Try these:

      http://www.cplusplus.com/doc/tutorial/
      http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

      Clifford

       
    • K.Z.

      K.Z. - 2008-05-26

      That looks like the inbuilt c tutorial that comes with dev-cpp.

      That particular part on random numbers is the worst tut Ive ever come across on the subject.

      If you would like a nice clean function for generating pesudo random numbers I can post one,
      otherwise I would look elsewhere for help on the topic.

       
      • Kaas

        Kaas - 2008-05-26

        Thanks, but I'm more interested in making the program working in general, If you or anyone understand such C, I would be happy : ) And, yes, this point in the tutorial is extremely confusing.

         
    • K.Z.

      K.Z. - 2008-05-26

      I use c++ rather than c,for no reason,
      but I can give a brief outline of this code.......

      include <stdio.h>

      include <stdlib.h>

      //====================================
      int randn(int n)
      {
      return rand()%n + 1;
      }

      [ see http://members.cox.net/srice1/random/crandom.html ]
      //====================================
      //====================================
      char getans()
      {
      int ans;

      printf("Throw y/n ?");
      ans = -1;
      while (ans == -1)
      {
      ans=getchar();
      }
      return ans;
      }
      //====================================
      [ read as char getAnswer()
      ...it uses getchar() to place the users input into the int
      ans (answer) and returns the functions local variable ans back
      to the main function (type promoting ans to type char in the process???is that right clifford!?)

      look at http://www.opengroup.org/onlinepubs/009695399/functions/getchar.html ]
      //====================================
      //====================================
      void blines(int n)
      {
      int i;

      for(i=1 ; i<=n ; i++) printf("\n");
      }

      [ read as blankLines(int numberOfLines)
      outputs the specified number of newlines ]

      \===================================
      \===================================
      void showone() ...2...3...4...etc
      {
      printf("\n * \n");
      }
      [ prints dots to the screen as they appear on a d6 ]

      When it prompts for 'Throw y/n' and the user types yes,
      the program will attempt to get a number in the range of 1 - 6,
      and call the function showone() if the number was 1,
      showtwo if it was 2 etc....

      which prints the dots of the die to the screen.

      One possable reason it is'nt printing anything is that the
      rand(n) function is screwed and its not returning a number from 1 - 6.

      Another possable reason might be due to the way the input is processed.

      I hope Wayne or Clifford can help you out, Im interested too why this poo code is'nt working.

       
      • Kaas

        Kaas - 2008-05-26

        I have looked over the program a little while now, and i realized, I don't understand the randn() function.

        __

        int randn(int n)
        {
        return rand()%n + 1;
        }

        __

        Here n is declared, but i don't see how n gets a value?

         
    • K.Z.

      K.Z. - 2008-05-26

      r = randn(6);

      n is the parameter of the funtion randn(int n) ;
      in this case n is passed the value of 6 with becomes the value of int n

      Do yourself a small favour,

      at the end of this conditional...

      if (r==1) showone();
      if (r==2) showtwo();
      if (r==3) showthree();
      if (r==4) showfour();
      if (r==5) showfive();
      if (r==6) showsix();

      add

      else { printf( "invalid return value from 'randn(int n)', value = %d", r) ; }

      If the problems with this function you can stop guessing as it will tell you.

       
      • Kaas

        Kaas - 2008-05-26

        Ok, i did as you said and added "else { printf( "invalid return value from 'randn(int n)', value = %d", r) ; }" thanks for the tip, but it does not affect the program, so then it is not the randn() function. I will take a break from this now, as i have scarce with energy, but if you have another tip or anything, please let me know. thanks for the help so far : )

         
    • K.Z.

      K.Z. - 2008-05-26

      Okay,I got annoyed with the t.v. and decided to sort this problem out...
      and this is the problem...

      1)6 is being passed in to randn(int n),
      This will always return 6 from rand() %n +1.
      Because srand() has been forgotten.

      Passing in any number here will return the same number...so...

      if you have a look at condition 6 it calls showSix..

      void showsix()
      {
      int i;

      for(i=1 ; i>=3 ; i++) printf(" * * \n");
      }

      i equals 1, if i is greater and or equal to 3....

      it should read

      void showsix()
      {
      int i;

      for(i=1 ; i<=3 ; i++) printf(" * * \n");
      }

       
    • cpns

      cpns - 2008-05-26

      There are a number of things wrong with this code. If this truly came or was derived from the Dev-C++ helpfile tutorial, know that pretty much all of that tutorial is atrociously bad.

      The first problem is that the first value returned from randn() is 6. randn() will always produce the same sequence because the code does not specifically set an alternative random number seed, and the first number in the sequence will always be 6. This is not actually a problem in itself, (in fact it is useful for repeatable tests), it is the treatment of the value 6 that is incorrect. You have a loop:

      for(i=1 ; i>=3 ; i++)

      the second clause in a for statment has 'while' semantics. i.e. loop while i >=3. Since it is initialised to zero, the loop never executes. To be honest, teh loop is pointless, you may as well have used similar code to the other values:

      void showsix()
      {
      printf(" * \n\n");
      printf(" *
      \n\n");
      printf(" * * \n\n");
      }

      If you must use a loop, then you wanted:

      for( i = 0; i < 3; i++ )

      The second problem is that console input is 'line oriented'. That is when asked to press 'y' or 'n', you in fact have to press (at least) 'y'+<enter>, or 'n'+<enter>. That is two characters; but getchar() only consumes one, leaving the <enter> buffered. So teh next time getchar() is called, it returns <enter> immediately, with no further input; since this is not 'y', the loop terminates. One solution to this is:

      char getans()
      {
      int ans;

      printf("Throw y/n ?");
      ans = getchar() ;
      while( ans != '\n' && getchar() != '\n' ){ / flush line input / }

      return ans;
      }

      Some minor issues also; it is good form to explicitly declare main() as returning an int, and to explicitly return a value (normally zero, since conventionally this indicates that the program completed without error). If you use teh compuiler options -Werror -Wall, you will get a warning to that effect, and compilation will fail, and your code quality will increase!

      As I said earlier, you will get the same pseudo-random sequence everytime you run the program; so don't use this code to play games of chance with people with good memories! You need to add an srand() call to set the seed. It is common to use the current system time to set the seed to something unpredictable.

      Finally, don't put your project in "../Documents and Settings/Nikolai/Mine dokumenter/". Had you read the thread titled "PLEASE READ BEFORE POSTING A QUESTION" you would know that and you would know why it is important!

      Anyway, a working version of your code is produced below. It is still not 'great' code however; consider for example, using a switch instead of sequential mutually exclusive if statements, or even a 'jump-table' array of function pointers. Also for purely cosmetic appearances, take a look at a real die to see how teh dots are laid out. Note also that since there is only one, this is a 'die throwing" problem, not a "dice throwing" problem. ;-)

      include <stdio.h>

      include <stdlib.h>

      int randn(int n)
      {
      return rand()%n + 1;
      }

      char getans()
      {
      int ans;

      printf("Throw y/n ?");
      ans = getchar() ;
      while( ans != '\n' && getchar() != '\n' ){ / flush line input / }

      return ans;
      }

      void blines(int n)
      {
      int i;

      for(i=1 ; i<=n ; i++) printf("\n");
      }
      void showone()
      {
      printf("\n * \n");
      }
      void showtwo()
      {
      printf(" * \n\n");
      printf(" * \n");
      }

      void showthree()
      {
      printf(" * \n");

      printf(" * \n");
      printf(" *\n");
      }

      void showfour()
      {
      printf(" * \n\n");
      printf(" *
      \n");
      }

      void showfive()
      {
      printf(" * \n");
      printf(" * \n");
      printf(" *
      \n");
      }

      void showsix()
      {
      printf(" * \n");
      printf(" *
      \n");
      printf(" * * \n");
      }

      int main()
      {
      int r;
      char ans;

      ans = getans();

      while(ans== 'y')
      {
      r = randn(6);

      blines(25);

      if (r==1) showone();
      if (r==2) showtwo();
      if (r==3) showthree();
      if (r==4) showfour();
      if (r==5) showfive();
      if (r==6) showsix();
      blines(21);

      ans = getans();
      }

      blines(2);
      system("pause");
      return 0 ;
      }

      Clifford

       
    • cpns

      cpns - 2008-05-26

      > Here n is declared, but i don't see how n gets a value?

      n takes the value passed as a parameter when called. In the case randn(6), n == 6.

      rand() produces a number 0 to RAND_MAX, the ... % n + 1 expression produces a value 1 to n inclusive.

      Note that it is strictly statistically biased if n is not a factor of RAND_MAX + 1. For small values of n and large values of RAND_MAX, this may not be significant. RAND_MAX is implementation dependent and often as small as 32765 (as is the case here I believe).

      Clifford

       
    • Kaas

      Kaas - 2008-05-27

      Thanks guys, With your help, it finally works properly! : D but shouldn't the creators of dev-c++ be notified of the fault in the tutorial? i don't see myself doing it since i'll probably not make sense. x)

      Anyways, BIG thanks! Both for the problem solving and for the wonderful explanations! : )

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.