المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : الدرس التاسع : دوال إنتاج الأرقام العشوائية - دورة CSharp 2005


khaledbelal
03-22-2010, 03:55 PM
الدرس التاسع

إنتاج أرقام عشوائية

ربما يتسائل البعض ما الذي يدعونا لإنتاج أرقام عشوائية وفي اي شيئ سنستخدمها

حسناً , يعتبر إنتاج الأرقام العشوائية من اهم الدعائم التي ترتكز عليها أنظمة الذكاء الإصطناعي والشبكات العصبية الإصطناعية

وإنتاج الأرقام العشوائية ليس بالسهولة التي تتصورها

حيث تستخدم خوارزمية شديدة التعقيد لغرض أنتاج أرقام لا معنى لها

تكمن الصعوبة في الخوارزمية أن أنظمة الحاسوب لاتستطيع أن تنتج أي شي لامعنى له

فلا يوجد شيئ "عشوائي" في أنظمة الحاسوب

ولكن خوارزميات إنتاج الأرقام العشوائية تستخدم الكثير من المدخلات من مصادر مختلفة لإنتاج الأرقام العشوائية

كأن تأخذ تاريخ ووقت النظام , وتجري عليه عددا من الدوال والحسابات

في برنامجنا سنضيف اليوم خاصية إختيار طريقة تشغيل الملفات , إما تتابعية أو عشوائية

تتابعية يعني أن يشغل البرنامج الملف الأول في قائمة التشغيل وعند الإنتهاء منه يشغل الملف الثاني وهكذا

أما الطريقة العشوائية فهي أن يقوم البرنامج بالحصول على رقم عشوائي بين الصفر و عدد الملفات في قائمة التشغيل ويبدأ بتشغيلة

وعند الإنتهاء منه يحصل على رقم عشوائي ويشغل ملف آخر وهكذا.

في لغة C# يوجد كائن مسئول عن إنتاج الأرقام العشوائية هو كائن Random

وعند تعريفة ولأنه كائن وليس متغير يجب إستخدام كلمة new هكذا :

Rabdom rnd=new Random();

في الكود السابق قمنا بتعريف كائن إسمه rnd من نوع Ranom

الدالة Next في هذا الكائن هي المسئولة عن إنتاج الأرقام العشوائية

وتستقبل هذه الدالة رقمين يمثلا الحد الأدنى والحد الأقصى للعدد العشوائي المراد إنتاجه

مثلاً لو أردنا إنتاج رقم عشوائي بين 0 و 10 :

rnd.Next(0,10);

حيث ستنتج هذه الدالة رقماً عشوائيا بين الصفر والعشرة

ولأن هذه الدالة تعيد قيمة فإن إستدعائها بالطريقة السابقة خاطئ , حيث يجب إسنادها لمتغير من نوع رقم:

int num;
num=rnd.Next(0,10);

حيث أن المتغير num سيحمل القيمة الناتجة من الدالة .

التطبيق
إفتح تصميم البرنامج , ومن صندوق الأدوات قم بسحب كائن صندوق المجموعة Group Box إلى الفورم الرئيسي:

http://absba7.absba.org/teamwork8/455943/71.jpg

قم بإختيار صندوق المجموعة ومن جدول الخصائص إذهب إلى خاصية Text
وأكتب أمامها "طريقة التشغيل" , ستلاحظ أن عنوان صندوق المجموعة قد تغير :

http://absba7.absba.org/teamwork8/455943/72.jpg

من صندوق الأدوات أيضاً قم بسحب كائن زر الإختيار Radio Button مرتين إلى صندوق المجموعة :

http://absba7.absba.org/teamwork8/455943/73.jpg

تأكد من أن زري الإختيار قد تم وضعها داخل صندوق المجموعة :

http://absba7.absba.org/teamwork8/455943/74.jpg

إختر زر الإختيار المسمى radioButton1 وإذهب إلى جدول الخصائص
وغير الخاصية (Name) من radioButton1 إلى serbtn
وغير الخاصية Text من radioButton1 إلى تتابعي
وغير أيضاً الخاصية Checked إلى true
إختر زر الإختيار الأخر المسمى radioButton2 وإذهب إلى جدول الخصائص
وغير الخاصية (Name) من radioButton2 إلى rndbtn
وغير أيضاً الخاصية Text من radioButton2 إلى عشوائي
عدل ترتيب الأدوات في النافذه حتى يصبح شكلها هكذا :

http://absba7.absba.org/teamwork8/455943/75.jpg

سنحتاج إلى متغير عام من نوع رقم وليكن current حيث سيقوم بخزن ترتيب الملف الذي يتم تشغيله حالياً
قم بإضافة هذا المتغير أسفل المتغيرات العامة من الدروس السابقة :

http://absba7.absba.org/teamwork8/455943/76.jpg

إجراء تشغيل الملف الحالي
الإجراء PlayCurrent وظيفته هي تشغيل الملف الذي ترتيبه هو قيمة current من القائمة albume
مثلاً إذا كانت قيمة current هي 3 فإن هذا الإجراء يشغل الملف من قائمة التشغيل والذي ترتيبه 3
إنسخ هذا الإجراء إلى شفرة البرنامج وتأكد أنه خارج أي إجراء آخر

void PlayCurrent()
{
LoadFile(albume[current]);
SetTrackBar();
PlayFile();
}

إجراء إختيار الملف التالي
وظيفة الإجراء SetNext هي إختيار الملف التالي لتشغيلة بعد الإنتهاء من تشغيل الملف الحالي
حيث يقوم هذا الإجراء بفحص طريقة التشغيل المختارة من قبل المستخدم ومن خلالها تقوم بإختيار الملف التالي بطريقتين مختلفتين:

if(rndbtn.Checked)
{
//current إضافة 1 إلى المتغير
}
else
{
// current إختيار رقم عشوائي وتحميلة للمتغير
}

إنسخ الإجراء التالي إلى شفرة البرنامج وتأكد أنه خارج أي إجراء آخر:

void SetNext()
{
if(serbtn.Checked)
{
current=current+1;
}
else
{
Random rnd=new Random();
current=rnd.Next(0,albume.Count-1);
}
pl.SelectedIndex = current;
PlayCurrent();
}

في السطر الثالث من الكود السابق توجد عبارة if والتي تفحص زر الإختيار serbtn الذي خصصناه للتشغيل التتابعي
فإذا كانت حالة الزر Ckecked أي أن الإختيار عليه , أي أن نوع التشغيل المختار من قبل المستخدم هو التتابعي
عندها في السطر الخامس نقوم بإضافة 1 إلى قيمة current , فإذا كانت قيمته مثلاً 5 ستصبح قيمته 6
إما إذا كذا الإختيار على الزر الآخر وهو المخصص للتشغيل العشوائي
ففي السطر التاسع قمنا بتعريف كائن من نوع Random
وفي السطر العاشر إسندنا للمتغير current القيمة الناتجة من دالة إنتاج الأرقام العشوائية
حيث أن الدالة ستنتج رقماً عشوائيا بين الصفر و ترتيب آخر عنصر في قائمة التشغيل
ونعرف أن عدد عناصر قائمة التشغيل هو طول نفس عدد عناصر القائمةalbume
ولكن عدد عناصر القائمة يختلف عن الترتيب لأنه كما قلنا في الدرس السابق فإن الترتيب في المصفوفات والقوائم يبدأ من الصفر
فإذا كان طول القائمة 5 فإن أعلى ترتيب فيها هو 4 لذلك إضفنا -1 بعد طول المصفوفة

في السطر الثاني عشر قمنا بتغيير الإختيار في قائمة التشغيل من خلال الخاصية SelectedIndex
مثلاً لو أردنا أن نختار العنصر الثالث من قائمة التشغيل سنستخدم الكود التالي :

pl.SelectedIndex=2;

لاحظ 2 و ليست 3 لأن العنصر الثالث في القائمة ترتيبه 2 وليس 3 حيث ان العنصر الأول كما قلنا ترتيبه 0
والعنصر الثاني ترتيبه 1 والعنصر الثالث ترتيبه 2 و هكذا .
في السطر الثالث عشر قمنا بإستدعاء الإجراءPlayCurrent والذي يقوم بتشغيل الملف الذي ترتيبه هو قيمة current

هناك ملاحظة على الكود السابق
فإذا كانت طريقة التشغيل تتابعي , ووصل ترتيب الملف إلى آخر عنصر
عندها إذا أضفنا 1 إلى المتغير current فإنه سيحمل ترتيب أعلى من ترتيب آخر عنصر في القائمة وهذا سيسبب خطأ
عند محاولة تحميل ملف غير موجود اساساً في قائمة الملفات albume وقائمة التشغيل
لذلك يجب أن نفحص قيمة current أولاً فإذا كانت تساوي آخر ترتيب في القائمة فنقوم بأسناد الرقم 0 إلى المتغير current
حتى يرجع ترتيب المتغير لأول عنصر في القائمة , وبالتالي عند الإنتهاء من تشغيل جميع الملفات في القائمة فسيعود تشغيل الملفات من أول القائمة مرة أخرى
في كود إجراء إختيار الملف أحذف السطر التالي :

current=current+1;

وأكتب مكانه هذه الأسطر :

if(current==albume.Count-1)
{
current=0;
}
else
{
current=current+1;
}

عبارة if في السطر الأول تقوم بفحص قيمة current فإذا كانت تساوي ترتيب آخر عنصر بالقائمة
ففي السطر الثالث تسند القيمة 0 إلى المتغير current
أما إذا كانت قيمة current لا تساوي ترتيب آخر عنصر
ففي السطر السابع تضيف 1 إلى قيمة current
بالتعديل السابق يصبح إجراء إختيار الملف التالي هكذا :

void SetNext()
{
if(serbtn.Checked)
{
if(current==albume.Count-1)
{
current=0;
}
else
{
current=current+1;
}
}
else
{
Random rnd=new Random();
current=rnd.Next(0,albume.Count-1);
}
pl.SelectedIndex = current;
PlayCurrent();
}

متى نستدعي إجراء إختيار الملف التالي ؟
إذا قمت بتشغيل البرنامج فلن يتم تشغيل الملفات لا عشوائيا و لا تتابعياً
لأننا قمنا بكتابة كود إجراء الأختيار ولكنا لم نستدعه في أي مكان في البرنامج
والمفروض أن نستدعي إجراء إختيار الملف التالي عند الإنتهاء من تشغيل الملف الحالي
ولكن كيف نعرف متى سيتم الإنتهاء من تشغيل الملف الحالي ؟
حسنا نعرف أن قيمة شريط التنقل عبر الملف تتغير كل ثانية بفعل المؤقت
سنستخدم هذه الميزة لنعرف وقت الإنتهاء من تشغيل الملف الحال ..
حيث أنه عند الإنتهاء من تشغيل الملف فإن قيمة شريط التنقل تصبح مساوية لطول الملف
إذا سنختبر قيمة شريط التنقل في كل مرة تتغير فيها فإذا أصبحت قيمته مسوية لطول الملف يعني أنه وصل إلي نهاية الملف الحالي
وبالتالي يجب إستدعاء إجراء SetNext
لكن هناك مشكلة , فالمؤقت يغير قيمة الشريط كل ثانية واحدة , وطول المف في ملفات الريل يقاس بالملي ثانية
أي انه عند وصول الملف لنهايته فهناك إحتمال كبير أن لا تكون قيمة الشريط هي طول الملف
لذلك يجب أن نجد طريقة أخر لفحص الصول إلى نهاية الملف
الطريقة هي أن نفحص نوع الملف الذي يتم تشغيله حالياً فإذا كان ملف ريل فالفحص يتم على آخر 1000 رقم
أما إذا كان ملف صوت عادي أو ملف فيديو فالفحص يتم على أخر رقم
أي أن شرط الوصول إلى نهاية ملف الريل يتحقق إذا كانت قيمة شريط التنقل أكبر من طول الملف ناقص 1000
وشرط الوصول إلى نهاية ملف الصوت العادي والفيديو يتحقق إذا كانت قيمة شريط التنقل أكبر من طول الملف ناقص واحد كما سنشرح في الفقرة التالية
إذهب إلى تصميم البرنامج وقم بإختيار كائن التنقل trackBar1
من نافذة الخصائص إختر خصائص الأحداث وانقر مزدوجاً أمام الحدث ValueChanged:

http://absba7.absba.org/teamwork8/455943/77.jpg

ستنتقل إلى شفرة البرنامج إلى إجراء TrackBar1ValueChanged هذا الإجراء يتم تنفيذه في كل مرة تتغير فيها قيمة شريط التنقل
حيث من المفترض ان نستدعي إجراء إختيار الملف التالي هنا :

void TrackBar1ValueChanged(object sender, EventArgs e)
{
//إستدعاء إجراء إختيار الملف التالي
}

إنسخ الكود التالي إلى داخل الإجراء TrackBar1ValueChanged :

int last;
if (type == "R")
{
last = trackBar1.Maximum - 1000;
}
else
{
last = trackBar1.Maximum - 1;
}
if (trackBar1.Value > last)
{
SetNext();
}

حيث يصبح الإجراء TrackBar1ValueChanged هكذا :

void TrackBar1ValueChanged(object sender, EventArgs e)
{
int last;
if (type == "R")
{
last = trackBar1.Maximum - 1000;
}
else
{
last = trackBar1.Maximum - 1;
}
if (trackBar1.Value > last)
{
SetNext();
}
}

في هذا الإجراء عرفنا متغير إسمه last من نوع رقم يحمل قيمة تمثل أعلى قيمة لطول الملف الصوتي
وهي طول الملف الصوتي ناقص 1000 في ملفات الريل
وهي طول الملف الصوتي ناقص واحد في ملفات الصوت العادية والفيديو
في السطر الرابع عبارة if لفحص نوع الملف الذي يتم تشغيله حالياً من خلال المتغير type الذي شرحناه في دروس سابقة
فإذا كانت قيمة type هي R يعني هذا أنه ملف ريل , وبالتالي فإن أعلى قيمة لطول الملف الصوتي هي آخر ثانية في الملف
وهي طول الملف ناقص 1000 , وقد وضعنا بدل طول الملف trackBar1.Maximum لأنها يحملان نفس القيمة بفعل الإجراء SetTrackBar
أما إذا لم يكن الملف ملف ريل فإن أعلى قيمة لطول الملف هي آخر ثانية وهي طول الملف ناقص واحد
في السطر الثاني عشر عبارة if أخرى تقوم بفحص قيمة شريط التنقل فإذا كانت قيمته أكبر من أعلى قيمة لطول الملف
فهذا يعني أن البرنامج وصل إلى نهاية الملف الصوتي , ويجب إستدعاء دالة إختيار الملف التالي وتشغيلة
..
إذهب إلى إجراء plSelectedIndexChanged من الدرس السابق وغير شفرته حتى يصبح هكذا :

void plSelectedIndexChanged(object sender, EventArgs e)
{
current=pl.SelectedIndex;
PlayCurrent();
}

عرفنا أن الإجراء plSelectedIndexChanged ينفذ في كل مرة تقوم بإختيار ملف من قائمة التشغيل
والكود السابق يقوم يتحميل المتغير current ترتيب الملف الذي إخترته ثم يستدعي إجراء تشغيله
الآن قم بتشغيل البرنامج وإختر عدة ملفات و جرب طرق التشغيل

الواجب
أرسل التطبيق
.نهاية الدرس التاسع.
..
.