www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - srand in D

reply pascal111 <judas.the.messiah.111 gmail.com> writes:
Hi! I'm C learner and found the high similarity between C and D, 
and was converting C code into D but couldn't get the equivalent 
of this C statement "srand(time(NULL));".
Oct 31 2021
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/31/21 9:54 AM, pascal111 wrote:
 Hi! I'm C learner and found the high similarity between C and D, and was 
 converting C code into D
Welcome! :) In case it makes to your use cases, check out -betterC as well: https://dlang.org/spec/betterc.html
 but couldn't get the equivalent of this C
 statement "srand(time(NULL));".
Just comment that line out. :) D's pseudo-random generators start randomized by default: import std.stdio; import std.random; void main() { // Pick a number between [0,10) writeln(uniform(0, 10)); } The documentation is at https://dlang.org/phobos/std_random.html Ali
Oct 31 2021
next sibling parent pascal111 <judas.the.messiah.111 gmail.com> writes:
On Sunday, 31 October 2021 at 17:02:00 UTC, Ali Çehreli wrote:
 On 10/31/21 9:54 AM, pascal111 wrote:
 Hi! I'm C learner and found the high similarity between C and 
 D, and was converting C code into D
Welcome! :) In case it makes to your use cases, check out -betterC as well: https://dlang.org/spec/betterc.html
 but couldn't get the equivalent of this C
 statement "srand(time(NULL));".
Just comment that line out. :) D's pseudo-random generators start randomized by default: import std.stdio; import std.random; void main() { // Pick a number between [0,10) writeln(uniform(0, 10)); } The documentation is at https://dlang.org/phobos/std_random.html Ali
Thanks! the code works now: /* Acey Ducey game, originally programmed in BASIC */ // D programming language import std.stdio; import core.stdc.stdlib; import std.ascii; import core.stdc.string; import core.stdc.stdio; import core.time; import std.conv; import std.random; /* char* card_name(int); // turning cards valuse into strings function void no_money_test(ref int); // money = 0 test */ // turning cards valuse into strings function void card_name(int x, ref string c) { /* char* c=cast(char*) malloc((strlen("queen")+1)*(char.sizeof)); if(!c){ writeln("A memory allocation failed!"); exit(EXIT_FAILURE);} */ switch (x) { case 11: c="Jack"; break; case 12: c="Queen"; break; case 13: c="King"; break; case 14: c="Ace"; break; default: c=to!string(x); } } // money = 0 test void no_money_test(ref int your_money) { char q; if (your_money == 0) { do { writeln("Oops! you have no money to bet with,"); write("do you want playing again (y/n)? "); readf(" %c", &q); } while ((toLower(q)!='y') && (toLower(q)!='n')); if (toLower(q)=='y') // nasted in 'if money = 0' { your_money = 100; } else exit(EXIT_SUCCESS); } // if money = 0 } int main() { int your_money=100; int card_A, card_B, card_C; string card_A_name, card_B_name, card_C_name; char q; int bet_much; //srand(time(NULL)); do // 1st do { writeln("You've ", your_money, "$"); // Generating the two cards: do { card_A = uniform(0, 13)+2; //(rand()%13)+2; card_B = uniform(0, 13)+2; } while (!((card_B - card_A) > 2) && !((card_A==2)&&(card_B==14))); card_name(card_A, card_A_name); card_name(card_B, card_B_name); writeln("Here are your two cards: ", card_A_name, " ", card_B_name); // Betting query: card_C = uniform(0, 13)+2; do { write("Do you'll bet (y/n/e = (exit))? "); readf(" %c", &q); } while ((toLower(q)!='y') && (toLower(q)!='n') && (toLower(q)!='e')); // agreeing betting if (toLower(q)=='y') { do { write("With how much? "); readf(" %d", &bet_much); if (bet_much>your_money) { writeln("You don't have this much to bet with,"); writeln("you have ", your_money, "$"); } } while (!(bet_much<=your_money)); if ((card_C>=card_A) && (card_C<=card_B)) // following agreeing betting 'if' { card_name(card_C, card_C_name); writeln("You are right! "); writeln("3rd card is: ", card_C_name); your_money+=bet_much; } else { card_name(card_C, card_C_name); writeln("Oops! you are wrong!"); writeln("3rd card is: ", card_C_name); your_money-=bet_much; } } else // 'else if' of agreeing betting 'if' if(toLower(q)=='e') exit(0); else // considered final 'else' of agreeing betting 'if' writeln("CHICKEN!!!"); // Your money = 0 test no_money_test(your_money); } while (true); // 1st do return 0; } // C version of the same game /* Acey Ducey game, originally programmed in BASIC */ #include <iostream> #include <cstdlib> #include <string> #include <cctype> #include <cstring> #include <cstdio> using namespace std; char *card_name(int); // turning cards valuse into strings function void no_money_test(int&); // money = 0 test int main(void) { int your_money=100; int card_A, card_B, card_C; char q; int bet_much; srand(time(NULL)); do // 1st do { cout << "You've " << your_money << "$" << endl; // Generating the two cards: do { card_A = (rand()%13)+2; card_B = (rand()%13)+2; } while (!((card_B - card_A) > 2) && !((card_A==2)&&(card_B==14))); cout << "Here are your two cards: " << card_name(card_A) << " " << card_name(card_B) << endl; // Betting query: card_C = (rand()%13)+2; do { cout << "Do you'll bet (y/n/e = (exit))? "; cin >> q; } while ((tolower(q)!='y') && (tolower(q)!='n') && (tolower(q)!='e')); // agreeing betting if (tolower(q)=='y') { do { cout << "With how much? "; cin >> bet_much; if (bet_much>your_money) { cout << "You don't have this much to bet with," << endl << "you have " << your_money << "$" << endl; } } while (!(bet_much<=your_money)); if ((card_C>=card_A) && (card_C<=card_B)) // following agreeing betting 'if' { cout << "You are right! " << endl << "3rd card is: " << card_name(card_C) << endl; your_money+=bet_much; } else { cout << "Oops! you are wrong!" << endl << "3rd card is: " << card_name(card_C) << endl; your_money-=bet_much; } } else // 'else if' of agreeing betting 'if' if(tolower(q)=='e') exit(0); else // considered final 'else' of agreeing betting 'if' cout << "CHICKEN!!!" << endl; // Your money = 0 test no_money_test(your_money); } while (true); // 1st do return 0; } // turning cards valuse into strings function char *card_name(int x) { char *c=(char *) malloc((strlen("queen")+1)*sizeof(char)); if(!c){ cerr << "A memory allocation failed!" << endl; exit(EXIT_FAILURE);} switch (x) { case 11: strcpy(c,"Jack"); break; case 12: strcpy(c,"Queen"); break; case 13: strcpy(c,"King"); break; case 14: strcpy(c,"Ace"); break; default: sprintf(c,"%d",x); } return c; } // money = 0 test void no_money_test(int& your_money) { char q; if (your_money == 0) { do { cout << "Oops! you have no money to bet with," << endl << "do you want playing again (y/n)? "; cin >> q; } while ((tolower(q)!='y') && (tolower(q)!='n')); if (tolower(q)=='y') // nasted in 'if money = 0' { your_money = 100; } else exit(EXIT_SUCCESS); } // if money = 0 }
Oct 31 2021
prev sibling parent reply kdevel <kdevel vogtner.de> writes:
On Sunday, 31 October 2021 at 17:02:00 UTC, Ali Çehreli wrote:
 Just comment that line out. :) D's pseudo-random generators 
 start randomized by default:
[...]
   https://dlang.org/phobos/std_random.html
Klicking at "Run" always delivers "mango": https://dlang.org/phobos/std_random.html#uniform A very unbalanced diet.
Jan 08 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/8/22 12:27 PM, kdevel wrote:
 On Sunday, 31 October 2021 at 17:02:00 UTC, Ali =C3=87ehreli wrote:
 Just comment that line out. :) D's pseudo-random generators start=20
 randomized by default:
=20 [...] =20
 =C2=A0 https://dlang.org/phobos/std_random.html
=20 Klicking at "Run" always delivers "mango": =20 https://dlang.org/phobos/std_random.html#uniform =20 A very unbalanced die
That example wrapped in a program is the following: import std.stdio; import std.random; void main() { auto rnd =3D MinstdRand0(42); writeln(rnd.uniform!ubyte); // 102 writeln(rnd.uniform!ulong); // 4838462006927449017 enum Fruit { apple, mango, pear } version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=3D15147= writeln(rnd.uniform!Fruit); // Fruit.mango } Apparently, the programmer wanted uniformly distributed randomness that=20 is reproducible. That's why they use a generator that is seeded with 42=20 there. It does produce random results but the first Fruit happens to be "mango" = with that seed. TIL, I can use uniform with a type as in uniform!Fruit. Pretty cool. :) Ali
Jan 08 2022
parent reply kdevel <kdevel vogtner.de> writes:
On Saturday, 8 January 2022 at 23:34:17 UTC, Ali Çehreli wrote:
[...]
 Apparently, the programmer wanted uniformly distributed 
 randomness that is reproducible. That's why they use a 
 generator that is seeded with 42 there.

 It does produce random results but the first Fruit happens to 
 be "mango" with that seed.
enum Fruit { apple, mango, pear } version (X86_64) writeln(uniform!Fruit); ``` This modified program delivers a fruit mix. Alas not in the online version, where one is supposed to have a preference for apples.
 TIL, I can use uniform with a type as in uniform!Fruit. Pretty 
 cool. :)
nice. But enum immutable (char) [] allowed_chars = [ 'c', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 't', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; char q = uniform!allowed_chars; writeln (q); complains with uni2.d(11): Error: template instance `uniform!(['c', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 't', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9'])` has no value
Jan 08 2022
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/8/22 4:17 PM, kdevel wrote:

     enum immutable (char) [] allowed_chars = [
        'c', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 't', 'v',
        'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9'
     ];

     char q = uniform!allowed_chars;
     writeln (q);

 complains with

 uni2.d(11): Error: template instance `uniform!(['c', 'f', 'g', 'h', 'j',
 'k', 'l', 'm', 'n', 'p', 'r', 't', 'v', 'w', 'x', 'y', 'z', '1', '2',
 '3', '4', '5', '6', '7', '8', '9'])` has no value
That's because uniform's first template parameter is expected to be a type. (There are two uses of 'enum' in D and the one above is not a type, rather "this is a manifest constant".) One might think that uniform should work with a string like "hello" but in that case what are the choices? The single string or its individual characters? What would work in the code above is 'choice': char q = choice(allowed_chars); But that hits another fact of D: arrays of chars are strings, which cannot be RandomAccessRange because individual chars must be decoded to form dchars. Keeping the 'choice' line above and replacing two 'char's with 'dchar's in your code makes it work. Ali
Jan 08 2022
parent kdevel <kdevel vogtner.de> writes:
On Sunday, 9 January 2022 at 03:15:02 UTC, Ali Çehreli wrote:
 What would work in the code above is 'choice':

   char q = choice(allowed_chars);

 But that hits another fact of D: arrays of chars are strings, 
 which cannot be RandomAccessRange because individual chars must 
 be decoded to form dchars.
One can use explicit index notation which is nearly as compact as the template parameter form: string salt = iota (0, 16) .map!(i => saltchars [uniform(0, $)]) .array;
Jan 09 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/8/22 7:17 PM, kdevel wrote:
 On Saturday, 8 January 2022 at 23:34:17 UTC, Ali Çehreli wrote:
 [...]
 Apparently, the programmer wanted uniformly distributed randomness 
 that is reproducible. That's why they use a generator that is seeded 
 with 42 there.

 It does produce random results but the first Fruit happens to be 
 "mango" with that seed.
enum Fruit { apple, mango, pear } version (X86_64) writeln(uniform!Fruit); ``` This modified program delivers a fruit mix. Alas not in the online version, where one is supposed to have a preference for apples.
The online compiler caches results to save on computational resources. So if you don't change the code, you will get the same result. Just add spacing to get it to rebuild. -Steve
Jan 10 2022
prev sibling parent Paul Backus <snarwin gmail.com> writes:
On Sunday, 31 October 2021 at 16:54:35 UTC, pascal111 wrote:
 Hi! I'm C learner and found the high similarity between C and 
 D, and was converting C code into D but couldn't get the 
 equivalent of this C statement "srand(time(NULL));".
Since D gives you access to the C standard library, you can use pretty much exactly the same code in D: ```d import core.stdc.stdlib; // bindings for <stdlib.h> import core.stdc.time; // bindings for <time.h> srand(time(null)); // null is lower-case in D ``` If you want to use D's standard library, you can instead use [`std.random.rndGen`][1], the default random number generator. Its documentation says:
 It is allocated per-thread and initialized to an unpredictable 
 value for each thread.
In other words, it is seeded for you automatically. So when you are converting C code that uses `rand` to D code that uses `rndGen`, you can simply delete the line `srand(time(NULL));`, and it will work ask expected. If you wanted to seed it yourself, however, you would do it using the `.seed` method, and generate the seed using [`std.random.unpredictableSeed`][2]. ```d import std.random; rndGen.seed(unpredictableSeed()); ``` This is mainly useful when you are using a custom RNG instead of the default `rndGen`, since custom RNGs are *not* automatically seeded. [1]: https://phobos.dpldocs.info/std.random.rndGen.html [2]: https://phobos.dpldocs.info/std.random.unpredictableSeed.1.html
Oct 31 2021