why I cannot stop this loop at 50 points? (code)

F

FSX

Hello everyone,
I would like to quit the execution of the while as soon as the program
reaches 50 points, so that a player wins. Here is both the pastebin page
and the source (but I think the pastebin page is better).

Should I create two distinct while loops? I tried to add a control
statement that breaks the while before the adding cycle but it still go
beyond 50 (to 70, it executes another turn).

Thank in advance to everyone.

FSX

http://fsx.pastebin.com/m203bc77


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

int main(void)
{
int dice1, dice2, score1, score2;
srand((unsigned)time(NULL));

dice1 = dice2 = score1 = score2 = 0;

while(score1 < 50 && score2 < 50)
{
if(score1 >= 50 || score2 >= 50)
break;

//player 1
dice1 = (rand()%6)+1;
dice2 = (rand()%6)+1;

if(dice1 == dice2)
{
printf("Player 1 scored double %d\n", dice1);
if(dice1 == 3)
score1 = 0;
else if(dice1 == 6)
score1 = score1 + 25;
else
score1 = score1 + 5;
printf("Player 1 = %d\n", score1);
}

//player 2
dice1 = (rand()%6)+1;
dice2 = (rand()%6)+1;
if(dice1 == dice2)
{
printf("Player 2 scored double %d\n", dice1);
if(dice2 == 3)
score2 = 0;
else if(dice2 == 6)
score2 = score2 + 25;
else
score2 = score2 + 5;
printf("Player 2 = %d\n", score2);
}
}
if(score1 == score2)
printf("Pari\n");
else if(score1 > score2)
printf("Player 1 Wins\n");
else
printf("Player 2 Wins\n");

return 0;
}

Posted using www.webuse.net
 
G

gw7rib

        while(score1 < 50 && score2 < 50)
        {      
                if(score1 >= 50 || score2 >= 50)
                        break;

(snip)

You don't seem too clear about how "while" works. Suppose, like here,
you have a condition in () brackets followed by some code in { }
brackets. What happens is that it tests the condition. If the
condition is false then it doesn't execute the code in the { }
brackets at all - it goes on to whatever follows it. If, however, the
condition is true, it executes all the code in the { } brackets, and
then tests the condition again. You might expect it to keep testing
the condition as it goes through the code, but C doesn't work like
that. (I once used a text editor which had an until-end-of-file
command uteof, which would continue until it had to do something that
was impossible at the end of a file. But C is different.)

If you want to stop at a particular place partway through the code,
you can put in another test at that point and do "break" if you want
to break out at that point. The "break" instruction that I have quoted
above would do, but you need to put it at the point you want the break
to occur, which in your case is about halfway through the { } code.
Putting the test at the top is pointless because you're testing
something that the original condition has only just checked. You want
to wait until the scores have had a chance to change.

Hope this is useful.
Paul.
 
G

gw7rib

By the way, the singular of "dice" is "die".

Ian Stewart, in his latest book, uses "dice", saying "I should have
used 'die' - but I've given up fighting that particular battle." He
adds "Anyway, the proverb tells us 'never say die'."

Paul.
 
F

FSX

(e-mail address removed) <[email protected]> ha scritto:

(snip)

Yes it is VERY useful.
Here is the updated thing that now works:

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

int main(void)
{
int die1, die2, score1, score2, throwscore;
srand((unsigned)time(NULL));

die1 = die2 = score1 = score2 = throwscore = 0;

while(score1 < 50 && score2 < 50)
{
//player 1
die1 = (rand()%6)+1;
die2 = (rand()%6)+1;

if(die1 == die2)
{
printf("Player 1 scored double %d\n", die1);
if(die1 == 3)
throwscore = score1 = 0;
else if(die1 == 6)
throwscore = 25;
else
throwscore = 5;

if(score1 + throwscore <= 50)
score1 += throwscore;

printf("Player 1 = %d\n", score1);
}

//player 2
die1 = (rand()%6)+1;
die2 = (rand()%6)+1;
if(die1 == die2)
{
printf("Player 2 scored double %d\n", die1);
if(die1 == 3)
throwscore = score2 = 0;
else if(die2 == 6)
throwscore = 25;
else
throwscore = 5;

if(score2 + throwscore <= 50)
score2 += throwscore;

printf("Player 2 = %d\n", score2);
}
}
if(score1 == score2)
printf("Game is a tie\n");
else if(score1 > score2)
printf("Player 1 Wins\n");
else
printf("Player 2 Wins\n");

return 0;
}


Posted using www.webuse.net
 
R

R J C

FSX scribbled:
#include <time.h>

int main(void)
{
int die1, die2, score1, score2, throwscore;
srand((unsigned)time(NULL));

No no no!!! :) Rare against form, Han from China actually offered
some practical advice here, if you can ignore his insults. The
'(unsigned)' doesn't rescue you from the non-portable code that
potentially invokes undefined behavior (actually, it was news to
me that there needn't be no wrap around, but sure enough, that's
the case). Non-portable code is off-topic here, so if you post
to the newsgroup for your particular system (comp.unix.programmer
perhaps?), you'll get much better help than you will here.

srand(time(NULL))

and the equivalent

srand((unsigned)time(NULL))

are NOT portable ISO C solutions!!!

Rob
 
F

FSX

Ok I admit I have copied that from a C++ program I seen on the 'net. I would
like to make portable code, can you suggest a better solution?

Thanks in advance Han from China.

FSX

Posted using www.webuse.net
 
F

FSX

pete said:
{
time_t t = time(NULL);

while (t > 0u - 1 + 0.0) {
t /= 2;
}
srand(t);
}

Ok thanks a lot! I'm afraid I am still a long way from understanding what I'm
doing at low level. So can someone explain me this solution and a decent book on
writing portable ISO C code?

Hope I'm not asking too much...

Thanks to all the nice answerers =)

Posted using www.webuse.net
 
B

Ben Bacarisse

pete said:
{
time_t t = time(NULL);

while (t > 0u - 1 + 0.0) {
t /= 2;
}
srand(t);
}

This does nothing to help if t is negative.

(What is the 0.0 for? I'd write the test as while (t > (unsigned)-1)
but I agree that is purely a style choice.)

Anyway, I think things are getting out of hand! All this is because
time_t might be a floating point type so the conversion to unsigned is
undefined. If that is the case you need to consider the purpose of
the code. To seed a generator from the time you want a reasonable
rate of change, and simply halving a time in an unknown encoding to
be in the right range might loose most of that variability.

On a practical note I'd test that time_t is an integer type with
something like assert((time_t)0.5 == 0.0); or one of the static assert
tricks and accept that investigation and re-writing is needed for a
floating point time_t system. The re-write can then do the right thing
for the particular encoding used.
 
F

FSX

Kenny McCormack said:
(*) No matter how absurd it may look to anyone with a lick of sense
(like you and me).


Ok but I am still a newbie in C programming and in programming in general, and I
have pointed this out in my first post here. So why should I be nudged to
migrate to another newsgroup? This is a bit unfair. My goal is to write pure C
code, clean and portable, and I am striving to do that everyday and this is the
reason for I have subscribed to this newsgroup.
I appreciate the help of everybody.

FSX

Posted using www.webuse.net
 
K

Kenny McCormack

Ok but I am still a newbie in C programming and in programming in
general, and I have pointed this out in my first post here. So why
should I be nudged to migrate to another newsgroup?

Who is "nudging" you to go to another newsgroup? Certainly not I.
This is a bit unfair.

What do you find unfair?
My goal is to write pure C code, clean and portable, and I am
striving to do that everyday and this is the reason for I have
subscribed to this newsgroup. I appreciate the help of everybody.

Glad to have been of service, buddy. Keep 'em comin'!
 
K

Keith Thompson

R J C said:
FSX scribbled:

No no no!!! :) Rare against form, Han from China actually offered
some practical advice here, if you can ignore his insults. The
'(unsigned)' doesn't rescue you from the non-portable code that
potentially invokes undefined behavior (actually, it was news to me
that there needn't be no wrap around, but sure enough, that's the
case). Non-portable code is off-topic here, so if you post to the
newsgroup for your particular system (comp.unix.programmer perhaps?),
you'll get much better help than you will here.

I don't think non-portable code is necessarily off-topic. In fact, we
spend a great deal of time discussing non-portable code, and examining
*why* it's non-portable.
srand(time(NULL))

and the equivalent

srand((unsigned)time(NULL))

are NOT portable ISO C solutions!!!

They can invoke undefined behavior only if time_t is a floating-point
type, and only if its value is outside the range 0 .. UINT_MAX.
In practice, I've never seen a system where it is.

And in practice, it's reasonable either to accept the
non-portability, or, as somebody else suggested, to add a
compile-time or run-time assertion that will prevent the program
from getting to the point where its behavior becomes undefined.

Making the program work reasonably with a floating-point time_t is
more challenging. Suppose time() yields a floating-point number
of days since some defined epoch. Then converting to unsigned
loses the fractional part, so the same value is passed to srand()
every time the program is run on a given day.

What you *could* do portably is use the fields of the struct tm
resulting from calling localtime(time(NULL)) or gmtime(time(NULL)).
Xor'ing them together isn't good enough, since that will only
cover a limited range of values (0 .. 511 if I'm not mistaken),
but it should be possible to scramble the tm_* values together
to produce a reasonably well distributed unsigned int value that
changes every second.

Of course if you want cryptographically secure random numbers,
time() and rand() aren't nearly good enough.
 
B

Ben Bacarisse

What about this?

srand( fmod( fabs(time(NULL)), UINT_MAX ) );

fabs to ensure it's positive, fmod to keep it in range of an unsigned int,
without sacrificing granularity.

That's reasonable, but it does (or at least may) sacrifice
granularity. If the time is in centuries you won't get much change.
My point was that if time_t is floating you need to know more to find
out how to make the most of it.
 
K

Kenny McCormack

Haha! *spills drink*

Yes. This was definitely a spills drink moment for me as well.
It's not off-topic when Thompson's buddy Heathfield recommends
non-portable code to someone, but it's off-topic when anyone
else does.

I know that consistency is the hobgoblin of little minds and is thus
optional for the crew here, but it certainly wouldn't take much Googling
to find quotes of them saying exactly the opposite - that portable code
is not only the only we discuss here, but the only that in existence
(i.e., the only thing that is "C" - everything else is "something else")

And by "something else", they clearly mean just as much "something else"
and as clearly distinct from "C" as, to use my previous analogy, beach
balls.
 
B

Beej Jorgensen

FSX said:
Ok thanks a lot! I'm afraid I am still a long way from understanding what I'm
doing at low level.

It's good to know why srand(time(NULL)) might invoke undefined behavior,
but it's a really common idiom. It's common enough to appear (with
caveats) in the comp.lang.c FAQ.

That being said, for this program, no one will think the worse of you
for using srand(time(NULL)). If you do something more than that, be
sure to leave a comment for the next coder so s/he knows what you were
thinking. :)

-Beej
 
C

CBFalconer

FSX said:
Han from China <[email protected]> ha scritto:

Ok I admit I have copied that from a C++ program I seen on the
'net. I would like to make portable code, can you suggest a
better solution?

Thanks in advance Han from China.

You didn't quote anything Han wrote. However, be advised he is an
admitted troll, with the stated objective of destroying
comp.lang.c. You are better off ignoring him.
 
C

CBFalconer

R said:
FSX scribbled:


No no no!!! :) Rare against form, Han from China actually offered
some practical advice here, if you can ignore his insults. The
'(unsigned)' doesn't rescue you from the non-portable code that
potentially invokes undefined behavior (actually, it was news to
me that there needn't be no wrap around, but sure enough, that's
the case). Non-portable code is off-topic here, so if you post
to the newsgroup for your particular system (comp.unix.programmer
perhaps?), you'll get much better help than you will here.

srand(time(NULL))
and the equivalent
srand((unsigned)time(NULL))
are NOT portable ISO C solutions!!!

The first may not be, because time returns a time_t, but I may be
wrong here. The second is obviously correct, since the argument
for srand is cast to the appropriate form, and time(NULL) is
defined. This is valid standard C code.

However, I echo your comment about Han.
 
K

Kenny McCormack

You didn't quote anything Han wrote. However, be advised he is an
admitted troll, with the stated objective of destroying
comp.lang.c. You are better off ignoring him.

Keep in mind that Han never stated that his objective was to "destroy" clc.
Nor did _I_ ever state that my objective was to "disrupt" clc.

Yet, the regs frequently state these things as if they were facts.

Thus we see that lying comes as easily as breathing for clc regs.

Keep *that* in mind when evaluating their statements.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top