מקביל לrealloc ב++C - עמוד 2 - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

מקביל לrealloc ב++C


Sikamikanico

Recommended Posts

אתה יכול אולי לשתף אותנו במה שמצאת?

ובעניין , יכול להיות שכן ויכול להיות שלו.. ז"א, מצד אחד הליבה של דומה מאוד ל 2000 (למעשה, זה NT5.1 ו 2000 זה NT5), אבל מצד שני יכול להיות שב "תיקנו" את זה, למרות שלא נראה לי... פשוט תנסה ותראה..

קישור לתוכן
שתף באתרים אחרים

  • תגובות 39
  • נוצר
  • תגובה אחרונה

כנס לפה:

http://www.retro-games.co.uk/downloads/progkeys.htm

הקוד הוא די פשוט ונוח (כדאי גם להוריד את הקובץ עצמו בתחתית העמוד, כדי לראות את כל הקוד).

הבעיה הוא שהצלחתי להפעיל אותו רק בDJGPP.

אני עובד עם BorlandC++Builder6 וממש לא הצלחתי להפעיל אותו.

למשל משום מה בDOS.H של הborland, אין את הפונקציות inportb ו outportb.

יש גם עוד כמה דברים בקוד שהוא לא מוכן לקבל.

כרגע מצאתי משהו שנקרא Allegro, שזה ספרייה לתכנות משחקים. בין האפשרויות שהיא נותנת, יש לה גם אפשרות לקלוט לחיצות מקלדת באמצעות פסיקות. לפי מה שהספקתי לקרוא, היא תומכת בבורלנד אז אולי יש סיכוי שזה יעבוד לי.

הנה הקישור:

http://www.talula.demon.co.uk/allegro/

קישור לתוכן
שתף באתרים אחרים

1) בקשר לסריקת המקלדת:

יש תוכנת משחקים (Open Source) בשם MAME32 (מומלץ כשלעצמו) שקוראת הקשות במקביל: http://www.classicgaming.com/mame32qa/

2) realloc (הדרך ה++)

אם תגדיר את המערך שלך כ:

vector<TPoint> myVect;

אז הוספה של זוג (נקודה) נוספת תראה כך:

TPoint myPoint(addThisX, addThisY);

myVect.push_back( myPoint );

(מבחינת ביצועים הכי טוב לעשות אלוקציה למקסימום הגודל ולהשתמש רק במה שצריך - לא שווה לבצע הרבה העתקות של הרבה תאים בשביל לחסוך בזכרון שתצרוך ממילא. אגב ל אובייקט vector יש פונקציה reserve ש"מכינה אותו נפשית" לגודל שאתה צופה...)

קישור לתוכן
שתף באתרים אחרים

12) realloc (הדרך ה++)

אם תגדיר את המערך שלך כ:

vector<TPoint> myVect;

אז הוספה של זוג (נקודה) נוספת תראה כך:

TPoint myPoint(addThisX, addThisY);

myVect.push_back( myPoint );

(מבחינת ביצועים הכי טוב לעשות אלוקציה למקסימום הגודל ולהשתמש רק במה שצריך - לא שווה לבצע הרבה העתקות של הרבה תאים בשביל לחסוך בזכרון שתצרוך ממילא. אגב ל אובייקט vector יש פונקציה reserve ש"מכינה אותו נפשית" לגודל שאתה צופה...)

בעניין השימוש ב vector, וב STL בכלל - אחלה רעיון, באמת לגמרי שכחתי את זה.. רק שזה לא כ"כ חובה במקרה הזה. וזה בטוח הרבה יותר איטי (לא שזה משנה משהו, כמו שאמרתי...)

12

(מבחינת ביצועים הכי טוב לעשות אלוקציה למקסימום הגודל ולהשתמש רק במה שצריך - לא שווה לבצע הרבה העתקות של הרבה תאים בשביל לחסוך בזכרון שתצרוך ממילא.)

אז זהו שלא. אולי במקרה הזה זה לא כ"כ משנה כי כמות הזכרון שיש להקצות היא במילא נורא קטנה. אבל ככלל, הדרך של הכפלת גודל המערך כל פעם שהוא מתמלא היא מאוד יעילה.

קישור לתוכן
שתף באתרים אחרים

בעניין השימוש ב vector, וב STL בכלל - אחלה רעיון, באמת לגמרי שכחתי את זה.. רק שזה לא כ"כ חובה במקרה הזה. וזה בטוח הרבה יותר איטי (לא שזה משנה משהו, כמו שאמרתי...)

המעבר מC ל C++ בא להרוויח סגנון(על כל המשתמע מכך: קריאות, תחזוקה, סטנדרטיזציה...) על חשבון הביצועים(התפשרות די קטנה).

אין שום חובה לעשות כלום. כמו שאין חובה לשים הערות או לכתוב ברור...

אז זהו שלא. אולי במקרה הזה זה לא כ"כ משנה כי כמות הזכרון שיש להקצות היא במילא נורא קטנה. אבל ככלל, הדרך של הכפלת גודל המערך כל פעם שהוא מתמלא היא מאוד יעילה.

אכן, בשני המקרים הסיבוכיות זהה. (חוצ מ realloc - n*n).

קישור לתוכן
שתף באתרים אחרים

הכוונה שלי היתה שלא חובה להשתמש פה בכלים "כבדים" כמו STL וכו'.. למרות שאתה לחלוטין צודק במה שאמרת.

בעניין הסיבוכיות, אי אפשר ממש לדעת כי אנחנו לא באמת יודעים איך ה vector פועל ולכן אנחנו יכולים רק לשער... לעומת זאת, השיטה שתיארתי (בהודעה קודמת ביתר פירוט) היא מאוד יעילה... (לא המצאתי אותה, למדתי אותה בקורס מבני נתונים באוניברסיטה... ;))

קישור לתוכן
שתף באתרים אחרים

אני מסכים אתך, הכפלת גודל האלוקציה היא מאד יעילה.

STL הוא לאו דווקא "כבד", בבורלנד הקוד מקור זמין ואפשר לראות איך הוא עובד (רוב הפונקיות הן inline).

אם אני זוכר נכון, גם vector מכפיל כל פעם את גודל האלוקציה.

קישור לתוכן
שתף באתרים אחרים

טוב אני אחזור שנייה לעניין של המקלדת:

אוף! נמאס לי!

מצאתי שתי דרכים שונות לעשות את העניין עם הפסיקות:

http://www3.telus.net/alexander_russell/course/chapter_4.htm

והדרך השנייה היא בקובץ המצורף.

הצלחתי להפעיל את הדרך השנייה רק עם DJGPP, אבל כמובן ששאר המשחק שלי לא עובד עליו.

יש סיכוי להפעיל אחת מהן בBorlandC++6?

אני הסתבכתי קודם כל בגלל שצריך dos.h בשביל הפקודה inportb ועוד כמה, ומשום מה בdos.h שיש לי, אין את הפקודה הזאת.

אז נסיתי להפעיל עם dos.h ישן יותר, אבל אז הוא לא מוכן לקמפל אותו.

עכשיו בדרך השנייה, משתמשים גם בdpmi.h ובgo32.h. וכמובן שכשניסיתי להוסיף אותם, היו לי אלף שגיאות קומפילציה.

זאת האפשרות היחידה שעובדת בDOS. בווינדוס הבנתי שכבר צריך להשתמש בDirectX וזה לא ממש בשבילי.

מישהו יכול אולי לנסות להפעיל אחת מהשיטות האלה?

ד"א - הצלחתי להשתמש בAllegro לעשות את אותה הפעולה, וזה גם עבד. אבל צריך לצרף מלא include, צריך DLL שלהם בתיקיית וחוץ מזה שזה עבד רק עם החלון של התכנית לא נמצא בפוקוס (הAllegro פותח חלון נפרד שאין בו כלום וצריך ללחוץ עליו כדי שהInput יעבוד).

עוד ד"א - אני רוצה לעשות כמה שלבים למשחק, שבכל שלב יש סידור שונה של מכשולים (קירות שאסור להתקל בהם). רציתי לדעת אם זה אפשרי לשמור את המכשולים של כל שלב ברשימה מקושרת, ואת הרשימות של כל שלב לשמור ברשימה אחת גדולה (ז"א, רשימה בתוך רשימה) שאותה אני שם בקובץ חיצוני (אולי אפילו ליצור עורך שלבים).

קישור לתוכן
שתף באתרים אחרים

טוב, עוד עדכון מהחזית:

מצאתי כמה ספריות (Lib) שנותנות להשתמש בפסיקות למקלדת.

לפי מה שאני יודע זה פותר את הבעיה של לקמפל את הקוד הבעייתי, כי הוא מגיע מוכן ורק צריך להשתמש בפונקציות.

צירפתי אחת מהן, כולל שני הincludes, קובץ cpp שמנסה להשתמש בפונקציות, ואת הספרייה עצמה.

עכשיו בבורלנד:

עשיתי add to project, הוספתי את קובץ הספרייה. עשיתי קומפילציה - אין בעיות.

ניסיתי להריץ את זה, והוא כותב לי את הerrors הבאות:

Build

[Linker Error] Unresolved external 'InitKeyScan()' referenced from C:\DOCUMENTS AND SETTINGS\ADMIN\DESKTOP\TEST.OBJ

[Linker Error] Unresolved external 'CheckKey(char)' referenced from C:\DOCUMENTS AND SETTINGS\ADMIN\DESKTOP\TEST.OBJ

[Linker Error] Unresolved external 'CloseKeyScan()' referenced from C:\DOCUMENTS AND SETTINGS\ADMIN\DESKTOP\TEST.OBJ

אלה הפוקציות שאני מנסה להשתמש בהן.

וד"א, כשאני מנסה להריץ את זה אפילו לפני שאני מוסיף לפרויקט את הספרייה, אני מקבל אותם errors.

פיספסתי משהו?

קישור לתוכן
שתף באתרים אחרים

טוב, למיקרה שמישהו גם רוצה לתכנת משחקים בדוס:

יש אפשרות לעבוד עם פסיקות כמו שצריך, אבל אפשר לעבוד עם זה רק בקומפיילרים שתומכים בדוס, כמו Turbo C++ 3.

ה-handler שמתקינים מסוגל להבחין בין כפתורים גם אם 4 לחוצים בו זמנית.

מי שרוצה לדעת איך לעשות את זה, שיכתוב פה ואני אעלה את הספריה שכתבתי לזה (לא ספרייה "סגורה", אפשר לשנות אותה).

בקשר לאיך לעבוד עם הזכרון, החלטתי בכל זאת לעבוד עם רשימה מקושרת, משתי סיבות:

1. מאוד קל להכניס איבר נוסף לרשימה לאיזה מקום שרוצים, בלי העתקות מיותרות, רק העתקות מחוונים.

2. לא הבנתי איך משתמשים בvector או בSTL, אבל נראה לי שבכל מקרה רשימה יותר מתאימה לי.

תודה על העזרה! :biggthumpup:

קישור לתוכן
שתף באתרים אחרים

טוב, ממש לא הבנתי מה זה STL.

תתחיל מהתחלה, כולל הראשי תיבות.

ד"א- התחלתי לנסות עם רשימה מקושרת, יש רק בעיה אחת - לוקח הרבה קוד ומשאבים להגיע לאיבר מסוים ברשימה (למשל האיבר החמישי, או העשרים).

אני צריך מבנה נתונים עם התכונות הבאות:

קל להוסיף בסוף איבר.

קל לבצע החלפות בין איברים.

קל להגיע לאיבר מסוים.

חשבתי אולי על מערך דינמי של מצביעים למבנים, כשבכל מבנה יש X וY.

אם המערך יהיה דינמי, אני אוכל להוסיף איברים לסוף בקלות.

אם המערך יכיל מצביעים ולא את המבנים עצמם, יהיה קל להחליף בין איברים.

יש אפשרות לדבר כזה?

קישור לתוכן
שתף באתרים אחרים

Standard Template Library

נותן לך אובייקטים לאכסון + פונקציות טיפול.

למשל כדי לצור רשימה מקושרת של אובייקטי XY (מוגדר מראש: TPoint)

list<TPoint> snake

עכשיו הנחש שלך צריך לעשות 3 דברים בסיסיים:

להתקדם, לאכול ולבדוק שהוא לא התנגש (בעצמו או בקירות)

הכרזת הclass:

class TSanke

{

list<TPoint> nodes;

public:

void Advance(TPoint point);

void Eat(int foodSize);

bool IsSelfCollide(void);

};

אגב, כנארה שתצתרך להוסיף בהתחלה:

#include <list>

#include <functional>

using namespace std;

והפונקציות עצמן:

bool equalTPoint(const TPoint a, const TPoint b)

{

return ((a.x==b.x) && (a.y==b.y));

}

void TSanke::Advance(TPoint point)

{

// add new point

nodes.push_front(point);

// remove point from back

nodes.pop_back();

}

void TSanke::Eat(int foodSize)

{

// this lines adds foodSize copies of nodes.back() (the last element) at the end of out snake :)

nodes.insert(nodes.end(), foodSize, nodes.back());

}

bool TSanke::IsSelfCollide(void)

{

if(nodes.empty())

return false;

// fook for a point on the body (= snake-head) that collides with the head(nodes.front)

// find will return nodes.end if no match was found. meaning that no collision has occured.

return find_if(++nodes.begin(), nodes.end(), bind2nd(ptr_fun(equalTPoint), nodes.front())) != nodes.end();

// bind2nd(ptr_fun(equalTPoint), nodes.front()) is used to define a custom built comparison

// as TPoint==TPoint is not defined

}

קישור לתוכן
שתף באתרים אחרים

זה נראה ממש טוב לי.

עכשיו יש לי כמה שאלות בקשר לפונקציות:

לא הבנתי את הפונקציה שבודקת להתנגשות. אני פשוט מפעיל אותה והיא בודקת אם הנחש התנגש בעצמו?

ומה לגבי התנגשות בדברים אחרים? לעשות את זה עם equalTpoint?

בפונקצית האכילה, foodsize זה בכמה להגדיל את הנחש?

לגבי הפרמטרים של הפונקציות, איך אני בודק נקודות שאני יודע את הערכים שלהם?

למשל לבדוק את ראש הנחש עם (40,78).

לפי מה שאני מבין, Nodes זו הרשימה של אוביקטים מסוג Tpoint. איך אני ניגש למשל לאיבר החמישי ברשימה, או השישי?

הראשון זה ()nodes.front

והאחרון ()nodes.end

נכון?

אבל מה מחזירות הפונקציות האלה? גם אוביקטים מסוג TPoint?

לגבי הinclude:

יש לי list.h

אבל אין functional.h

הlist.h נמצא בספרייה classlib, תחת include.

אני משתמש בTC3, ככה שיכול להיות שאין את TPoint.

יש אולי תיעוד יותר מפורט של הספרייה הזו?

עריכה - לדעתי הTC3 משתמש במשהו שונה מSTL.

ניסיתי להפעיל את התכנית הזאת, והוא לא מזהה את TPoint.

אבל זה בעיה קטנה, כי אני יכול להשתמש במבנה משלי שיכיל את הנקודות.

אני חושב שהרשימה שאתה מתאר שונה מהרשימה שיש אצלי.

עוד עריכה - החלפתי את TPoint במבנה שלי.

עכשיו אין לו בעיה אם זה רק שהוא לא מכיר אף אחת מהפונקציות שהשתמשת.

אני אנסה לקרוא קצת בעזרה של הTC, אולי אני אצליח להבין איך להשתמש באחד הכלים שיש שם. בינתיים ראיתי שיש:

list - רשימה רגילה.

double list - רשימה כפולה (אפשר ללכת מהזנב או מהראש).

deque - כמו מחסנית רק דו צדדי. אפשר להכניס ולהוציא משני הצדדים.

הבעיה באלה (ובמה שנתת לי) זה שדי קשה להגיע לאיבר מסוים ברשימה (לפי index).

אין מבנה נתונים שהוא מערך רק שאפשר להוסיף ולהוריד איברים ממנו?

קישור לתוכן
שתף באתרים אחרים

הפוקצייה שבודקת התנגשות מחפשת בגוף הנחש (הכל חוץ מהראש) חוליה השווה בקורדינאטות לזו של הראש (nodes.front). אם היא מוצאת כזו (יש התנגשות) והיא מחזירה את המיקום שלה אם היא לא מוצאת אז היא מחזירה nodes.end ואז בדיקת ההתנגשות מחזירה false. אתה צריך לבדוק רק את ראש הנחש כי שאר הגוף נמצא במקומות שהראש היה בהם והם כבר נבדקו.

את equalTPoint אני הגדרתי כי ל TPoint שלי לא היה מוגדר == אם אתה מגדיר את TPoint לבד אתה יכול להגדיר לו לבד פונקציית השוואה.

אין ל list גישה אקראית. אתה לא יכול לגשת ישירות לאיבר ה5 - מצד שני אני לא רואה מדוע אתה צריך ?

הראשון זה ()nodes.front

והאחרון ()nodes.end

נכון?

בערך: front ו back הם האיברים. begin הוא כמו פוינטר (נקרא iterator) שמצביע לאיבר הראשון ו end באופן דומה אבל, לאיבר אחד אחרי כמו שאתה מגדיר מערך int a[10] אז לולאה נראית כך: for(int i=0 ; i != 10 ; i++(

a[10] לא קיים, זה איבר אחד אחרי הסוף. באופן דומה: nodes.end

שים לב ל++ בקריאה ל find שדואגת לדלג על הראש.

אם אתה רוצה לצייר את הנחש:

for_each(nodes.begin(), nodes.end(), drawNode);

תעשה את העבודה כש drawNode היא פונקציה שמקלת נקודה מציירת אותה.

ההגדרה של TPoint:

struct TPoint

{

TPoint() {}

TPoint(int _x, int _y) : x(_x), y(_y) {}

TPoint(POINT& pt)

{

x = pt.x;

y = pt.y;

}

int x;

int y;

};

אתה עובד בדוס ?

אני לא מכיר את TC3 (עבדתי עם BC3.1 ויש לי אם אתה מעוניין)

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.


×
  • צור חדש...