भाग्य के खेलों को यादृच्छिकता के किसी स्रोत की ज़रूरत होती है। Factor की random वोकैबुलरी एक जेनेरिक शब्द, random, देती है, जो आप उसे जो भी सौंपें उसके हिसाब से ढल जाता है। इसके अलावा इसमें शफल करने और सैंपल लेने के लिए सहायक हैं, और टेस्ट के लिए यादृच्छिकता को दोबारा पैदा करने योग्य बनाने का एक तरीका भी है।
inline चिह्नित करनाइस अभ्यास के कुछ कार्य एक ऐसा शब्द बनाते हैं जो एक कोटेशन (एक [ … ] ब्लॉक) को आर्गुमेंट की तरह लेता है और उसे चलाता है। Factor में इस बारे में एक सख्त नियम है: जो शब्द किसी आर्गुमेंट के रूप में मिली कोटेशन को call करता है, उसे inline घोषित करना ज़रूरी है, और यह क्लोज़िंग ; के ठीक बाद inline लिखकर किया जाता है।
inline कंपाइलर को यह बताता है कि वह शब्द के बॉडी को हर कॉल साइट पर जोड़ दे, न कि उसे अलग से एक बार कंपाइल करे।
यहाँ एक छोटा शब्द है जो 10 पुश करता है और फिर उसे सौंपी गई कोटेशन चलाता है:
USING: kernel math prettyprint ;
: with-ten ( quot -- ) 10 swap call ; inline
इसका स्टैक इफेक्ट, ( quot -- ), कोई आउटपुट नहीं बताता, फिर भी इसे अलग-अलग इफेक्ट वाली दो कोटेशनों के साथ कॉल करने पर अलग-अलग नतीजे मिलते हैं, और सब कुछ वापस कॉलर तक पहुँचता है:
[ 1 + ] with-ten . ! => 11 (quotation ( n -- n ): one value back)
[ dup 2 * ] with-ten . . ! => 20
! => 10 (quotation ( n -- n n ): two values back)
random: एक एलिमेंटrandom (random में) अपने आर्गुमेंट के ऊपर जेनेरिक है:
random ( obj -- elt )
n दिया जाए, तो यह [0, n) में एक यादृच्छिक पूर्णांक लौटाता है:USING: random ;
6 random . ! 4 (a value from 0 to 5)
{ "rock" "paper" "scissors" } random . ! "paper"
साधारण पासा फेंकने के लिए आप रेंज को एक से बढ़ा देते हैं: 6 पर random 0 से 5 देता है, इसलिए 6 random 1 + 1 से 6 देता है।
किसी तय संख्या में यादृच्छिक नतीजे इकट्ठा करने के लिए, replicate (sequences में) की मदद से एक कोटेशन दोहराइए:
replicate ( n quot -- seq )
USING: random sequences ;
3 [ 6 random 1 + ] replicate . ! { 4 1 6 } (three dice)
randomize: उसी जगह पर शफल करनाrandomize (random में) उसी सीक्वेंस को लौटाता है जिसके एलिमेंट यादृच्छिक क्रम में हों:
randomize ( seq -- randomized )
{ 1 2 3 4 5 } randomize . ! { 3 1 5 2 4 }
यह उसी जगह पर शफल करता है और वही सीक्वेंस लौटाता है, इसलिए अगर आपको मूल क्रम बनाए रखना है तो पहले clone कीजिए।
sample: कई अलग-अलग एलिमेंटsample (random में) एक सीक्वेंस से n अलग-अलग एलिमेंट निकालता है, जैसे ताश के पत्ते बाँटना, जिसमें एक ही पत्ता दोबारा नहीं आता:
sample ( seq n -- seq' )
{ 10 20 30 40 50 } 3 sample . ! { 40 10 30 }
सीक्वेंस में जितने एलिमेंट मौजूद हैं उससे ज़्यादा माँगना एक एरर है।
डिफ़ॉल्ट रूप से random एक ग्लोबल जेनेरेटर से निकालता है जिसे सिस्टम क्लॉक से सीड किया जाता है, इसलिए हर बार चलाने पर नतीजा अलग आता है। टेस्ट के लिए, या जब भी आप ऐसा खेल चाहते हैं जिसे दोबारा खेला जा सके, किसी तय सीड वाले जेनेरेटर को बाँधिए।
<mersenne-twister> (random.mersenne-twister में) एक पूर्णांक सीड से एक जेनेरेटर बनाता है, और with-random (random में) उस जेनेरेटर को सेट करके एक कोटेशन चलाता है:
<mersenne-twister> ( seed -- rnd )
with-random ( rnd quot -- )
USING: random random.mersenne-twister ;
42 <mersenne-twister> [ 6 random 1 + ] with-random .
! always the same value for seed 42
कोटेशन के अंदर की हर चीज़, यानी random, randomize, sample, सीड किए गए जेनेरेटर से ही निकालती है, इसलिए वही सीड हमेशा वही नतीजा दोहराती है।
जो शब्द किसी कोटेशन को आर्गुमेंट की तरह लेता है और उसे with-random के ज़रिए चलाता है, वह उस नियम के अंतर्गत आता है जो किसी शब्द को inline चिह्नित करना वाले हिस्से में बताया गया है: with-random अंत में उस कोटेशन को call करता है, इसलिए ऐसे रैपर को inline चिह्नित करना ज़रूरी है।
आप समुद्र किनारे के बोर्डवॉक आर्केड में भाग्य के खेल चलाते हैं। खिलाड़ी पासे फेंकते हैं, क्लॉ मशीन इनाम पकड़ती है, और ताश की मेज़ पर गड्डी फेंटनी पड़ती है और हैंड बाँटने पड़ते हैं। यह सब बेतरतीब ढंग से होता है। रात के अंत में आपको एक "रिप्ले" सुविधा भी चाहिए, ताकि किसी विवादित खेल को उसी सीड से दोबारा चलाया जा सके।
roll-die बनाइए, जो पासे के फलकों की संख्या लेता है और 1 से sides तक (दोनों समेत) के बीच एक रोल लौटाता है।
6 roll-die .
! => 4 (some value from 1..6)
pick-prize बनाइए, जो इनामों का एक सीक्वेंस लेता है और उनमें से कोई एक बेतरतीब ढंग से लौटाता है।
{ "teddy" "goldfish" "keyring" } pick-prize .
! => "goldfish"
shuffle-deck बनाइए, जो एक गड्डी (सीक्वेंस) लेता है और उस गड्डी को बेतरतीब क्रम में लौटाता है।
{ 1 2 3 4 5 } shuffle-deck .
! => { 3 1 5 2 4 }
deal-hand बनाइए, जो एक गड्डी और एक संख्या n लेता है, और गड्डी से n अलग-अलग कार्ड लौटाता है।
{ 10 20 30 40 50 } 3 deal-hand .
! => { 40 10 30 }
play-seeded बनाइए, जो एक सीड और एक कोटेशन लेता है, और उस कोटेशन को ऐसे जनरेटर से चलाता है जिसका सीड उस पूर्णांक से लिया गया है, ताकि वही सीड हमेशा वही परिणाम दोबारा दे। कोटेशन का परिणाम कॉल करने वाले को लौटाया जाना चाहिए।
42 [ 6 roll-die ] play-seeded .
! => the same value every time for seed 42
! Same seed, same game:
99 [ 5 deal-hand ] play-seeded 99 [ 5 deal-hand ] play-seeded = .
! => t
Exercism पर साइन अप कीजिए और Factor को 47 कॉन्सेप्ट163 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।