ابْدَأ بهذه النقطة المهمة: حتى المهام البرمجية التي تبدو سهلة، مثل سحب الأرقام العشوائية دون تكرار (كالتي تراها في ألعاب اللوتو أو اليانصيب)، قد تخفي وراءها مشكلات أداء خطيرة تؤثر على تجربة المستخدم. وهذا يعني بالنسبة لك، سواء كنت مطوراً أو مجرد مستخدم يستمتع بالألعاب الرقمية، أن الأخطاء الشائعة في هذه الأكواد يمكن أن تجعل تطبيقك بطيئاً جداً أو حتى يتوقف عن العمل تماماً.

يظن الكثيرون أن الحل بسيط: توليد رقم عشوائي، ثم التحقق إذا كان قد تم سحبه من قبل. إذا كان كذلك، أعد المحاولة. هذه الطريقة، التي تُعرف بـ «أخذ العينات بالرفض»، تعمل في البداية بسرعة. تخيل أنك تسحب أرقاماً من 75 رقماً. في الجولات الأولى، معظم السحوبات تنجح من المحاولة الأولى. ولكن ماذا يحدث عندما يتم سحب 70 رقماً بالفعل وتبقى 5 أرقام فقط؟

هنا تكمن المشكلة الحقيقية. يصبح البرنامج مضطراً لتوليد أرقام عشوائية مرات عديدة والتحقق من كل واحد منها مراراً وتكراراً قبل أن يجد رقماً جديداً. هذا يؤدي إلى إبطاء شديد، فكل عملية سحب قد تتطلب 15 محاولة أو أكثر. تخيل هذا يحدث في لعبة بسيطة تعرضها على جهاز عرض! الأسوأ من ذلك، أنه إذا تم سحب جميع الأرقام الـ 75، فإن هذه الطريقة ستظل تحاول إلى الأبد، مما يتسبب في تعليق البرنامج. بالإضافة إلى ذلك، عملية البحث داخل قائمة الأرقام المسحوبة سابقاً تصبح أبطأ كلما زادت الأرقام المسحوبة.

لحسن الحظ، هناك طريقة أفضل وأكثر ذكاءً لتجنب هذه المشكلات. بدلاً من «التخمين» والتحقق، يجب أن نختار مباشرة من مجموعة الأرقام المتبقية. الفكرة هي إنشاء قائمة بالأرقام التي لم تُسحب بعد، ثم سحب رقم عشوائي واحد فقط من هذه القائمة مباشرةً. هذا التغيير البسيط يُحدث فرقاً كبيراً:

1. يستخدم البرنامج طريقة بحث أسرع بكثير (تخيل البحث في فهرس كتاب بدلاً من قراءة الكتاب كله كل مرة).
2. تتم عملية توليد الأرقام العشوائية مرة واحدة فقط لكل سحب، مما يضمن أداءً ثابتاً وسريعاً بغض النظر عن عدد الأرقام المتبقية.
3. عندما لا تتبقى أي أرقام، يعلم البرنامج ذلك ويعود بنتيجة واضحة (مثل «لا يوجد المزيد من الأرقام») بدلاً من الدخول في حلقة لا نهائية.

باختصار، ما يبدو كخدعة برمجية بسيطة له حلول أفضل وأكثر كفاءة تضمن استقرار وسلاسة تطبيقاتنا وألعابنا. إن فهم هذه الفروقات الدقيقة هو ما يميز الكود الجيد عن الكود الذي قد يفشل عندما تشتد الحاجة إليه.