Δημοσιεύτηκε: 25 Απρ 2012, 22:54
Πολλά, πολλά μπράβο Ηλία!
Δεν το είχα πάρει χαμπάρι πως άνοιξες ξεχωριστό νήμα! Πολύ καλά έκανες
Off topic:
Εγώ είχα ξεκινήσει να αναδιοργανώνω τον κώδικα ώστε να είναι πιο ευέλικτος σε αλλαγές, να στήσω σκελετό δηλαδή, αλλά το σταμάτησα γιατί είχα δουλειές. Σήμερα είπα να το συνεχίσω, αλλά τελικά στη το ξαναφτιάχνω από το 0, υλοποιώντας το με OOP λογική. Χωρίς κληρονομικότητες, πολυμορφισμούς, κλπ, αλλά με encapsulation και αυτονομία των δομών που θα παίζουν το ρόλο των κλάσεων.
Για να μην τα πολυλογώ, μου χει βγει το λάδι να διπλογράφω κώδικα, για να είναι συμβατός με την OOP λογική. Δηλαδή μια "κλάση" να μην έχει πρόσβαση στα private members οποιασδήποτε άλλης, και ότι θέλει να το ζητάει μέσω μεθόδων (συναρτήσεων δηλαδή) από το interface της κλάσης.
Προς το παρόν έχω φτιάξει μονάχα την "κλάση" Animal_T (βάζω τη λέξη σε εισαγωγικά, γιατί δεν είναι κανονική κλάση) η οποία περιέχει μια άλλη, την AnimalName που είναι το όνομα του ζώου. Το έχω κάνει έτσι, γιατί λόγω της υποστήριξης πολλών γλωσσών, το όνομα δεν είναι ένα απλό string, έχει ενικό, πληθυντικό, άρθρο διαφορετικό γένους για το κάθε ζώο, και του 'χω βάλει και αιτιατική (ώστε π.χ. στα Ελληνικά να μπορείς να γράψεις και "δες λύκο" και "δες λύκος").
Κανονικά η "κλάση" AnimalName πρέπει να πάει σε δικό της ξεχωριστό αρχείο, με το private interface της υλοποιημένο σε δικό της .c αρχείο και το public σε .h αρχείο, αλλά βαρέθηκα και την άφησα στο ίδιο με την Animal_T. Οπότε σε ένα αρχείο υλοποιώ και το private και το public interface και των 2 "κλάσεων". Οπότε όταν κάποιος θελήσει να ζητήσει κάτι από την AnimalName (ή να της αλλάξει κάτι) πρέπει να το κάνει μέσω του public interface της Animal_T (η οποία με τη σειρά της το μεταβιβάζει στην AnimalName μέσω του public interface αυτηνής).
Βασικά η νοοτροπία του OOP ομοιάζει σεA πολλές τομείς με αυτήν των βιβλιοθηκών, υπό την έννοια πως πρέπει ο κώδικας να είναι γραμμένος γενικά και αυτόνομα για την κάθε "κλάση". Ώστε να μπορεί να δέχεται μελλοντικές αλλαγές/βελτιώσεις/αναβαθμίσεις χωρίς να επηρεάζονται τα προγράμματα που τη χρησιμοποιούν ήδη. Αυτά χρησιμοποιούν το public interface της "κλάσης"/βιβλιοθήκης, ενώ η υλοποίησή της είναι private. Αν είναι εξαρχής σωστά σχεδιασμένο το public interface και η private υλοποίηση, τότε οι μελλοντικές αλλαγές είναι εν πολλοίς απλώς προσθήκη νέων properties & μεθόδων στην υλοποίηση και αντίστοιχες συναρτήσεις διαχείρισής τους στο public interface.
Δίνεις δηλαδή στον άλλον τον interface της κλάσης σου (το .header αρχείο) μαζί με το object αρχείο της κι αρχίζει να φτιάχνει προγράμματα που χρησιμοποιούν τα ζώα της κλάσης σου, χωρίς να ξέρει και χωρίς να τον ενδιαφέρει πως είναι υλοποιημένα εσωτερικά.
Το public interface της "κλάσης" Animal_T που έχω κάνει μέχρι στιγμής είναι αυτό εδώ το .h αρχείο...
όπου ο χρήστης το μόνο που χρειάζεται να ξέρει είναι ότι περιέχει αυτό το αρχείο (πλην της γλώσσας, που θέλει re-compilation του animal.c). Αν του δώσεις μαζί και το .o αρχείο (ή μάλλον τα .o αρχεία, ένα για κάθε γλώσσα) τότε μπορεί να ξεκινήσει να χρησιμοποιεί απευθείας ότι του παρέχει η "κλήση"/βιβλιοθήκη.
Π.χ...
Για να μπορεί να χρησιμοποιήσει και τα media, πρέπει στο ζιπ με το .h και τα .o να υπάρχουν και τα αρχεία εικόνας και βίντεο του κάθε ζώου, τοποθετημένα στο σωστό directory (αλλιώς μπορεί να βάλει δικά του, με την προϋπόθεση πως θα τα βάλει στον φάκελο που τα περιμένει η "κλάση"/βιβλιοθήκη και θα τα ονοματίζει με τα ονόματα που περιμένει η βιβλιοθήκη).
Ο κώδικας της εσωτερικής υλοποίησης είναι εδώ (χωρίς τα αρχεία media) : http://www.box.com/s/fb6b2fe18e2246ab22ec
Όποιος θέλει να βάλει δικά του αρχεία media, τότε οι εικόνες πρέπει να έχουν κατάληξη .jpg και τα βίντεο .flv και τα κύρια ονόματα των αρχείων πρέπει να είναι αυτά που έχει στην αρχή του αρχείο animal.c ως key-names, δηλαδή αυτά...
Και πρέπει να μπουν σε έναν υποφάκλεο φάκελο: data/media στο κύριο φάκελο του προγράμματός σας (του εκτελέσιμου δηλαδή που θα χρησιμοποιεί την βιβλιοθήκη).
Δηλαδή για να σας ανοίξει το βίντεο του λύκου η κλήση της συνάρτησης...
χρειάζεται να υπάρχει το αρχείο: data/media/wolf.flv (για εικόνα, data/media/wolf.jpg );
Οπότε για παράδειγμα, αν βάλετε 2 τέτοια αρχεία, τότε σε ένα δικό σας πρόγραμμα που θα το κάνετε compile μαζί με το animal.o ή animal.c ...
μπορείτε να γράψετε κάτι σαν αυτό για να σας ανοίξει τα media...
Οι συναρτήσεις που μπορείτε να χρησιμοποιήσετε είναι τεκμηριωμένες στο animal.h. Προφανώς ακόμα τα ζώα δεν μπορούν να κάνουν πολλά πράγματα, γιατί είμαι στην αρχή. Επίσης δεν έχω βγάλει public συναρτήσεις που μπορούν να αλλάξουν τη διάθεση, την υγεία, κλπ του ζώου απευθείας. Έχω βάλει όμως randomizers, είτε για την υγεία, είτε για την διάθεση είτε και για τα 2 μαζί. Μπορείτε επίσης να τα δημιουργήστε εξαρχής randomly, με τις: animal_new_random() και animal_new_Random()
Τα ζώα κάνουν 3 κινήσεις: attack, wander και hide οι οποίες δεν είναι πάντα ίδιες, αλλά επηρεάζονται από την τρέχουσα υγεία και διάθεσή του. Αν για παράδειγμα ένα ζώο είναι ετοιμοθάνατο και του πείτε: animal_attack() τότε θα σας πει κάτι σαν "και να θέλει δεν μπορεί"... βασικά το τι θα σας πει ακριβώς εξαρτάται κι από την διάθεσή του.
Μπορείτε επίσης να δώσετε γενικώς: animal_move() οπότε ανάλογα την υγεία του και τη διάθεσή του θα διαλέξει μόνο του αν θα επιτεθεί, αν θα μείνει αδιάφορο ή αν θα απομακρυνθεί φοβισμένο.
Από default η γλώσσα είναι Αγγλικά και είναι ενεργοποιημένα τα debugging info (στα σφάλματα "βαράει" καμπανάκι εκτός από κείμενο). Για να αλλάξετε γλώσσα, όταν κάνετε compile το animal.c δώστε στον compiler -DLANG_EL ή -DLANG_EL_GREEKLISH (χωρίς τίποτα ή με -DLANG_EN βγάζει αγγλικά).
Για τα debugging info, δώστε -DANIMAL_NODEBUG αν δεν θέλετε να σας ειδοποιεί για σφάλματα.
Αν υπάρχει κάνα bug μου λέτε.
ΥΓ. Επίτηδες έβαλα το link κατεβάσματος στη μέση της... έκθεσης, για να το κατεβάσουν μόνο οι σοβαροί
Δεν το είχα πάρει χαμπάρι πως άνοιξες ξεχωριστό νήμα! Πολύ καλά έκανες
Off topic:
Εγώ είχα ξεκινήσει να αναδιοργανώνω τον κώδικα ώστε να είναι πιο ευέλικτος σε αλλαγές, να στήσω σκελετό δηλαδή, αλλά το σταμάτησα γιατί είχα δουλειές. Σήμερα είπα να το συνεχίσω, αλλά τελικά στη το ξαναφτιάχνω από το 0, υλοποιώντας το με OOP λογική. Χωρίς κληρονομικότητες, πολυμορφισμούς, κλπ, αλλά με encapsulation και αυτονομία των δομών που θα παίζουν το ρόλο των κλάσεων.
Για να μην τα πολυλογώ, μου χει βγει το λάδι να διπλογράφω κώδικα, για να είναι συμβατός με την OOP λογική. Δηλαδή μια "κλάση" να μην έχει πρόσβαση στα private members οποιασδήποτε άλλης, και ότι θέλει να το ζητάει μέσω μεθόδων (συναρτήσεων δηλαδή) από το interface της κλάσης.
Προς το παρόν έχω φτιάξει μονάχα την "κλάση" Animal_T (βάζω τη λέξη σε εισαγωγικά, γιατί δεν είναι κανονική κλάση) η οποία περιέχει μια άλλη, την AnimalName που είναι το όνομα του ζώου. Το έχω κάνει έτσι, γιατί λόγω της υποστήριξης πολλών γλωσσών, το όνομα δεν είναι ένα απλό string, έχει ενικό, πληθυντικό, άρθρο διαφορετικό γένους για το κάθε ζώο, και του 'χω βάλει και αιτιατική (ώστε π.χ. στα Ελληνικά να μπορείς να γράψεις και "δες λύκο" και "δες λύκος").
Κανονικά η "κλάση" AnimalName πρέπει να πάει σε δικό της ξεχωριστό αρχείο, με το private interface της υλοποιημένο σε δικό της .c αρχείο και το public σε .h αρχείο, αλλά βαρέθηκα και την άφησα στο ίδιο με την Animal_T. Οπότε σε ένα αρχείο υλοποιώ και το private και το public interface και των 2 "κλάσεων". Οπότε όταν κάποιος θελήσει να ζητήσει κάτι από την AnimalName (ή να της αλλάξει κάτι) πρέπει να το κάνει μέσω του public interface της Animal_T (η οποία με τη σειρά της το μεταβιβάζει στην AnimalName μέσω του public interface αυτηνής).
Βασικά η νοοτροπία του OOP ομοιάζει σεA πολλές τομείς με αυτήν των βιβλιοθηκών, υπό την έννοια πως πρέπει ο κώδικας να είναι γραμμένος γενικά και αυτόνομα για την κάθε "κλάση". Ώστε να μπορεί να δέχεται μελλοντικές αλλαγές/βελτιώσεις/αναβαθμίσεις χωρίς να επηρεάζονται τα προγράμματα που τη χρησιμοποιούν ήδη. Αυτά χρησιμοποιούν το public interface της "κλάσης"/βιβλιοθήκης, ενώ η υλοποίησή της είναι private. Αν είναι εξαρχής σωστά σχεδιασμένο το public interface και η private υλοποίηση, τότε οι μελλοντικές αλλαγές είναι εν πολλοίς απλώς προσθήκη νέων properties & μεθόδων στην υλοποίηση και αντίστοιχες συναρτήσεις διαχείρισής τους στο public interface.
Δίνεις δηλαδή στον άλλον τον interface της κλάσης σου (το .header αρχείο) μαζί με το object αρχείο της κι αρχίζει να φτιάχνει προγράμματα που χρησιμοποιούν τα ζώα της κλάσης σου, χωρίς να ξέρει και χωρίς να τον ενδιαφέρει πως είναι υλοποιημένα εσωτερικά.
Το public interface της "κλάσης" Animal_T που έχω κάνει μέχρι στιγμής είναι αυτό εδώ το .h αρχείο...
Spoiler: show
όπου ο χρήστης το μόνο που χρειάζεται να ξέρει είναι ότι περιέχει αυτό το αρχείο (πλην της γλώσσας, που θέλει re-compilation του animal.c). Αν του δώσεις μαζί και το .o αρχείο (ή μάλλον τα .o αρχεία, ένα για κάθε γλώσσα) τότε μπορεί να ξεκινήσει να χρησιμοποιεί απευθείας ότι του παρέχει η "κλήση"/βιβλιοθήκη.
Π.χ...
Spoiler: show
Για να μπορεί να χρησιμοποιήσει και τα media, πρέπει στο ζιπ με το .h και τα .o να υπάρχουν και τα αρχεία εικόνας και βίντεο του κάθε ζώου, τοποθετημένα στο σωστό directory (αλλιώς μπορεί να βάλει δικά του, με την προϋπόθεση πως θα τα βάλει στον φάκελο που τα περιμένει η "κλάση"/βιβλιοθήκη και θα τα ονοματίζει με τα ονόματα που περιμένει η βιβλιοθήκη).
Ο κώδικας της εσωτερικής υλοποίησης είναι εδώ (χωρίς τα αρχεία media) : http://www.box.com/s/fb6b2fe18e2246ab22ec
Όποιος θέλει να βάλει δικά του αρχεία media, τότε οι εικόνες πρέπει να έχουν κατάληξη .jpg και τα βίντεο .flv και τα κύρια ονόματα των αρχείων πρέπει να είναι αυτά που έχει στην αρχή του αρχείο animal.c ως key-names, δηλαδή αυτά...
- Κώδικας: Επιλογή όλων
/* key-names of animals */
#define STR_BADGER "badger"
#define STR_BEAR "bear"
#define STR_DEER "deer"
#define STR_DUCK "duck"
#define STR_FERRET "ferret"
#define STR_FOX "fox"
#define STR_RABBIT "rabbit"
#define STR_RACOON "racoon"
#define STR_WLDBOAR "wild-boar"
#define STR_WOLF "wolf"
Και πρέπει να μπουν σε έναν υποφάκλεο φάκελο: data/media στο κύριο φάκελο του προγράμματός σας (του εκτελέσιμου δηλαδή που θα χρησιμοποιεί την βιβλιοθήκη).
Δηλαδή για να σας ανοίξει το βίντεο του λύκου η κλήση της συνάρτησης...
- Κώδικας: Επιλογή όλων
animal_media_open_video();
χρειάζεται να υπάρχει το αρχείο: data/media/wolf.flv (για εικόνα, data/media/wolf.jpg );
Οπότε για παράδειγμα, αν βάλετε 2 τέτοια αρχεία, τότε σε ένα δικό σας πρόγραμμα που θα το κάνετε compile μαζί με το animal.o ή animal.c ...
- Κώδικας: Επιλογή όλων
gcc animal.c mypro.c -o myprog
μπορείτε να γράψετε κάτι σαν αυτό για να σας ανοίξει τα media...
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include "animal.h"
int main( void )
{
Animal_T *a = animal_new( ATID_WOLF );
if ( !a ) {
puts( "internal error" );
return 1;
}
/* open the wolf image */
animal_media_open_image( a );
/* play the wolf video */
animal_media_open_video( a );
animal_free( a );
return 0;
}
Οι συναρτήσεις που μπορείτε να χρησιμοποιήσετε είναι τεκμηριωμένες στο animal.h. Προφανώς ακόμα τα ζώα δεν μπορούν να κάνουν πολλά πράγματα, γιατί είμαι στην αρχή. Επίσης δεν έχω βγάλει public συναρτήσεις που μπορούν να αλλάξουν τη διάθεση, την υγεία, κλπ του ζώου απευθείας. Έχω βάλει όμως randomizers, είτε για την υγεία, είτε για την διάθεση είτε και για τα 2 μαζί. Μπορείτε επίσης να τα δημιουργήστε εξαρχής randomly, με τις: animal_new_random() και animal_new_Random()
Τα ζώα κάνουν 3 κινήσεις: attack, wander και hide οι οποίες δεν είναι πάντα ίδιες, αλλά επηρεάζονται από την τρέχουσα υγεία και διάθεσή του. Αν για παράδειγμα ένα ζώο είναι ετοιμοθάνατο και του πείτε: animal_attack() τότε θα σας πει κάτι σαν "και να θέλει δεν μπορεί"... βασικά το τι θα σας πει ακριβώς εξαρτάται κι από την διάθεσή του.
Μπορείτε επίσης να δώσετε γενικώς: animal_move() οπότε ανάλογα την υγεία του και τη διάθεσή του θα διαλέξει μόνο του αν θα επιτεθεί, αν θα μείνει αδιάφορο ή αν θα απομακρυνθεί φοβισμένο.
Από default η γλώσσα είναι Αγγλικά και είναι ενεργοποιημένα τα debugging info (στα σφάλματα "βαράει" καμπανάκι εκτός από κείμενο). Για να αλλάξετε γλώσσα, όταν κάνετε compile το animal.c δώστε στον compiler -DLANG_EL ή -DLANG_EL_GREEKLISH (χωρίς τίποτα ή με -DLANG_EN βγάζει αγγλικά).
Για τα debugging info, δώστε -DANIMAL_NODEBUG αν δεν θέλετε να σας ειδοποιεί για σφάλματα.
Αν υπάρχει κάνα bug μου λέτε.
ΥΓ. Επίτηδες έβαλα το link κατεβάσματος στη μέση της... έκθεσης, για να το κατεβάσουν μόνο οι σοβαροί