Προς το περιεχόμενο

[C++] - Δημιουργία Λαβυρίνθων


bnvdarklord

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Πριν κάνα χρόνο είχα φτιάξει ενα πρόγραμμα σε C++ που παράγει τυχαίους λαβυρίνθους. Ήθελα να το ανεβάσω εδώ, αλλα το είχα ξεχάσει, μέχρι που το βρήκα τώρα τυχαία στο pc.

 

Θα εκτιμούσα τα σχόλια σας, αν έχετε χρόνο, για τον ίδιο τον κώδικα. Αν κάνω κάτι με χαζό τρόπο, ή μη αποδοτικά κτλ.

 

 

(το bitmap.h το πήρα έτοιμο απο κάπου στο internet και το τροποίησα ελάχιστα)

(χρειάζεται flag -std=c++11 για compile)

 

Ευχαριστώ.

 

edit: Δείτε την νεότερη έκδοση εδώ: https://github.com/InsomniaProjects/maze-generator

mz.zip

Επεξ/σία από bnvdarklord
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 45
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Λαθος "σπασιμο" σε αρχεια.

Το bitmap.h εχει ενα undefined Color το οποιο δεν το βλεπεις επειδη εχει include color.h στην maze.h, δηλαδη εχεις δυο αρχεια. Την main.cpp και την maze.h, ομως η τελευταια εχει και definitions αρα εχεις ενα αρχειο ολο κι ολο, την main.cpp

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Είπα να το δω λίγο, είδα ότι αν το πήγαινα "μέχρι τέλους" θα έκανα πάρα πολλές αλλαγές, σκέφτηκα wtf...

 

Ο,τι κάνω (δεν ξέρω από χρόνο τι θα γίνει) θα το κάνω εδώ:

 

https://github.com/InsomniaProjects/maze-generator

 

darklord, αν σε χαλάει που το έβαλα online ή που επέλεξα MIT license πες να το σιγυρίσουμε. Commit rights υπάρχουν για όποιον πιστεύει πως θέλει να τα χρησιμοποιήσει, στείλτε μου πμ με το username σας.

 

Προς το παρόν πείραξα μόνο το Color.h (και πρόσθεσα το σχετικό Color.cpp), επίσης έβαλα ένα VS2012 project για ευκολία.

  • Like 2
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Thanks για τον χρόνο σου.

 

Όχι δεν με πειράζει που το ανέβασες, κάτι που έφτιαξα για να θυμηθώ την C++ ήταν.

 

Παρόλα αυτά, αλλαγές χωρις εξήγησεις δεν μου προσφέρουν κάτι.

Πχ είδα χώρησες definitions και implementation. Απο συνήθεια που εγραφα σε java και c# τα είχα σε ένα αρχείο είναι η αλήθεια, αλλα γιατι "πρέπει" να είναι χωριστά;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μπερδεύτηκα. 

 

Tι εννοεις έχω ενα αρχείο ολο κι ολο;

https://github.com/InsomniaProjects/maze-generator/blob/master/src/Bitmap.h

Εδω εχεις εναν "header" που ειναι "δεμενος" με το color.h μεσου https://github.com/InsomniaProjects/maze-generator/blob/master/src/Maze.h .

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Cool.

 

Απο δω και πέρα οι αλλαγές θα συνοδεύονται από commit messages και θα είναι μικρές και αυτοτελείς, οπότε θα προσφέρουν. Ήταν και βασικός λόγος που το έβαλα στο git.

 

Definitions/implementation: σε οποιοδήποτε πραγματικό πρόγραμμα με πάνω από 1 TU το οποίο κάνει include τον header σου, ένα definition στον header θα έχει σαν αποτέλεσμα να υπάρχουν στο τέλος πολλαπλά definitions και να παραβιάζεται ο ODR (στην πράξη έχεις linker error).

 

Τώρα στο συγκεκριμένο πρόγραμμα που είναι όλο κι όλο ένα TU τέτοιο θέμα δεν υπάρχει, αλλά το κάνω από συνήθεια.

 

Μπορείς επίσης να αποφασίσεις πως θα βάλεις τα πάντα όλα μέσα στους headers (όχι όμως όπως το κάνεις εσύ -- για παράδειγμα θα πρέπει όλες οι methods να μαρκαριστούν inline αν έχεις πάνω από 1 TU), και σε κάποιες περιπτώσεις όντως το κάνουν αυτό, αλλά υπάρχουν σοβαρά μειονεκτήματα (π.χ. μια αλλαγή σε ένα header => recompile the universe, κάτι που είναι τόσο προβληματικό by default που υπάρχει ειδικό trick για να το αποφύγεις).

 

Το παπί σωστά λέει ότι υπάρχει θέμα στο Bitmap.h: χρησιμοποιεί το definition του Color αλλά δεν κάνει include το Color.h -- επαφίεται στο ότι το ίδιο το Bitmap.h γίνεται included στο TU μόνο αφού έχει ήδη γίνει "με κάποιο μαγικό τρόπο" ήδη include το Color.h. Αυτό είναι λάθος γιατί κρύβεις το υπαρκτό dependency του ενός στο άλλο.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Είπα να το δω λίγο, είδα ότι αν το πήγαινα "μέχρι τέλους" θα έκανα πάρα πολλές αλλαγές, σκέφτηκα wtf...

 

Ο,τι κάνω (δεν ξέρω από χρόνο τι θα γίνει) θα το κάνω εδώ:

 

https://github.com/InsomniaProjects/maze-generator

 

darklord, αν σε χαλάει που το έβαλα online ή που επέλεξα MIT license πες να το σιγυρίσουμε. Commit rights υπάρχουν για όποιον πιστεύει πως θέλει να τα χρησιμοποιήσει, στείλτε μου πμ με το username σας.

 

Προς το παρόν πείραξα μόνο το Color.h (και πρόσθεσα το σχετικό Color.cpp), επίσης έβαλα ένα VS2012 project για ευκολία.

 

 

Μερικα issues που βρηκα κανωντας review:

 

https://github.com/InsomniaProjects/maze-generator/issues

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

https://github.com/InsomniaProjects/maze-generator/blob/master/src/Bitmap.h

Εδω εχεις εναν "header" που ειναι "δεμενος" με το color.h μεσου https://github.com/InsomniaProjects/maze-generator/blob/master/src/Maze.h .

 

Το παπί σωστά λέει ότι υπάρχει θέμα στο Bitmap.h: χρησιμοποιεί το definition του Color αλλά δεν κάνει include το Color.h -- επαφίεται στο ότι το ίδιο το Bitmap.h γίνεται included στο TU μόνο αφού έχει ήδη γίνει "με κάποιο μαγικό τρόπο" ήδη include το Color.h. Αυτό είναι λάθος γιατί κρύβεις το υπαρκτό dependency του ενός στο άλλο.

 

Ουσιαστικά λοιπόν το (μόνο ; ) πρόβλημα με τα έμμεσα includes υπάρχει επειδή αν θελήσω να πάρω το Bitmap.h για κάποιο άλλο project δεν φαίνεται ευκολα οτι ειναι dependent από το Color.h. 

 

 

Definitions/implementation: σε οποιοδήποτε πραγματικό πρόγραμμα με πάνω από 1 TU το οποίο κάνει include τον header σου, ένα definition στον header θα έχει σαν αποτέλεσμα να υπάρχουν στο τέλος πολλαπλά definitions και να παραβιάζεται ο ODR (στην πράξη έχεις linker error).

Το εξηγείς λίγο αυτό;

 

Τώρα στο συγκεκριμένο πρόγραμμα που είναι όλο κι όλο ένα TU τέτοιο θέμα δεν υπάρχει, αλλά το κάνω από συνήθεια.

Είδα λιγο στο wiki τι ειναι το translation unit. Πώς γινεται να έχεις 2 στο ιδιο project;

 

 

Μπορείς επίσης να αποφασίσεις πως θα βάλεις τα πάντα όλα μέσα στους headers (όχι όμως όπως το κάνεις εσύ -- για παράδειγμα θα πρέπει όλες οι methods να μαρκαριστούν inline αν έχεις πάνω από 1 TU), και σε κάποιες περιπτώσεις όντως το κάνουν αυτό, αλλά υπάρχουν σοβαρά μειονεκτήματα (π.χ. μια αλλαγή σε ένα header => recompile the universe, κάτι που είναι τόσο προβληματικό by default που υπάρχει ειδικό trick για να το αποφύγεις).

 

Δηλαδή όπως έχω το Maze.h χωριστά σε αντίθεση με το Color.h που ειναι C# style;

 

 

  

 

Μερικα issues που βρηκα κανωντας review:

 

https://github.com/InsomniaProjects/maze-generator/issues

Thanks. Το Bitmap.h αν θυμάμαι καλά οταν το δοκίμασα πρώτη φορά μου έβγαζε εικόνες που δεν διαβαζαν τα windows και νομίζω κατι άλλαξα(έσβησα ισως ; ) από τους headers. Ίσως ήταν για linux μονο; Περίεργο πάντως που το .bmp πρότυπο μπορει να μην ειναι 100% cross platform.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

 

 

Το εξηγείς λίγο αυτό;

 

 

Είδα λιγο στο wiki τι ειναι το translation unit. Πώς γινεται να έχεις 2 στο ιδιο project;

 

 

 

 

Το translation unit ουσιαστικα ειναι το αρχειο που γινεται compile. Το αρχειο που κουμπωνεις στον compiler.

Τα header files ειναι "τζουφια" αρχεια, ειναι copypaste, ειναι το ctrl+c. Εκει που θα βαλεις το include  εκει θα γινει το paste το ctrl+v.

Εδω εισαι. https://github.com/AnonymoPapaki/maze-generator/tree/master/src

4 tu

 

ΥΓ: Πως τα καταφερα και το ανεβασα το project, ενας θεος ξερει... Την τελευταια φορα ειχα καψει 213321 ωρες, απλα για να κατεβασω ενα project...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ουσιαστικά λοιπόν το (μόνο ; ) πρόβλημα με τα έμμεσα includes υπάρχει επειδή αν θελήσω να πάρω το Bitmap.h για κάποιο άλλο project δεν φαίνεται ευκολα οτι ειναι dependent από το Color.h.

Και ότι αν χρειαστείς το Bitmap.h σε δεύτερο ή τρίτο κλπ TU θα πρέπει να κάνεις και από εκεί το include. Που είναι καγκουριά.

 

Αφού υπάρχει dependency βάζεις το include εκεί που πρέπει και τελειώνει η υπόθεση. Δεν υπάρχει κανένας λόγος να το κάνεις διαφορετικά.

 

Το εξηγείς λίγο αυτό;

Το τι είναι ODR θεωρητικά εννοείς ή στην πράξη;

 

Στην πράξη αν πάρεις το definition του Color::Yellow από το Color.cpp και το βάλεις στο .h, αφήνοντας το Color.cpp (και το #include "Color.h") μέσα στο project τότε έχεις 2 TU (το Color.cpp και το MazeGenerator.cpp) καθένα από τα οποία δίνει δικό του definition στο Color::Yellow. Αυτό έχει σαν αποτέλεσμα στο πρόγραμμα σα σύνολο το Color::Yellow να έχει πάνω από ένα definition πράγμα το οποίο αποτελεί παραβίαση του ODR. Το αποτέλεσμα:

1>MazeGenerator.obj : error LNK2005: "public: static class Color const Color::Yellow" ( ?Yellow@Color@@2V1@Β ) already defined in Color.obj
1>F:\www\maze\build\vs2012\Debug\Maze.exe : fatal error LNK1169: one or more multiply defined symbols found

Είδα λιγο στο wiki τι ειναι το translation unit. Πώς γινεται να έχεις 2 στο ιδιο project;

 

TU σε απλά ελληνικά είναι κάθε ένα αρχείο που ταϊζεις στον compiler συν τα διάφορα includes που κάνει αυτό άμεσα ή έμμεσα. Δηλαδή σε ένα project όσα .cpp αρχεία έχεις τόσα θα είναι και τα TU, οπότε πολύ εύκολο σε real life project να έχεις όχι 2 αλλά και 222.

 

Δηλαδή όπως έχω το Maze.h χωριστά σε αντίθεση με το Color.h που ειναι C# style;

Όχι, το Maze.h είναι παράδειγμα προβλήματος που περιμένει να εμφανιστεί.

 

Για να το πω συνοπτικά, μια method που είναι inline επιτρέπεται να έχει παραπάνω από ένα definition στο πρόγραμμα σα σύνολο (αν δεν είναι, τότε ODR). Το inline μπορεί να το πάρει implicitly αν το definition της μεθόδου δίνεται μέσα στην class, πράγμα το οποίο είναι και ο λόγος που αν έχεις π.χ. αυτό το header:

 

class whatever { public: void foo() { /* ... */ }; };

μπορείς να το κάνεις include σε όσα TU θέλεις και επειδή η foo είναι inline το πρόγραμμα θα κάνει compile κανονικά χωρίς προβλήματα.

 

Αν όμως το header ήταν όπως τα έχεις εσύ, δηλαδη

class whatever { public: void foo(); };
void whatever::foo() { /* */ }

τότε η foo δεν είναι inline και κάνοντας include αυτό το header σε παραπάνω από 1 TU θα έχεις το ίδιο error LNK1169 επειδή παραβίασες το ODR. Αν όμως επιπλέον κάνεις τη foo explicitly inline με inline void foo(); τότε θα είσαι εντάξει και πάλι.

 

Συμπερασματικά, εσύ έχεις τις methods να μην είναι inline (δίνεις το definition ξεχωριστά) και με ανοιχτό το ενδεχόμενο να υπάρχει το definition αυτό σε παραπάνω από 1 TU (αφού είναι σε header που μπορεί να γίνει include, ενώ αν τα είχες σε cpp τότε αυτό θα ήταν και το μοναδικό TU στο οποίο εμφανίζονται). Αυτό είναι πρόβλημα. Μπορείς να το δεις εύκολα στην πράξη βάζοντας μέσα στο Color.cpp ένα #include "Maze.h" και βλέποντας τα πυροτεχνήματα.

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ευχαριστώ. Θα τα ξαναδιαβάσω άλλη μια και αυριο με πιο καθαρό μυαλό.

 

Αυτο που δεν κατάλαβα ομως ειναι το εξης:

Λες αν έχω Color.h και Color.cpp και βαλω definition στο 1ο, έχω διπλό definition. Ωραία. Αν δεν κρατήσω όμως το Color.cpp και έχω μονο το Color.h αυτό το πρόβλημα δεν υπάρχει. Οπότε τι πειράζει να είναι σε ένα αρχείο;

 

Σόρυ αν πρήζω, θέλω να τα καταλάβω καλά, γιατι αλλιώς δεν προκειται να τα εφαρμόσω.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Moderators

Ευχαριστώ. Θα τα ξαναδιαβάσω άλλη μια και αυριο με πιο καθαρό μυαλό.

 

Αυτο που δεν κατάλαβα ομως ειναι το εξης:

Λες αν έχω Color.h και Color.cpp και βαλω definition στο 1ο, έχω διπλό definition. Ωραία. Αν δεν κρατήσω όμως το Color.cpp και έχω μονο το Color.h αυτό το πρόβλημα δεν υπάρχει. Οπότε τι πειράζει να είναι σε ένα αρχείο;

 

Σόρυ αν πρήζω, θέλω να τα καταλάβω καλά, γιατι αλλιώς δεν προκειται να τα εφαρμόσω.

 

Γιατί δεν διαβάζονται. Με αυτή τη λογική, φαντάζεσαι να έχεις ένα πρόγραμμα 10.000 γραμμών σε ένα αρχείο;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...