الشبكة العربية لمطوري الألعاب

محترف  انس مشاركة 1

السلام عليكم .


لدي استفار فيما يخص البحث في مصفوفة .

ابدا بالكود حتى تتوضح الفكرة :



struct FONT
{
  SDL_Surface *img;
  char id;

};
 


...
 


int main()
{
  FONT fnt[26];
  ...
  print_fnt(fnt,'a');

}

ما اريد فعله هو ايجاد طرقة لجعل ال 'a' المرسل للدالة  print_fnt عبارة عن index  للمصفوفة . حيث لحد الان اقوم بالبحث في كامل المصفوفة عن العنصر ذي الـ 'id = 'a  و هذا قد يتطلب  وقتا طويلا  خصوصا اذا كانت المصفوفة كبيرة ، و عدد استدعاء دالة الرسم عديد .



FONT fnt[1226];

...


print_fnt(fnt,'A');


print_fnt(fnt,'g');


print_fnt(fnt,'d');


print_fnt(fnt,'n');

هل الفكرة واضحة او تحتاج الى توضيح اكثر ؟

شكرا لكم .

سلام .

محترف مشرف عبد اللطيف حاجي علي مشاركة 2

يمكنك استخدام std::map<char,> وهذا هو الحل الأفضل برأيي ☺
 
أو بإمكانك أن تقوم بعمل indexer يعتمد على كون الحروف في معظم الأنظمة متتابعة.
فيقوم هذا الـ indexer بفحص ما إذا كان الحرف كبيراً ويطرح قيمة 'A' منه.
أنا إذا كان صغيراً فيطرح قيمة 'a' ويجمع قيمة 'A'
وهكذا
 
أرجو أن يكون الحل واضحاً

عبد اللطيف حاجي علي
مبرمج
In|Framez

مفصول عمر سمير  مشاركة 3

لماذا هذه الطريقة المعقدة  ...

توجد طريقة افضل منها بكثير  وهي  كالتالي :



public IndexCollection (int)
OR

او  من مثال سهل وبسيط  يمكن التعامل معه في اي مصفوفة  مهما كانت كبيرة العدد
class MainClass {  
  public static void Main() {  
    int[] nums = new int[10]; 
    int avg = 0; 

    nums[0] = 99; 
    nums[1] = 10; 
    nums[2] = 100; 
    nums[3] = 18; 
    nums[4] = 78; 
    nums[5] = 23; 
    nums[6] = 63; 
    nums[7] = 9; 
    nums[8] = 87; 
    nums[9] = 49; 

    for(int i=0; i < 10; i++)  
      avg = avg + nums[i]; 

    avg = avg / 10; 

    Console.WriteLine("Average: " + avg); 
  }  
}

OSF متخصص محترف

محترف مشرف عبد اللطيف حاجي علي مشاركة 4

في 06 نيسان 2009 01:47 م، غمغم عمر سمير باستغراب قائلاً:

لماذا هذه الطريقة المعقدة  ...

توجد طريقة افضل منها بكثير  وهي  كالتالي :

احتمالان لا ثالث لهما 😒  إما أن أكون فهمت الموضوع بشكل خاطئ أو أن تكون فهمت الموضوع بشكل خاطئ 😄
 
ما يحاول أنس الوصول له هو أن تقوم الحروف مقام الـ index للمصفوفة حتى يختصر عمليات البحث. أمر لا يقوم مثالك بتحقيقه (بصرف النظر أنه يقوم بحساب المعدل لعشر أرقام بنجاح كبير)

عبد اللطيف حاجي علي
مبرمج
In|Framez

مفصول عمر سمير  مشاركة 5

تأكد انني على علم بما يقوله 

وانني  قمت بتجربة البحث هذه  كما قال أخينا

وطلعت النتيجة  صالحة  100%




int[] nums = new int[اي رقم يريده];     int البحث عن القيمة = 0;

الله يهديك  ويصلح بالك  يا عبداللطيف  هدئ من روعك شوية  ولا تتعصب كثيراً  مش كويس عشان اعصابك  تتشد 
شوف  الصالح  وحطه  عند  أنس  صاحب السؤال المطروح سابقاً

OSF متخصص محترف

خبير  أحمد عبد الغني مشاركة 6

وفي 11/ربيع الثاني/1430 12:19 م، أعرب عمر سمير عن رأيه بالموقف كالآتي:

تأكد انني على علم بما يقوله 

وانني  قمت بتجربة البحث هذه  كما قال أخينا

وطلعت النتيجة  صالحة  100%

😲  😲  😲
 
سبحان الله! ولله في خلقه شؤون!
 


في 11/ربيع الثاني/1430 12:19 م، قال عمر سمير بهدوء وتؤدة:

الله يهديك  ويصلح بالك  يا عبداللطيف  هدئ من روعك شوية  ولا تتعصب كثيراً  مش كويس عشان اعصابك  تتشد 
شوف  الصالح  وحطه  عند  أنس  صاحب السؤال المطروح سابقاً

هو بصراحة عبد اللطيف ما عصبش ولا حاجة، بس شكلي أنا اللي حعصب 😭  
أخي عمر، عبد اللطيف قام باقتراح حلّين مناسبين لمشكلة أنس. الأول باستخدام حسبة رياضية بالاعتماد على جدول آسكي والثاني (الأضمن) باعتماد خريطة تربط الحرف بالصورة المناسبة له.
 
أولاً قمتَ بالتعليق على حلـّه بأنه معقد، وقدمت بدلاً منه كود لا علاقة له بالمسألة. الأخ عبد اللطيف تواضع وقال أن أحدكما مخطئ في فهم المسألة كي لا يوجه الرسالة لك مباشرة فيحرجك. لكنك في ردك الأخير أصررت على موقفك بل وانتقدته على كلامه.
 
أنا أحب هذه الشبكة جداً. وأنا شخصياً أتابعها لأتعلم. ولا عيب في أن يخطئ أحدنا، لكن عدم الاعتراف بالخطأ والإصرار عليه ليس من أخلاق المتعلم، لا سيما أخي الكريم أنك بحاجة لتعلم المزيد في البرمجة كي تتقنها.
 
بدلاً من أن ترسل مشاركات مليئة بالأخطاء، أرجو أن تطرح أسئلة محددة عن الموضوع الذي لم تستطع فهمه، وستجدنا جميعاً نساعدك إن شاء الله.
 
 
أرجو أن لا يأخذ المشرفون كلامي على أنه تهجم أو انتقاص من احترام عضو في الشبكة. لكني أتكلم بعد أن نفذ صبري. 😢

اللهم انصر أهلنا في فلسطين وآجرنا أن نكون عوناً لهم

مفصول عمر سمير  مشاركة 7

آسف على الأزعاح ....

تقبلوا اعتذاري .....

ولكم جزيل الشكر .....

OSF متخصص محترف

محترف  انس مشاركة 8

السلام عليكم


في 06 ابريل 2009 06:58 م، عقد عمر سمير حاجبيه بتفكير وقال:

بس على فكرة   ::((  لقيت  اسلوب  آخر  للبرمجة اللي سئل عنه  اخي انس   وهو كالتالي :
اخي عمر اشكرك على مشاركتك ، لكن ليس هذا ما ابحث عنه . حنا ساعالج الكود الذي اتيتنا به لعل الصورة تتضح اكثر :



struct st
{
       char name[20];
       long num;
       int age;
       char sex;
       float score;
};

int main()
{
       struct st student[1053];

       GetData ( student , file ) ;

       FindStudent_ByName ( student , "Omare" ) ;
       FindStudent_ByOrder ( student , 5 ) ;



  }

void  FindStudent_ByOrder ( st* student , int order ){

print ( student[ order ] ) ;

}


// خاطئة و لا تعمل 
void  FindStudent_ByName ( st* student , char* name ){

print ( student[ name ] ) ;

}

لاحظ اخي انني ابحث عن حل للدالة الخاطئة و التي تستقبل اسما .

استاذ عبد اللطيف اشكرك على اقتراحك للحل لكن هناك بعض العوائق منها :

انني ابرمج بلغة السي ☺ .
ما اريد فعله ليس مرتبطا بالاحرف حتى يمكنني التلاعب بالقيم و انما المثال الموضوع هو جزء من المشكلة التي اواجهها . اليك مثال اخر ( اصبر علي ☺ فهو ممل بعض الشيئ ) :

هذا هو الكود الذي استعمله حاليا  :

void PlayAnim( SFF *sff_file , AIR_ANIM* air_file ,SDL_Surface* Axe_img , SDL_Surface* pScreen ) {

  int curent = Mugen_SDL_Frame( Get_SDL_Ticks() ) ;
  static int pass   = 0 ;

  if ( ( curent - pass ) > 4 ) {



     pass = curent ;
     air_file->time_cmpt ++;
  }


  if ( air_file->time_cmpt >= air_file->AnimElem[ air_file->Elemnt_cmpt ].time ){

      air_file->time_cmpt = 0 ;

   // si l'element n'as pas un temps nigative alors en passe au prochain ellement sinon en arrete
   if ( air_file->AnimElem[ air_file->Elemnt_cmpt ].time >=0 ) {

      // si le compteur des element != nbr_totlae_elem ; en passe au prochain elem
      if ( air_file->Elemnt_cmpt < air_file->ElemNbr-1 ) air_file->Elemnt_cmpt++ ;
      else {
          // gestion de boucle
          if ( air_file->loop ) air_file->Elemnt_cmpt = air_file->index_loop ;
          else air_file->Elemnt_cmpt = 0 ;
      }

       }


  }


    show_img( sff_file , air_file->AnimElem[ air_file->Elemnt_cmpt ].groupe
                       , air_file->AnimElem[ air_file->Elemnt_cmpt ].image
                       , Axe_img
                       , pScreen ) ;

}

الكود يعمل بشكل جيد لكن المشكلة انني مضطر الى تحديد الصورة المتحركة اثناء استدعاء الدالة كما يلي :

PlayAnim( &sff_file , &anim[9] ,Axe_img , pScreen ) ;


لنوضح الامور قليلا :

الـ SFF يحتوي المعلومات الخاصة بالصور .
struct SFF {

  Headers Headers ; // تستعمل لقراءة الملف 
  Sub_Headers* Sub_Headers ; // تستعمل لقراءة الملف 
  Sprite* spr  ; // تستعمل لتحميل المعلومات من الملف الى الذاكرة 
};

الـ AIR_ANIM  يحتوي معلومات عن كيفية تحريك الصور .


struct AIR_ANIM{

    int id ;                // مميز الصورة المتحركة 
    int ElemNbr ;           // عدد صور الحركة 
    int loop ;              // حلقة ؟
    int index_loop ;        // اين تبدأ الحلقة 
    int time_cmpt  ;        // حاسب الوقت 
    int Elemnt_cmpt  ;      // حاسب و مؤشر عناصر الحركة 
    AnimElem*  AnimElem ;   // عناصر الحركة 

    };

 لنعد الان الى الدالة :

PlayAnim( &sff_file , &anim[9] ,Axe_img , pScreen ) ;

تلاحظون انني اضطررت الى تحديد الصورة المتحركة ، لكن ما اريده هو دالة توقيعها كالاتي :



void PlayAnim( SFF* sff_file , AIR_ANIM* animm int animID ,IMG axe , SCREEN screen  ) ;

حيث يكون استدعاء الدالة بهذا الشكل :


PlayAnim( &sff_file , anim , 5 ,Axe_img , pScreen ) ;

ملاحظة الرقم 5 لا يشير الى الخانة 5 بل الى الخانة التي تحوي ID = 5  .

نظرة بسيطة على ملف الصورة المتحركة :



;stand
[Begin Action 0]
0,0, 0,0, 3
0,1, 0,0, 3
0,2, 0,0, 3
0,3, 0,0, 3
0,4, 0,0, 3
0,5, 0,0, 3
0,6, 0,0, 3
0,7, 0,0, 3
0,8, 0,0, 3
0,9, 0,0, 3
0,10, 0,0, 3
0,11, 0,0, 3
0,12, 0,0, 3
0,13, 0,0, 3
0,14, 0,0, 3
0,15, 0,0, 3


;stand a tourner
[Begin Action 5]
5,0, 7,0, 3
5,0, 0,0, 4


;0
[Begin Action 6]
5,2, 0,0, 2
5,3, 0,0, 4

تلاحظون ان ال ID  يختلف حسب ما يشاء كاتب الملف .

هل اتضحت الامور ... هناك عدة اشياء تعاني من نفس المشكل المطروح هنا في المكتبة التي احاول كتابتها .

شكرا لكم .

سلام .

خبير  سعيد بسيوني مشاركة 9

طيب يا حاج. بلاش. من غير ++C
 
ممكن تبني الخريطة بالـ C زي ما بتبنيها بالـ ++C. بس الفرق انك مش حتستخدم كلاس الـ std.
 
بص معايا الكلام ده:
 
http://uthash.sourceforge.net/
 
المثال اللي في الصفحة الأولى حيكون شكلو مألوف قوي بالنسبة ليك 😏
 
 
الاقتراح التاني انك تعمل بحث ثنائي بدل البحث الخطي، بس ده بشرط انك تكون مرتب المصفوفة بتاعتك تصاعدياً، وإلا حيحصل حاجات وحشة ☺

محترف مشرف عبد اللطيف حاجي علي مشاركة 10

كما قال سعيد. تستطيع بناء "خريطة" مشابهة باستخدام لغة C. الفكرة الأساسية هي ألا تنفذ البحث بشكل خطي بل باستخدام أحد الخوارزميات الأخرى. أمثال: AVL Tree, Binary Search أو Red-Black tree. أذكر أن هذه الأخيرة هي الخوارزمية المستخدمة في تنفيذ std::map في مكتبة STL في Visual Studio 2008.

هناك كلمة أحاول أن أمنع نفسي من قولها منذ بدء المشاركة 😖 . لكن صراحة لم أعد أستطيغ 😭
كم هو عدد العناصر في المصفوفة؟
ما هي كلفة المقارنة؟
ما هو التواتر الذي تستخدم فيه هذا البحث؟
لماذا تعتقد أنه بحاجة إلى تحسين؟

حسناً أشعر بتحسن كبير 😄

عبد اللطيف حاجي علي
مبرمج
In|Framez