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));".
Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 31, 2021 srand in D | ||||
---|---|---|---|---|
| ||||
October 31, 2021 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to pascal111 | 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 |
October 31, 2021 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to pascal111 | 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:
If you want to use D's standard library, you can instead use 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 If you wanted to seed it yourself, however, you would do it using the
This is mainly useful when you are using a custom RNG instead of the default |
October 31, 2021 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 } |
January 08, 2022 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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. |
January 08, 2022 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On 1/8/22 12:27 PM, kdevel wrote: > 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 die That example wrapped in a program is the following: import std.stdio; import std.random; void main() { auto rnd = 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=15147 writeln(rnd.uniform!Fruit); // Fruit.mango } 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. TIL, I can use uniform with a type as in uniform!Fruit. Pretty cool. :) Ali |
January 09, 2022 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 |
January 08, 2022 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | 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 |
January 09, 2022 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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;
|
January 10, 2022 Re: srand in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | 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 }
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 |