Τα πάντα για την C

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 12 Απρ 2012, 20:11

migf1 έγραψε:Μπορείς επίσης να τον αφήνεις να πυροβολεί μέχρι ένα όριο φορών (και καλά μετά ξεμένει από πυρομαχικά).

Στο μυαλό μου είσαι. :D
Σκέφτηκα να ξεκινάει ο χρήστης με κάποιες σφαίρες και μερικά χρήματα και ανάλογα με το αν καταφέρνει να σκοτώσει ζώα ή όχι θα αποκτά περισσότερο χρυσάφι ώστε να αγοράσει περισσότερες σφαίρες. Όταν κάποια στιγμή μείνει χωρίς σφαίρες θα παίρνει ένα μήνυμα σαν "Ήρθε η σειρά των ζώων να διασκεδάσουν." :lol:.

Ξεφεύγει βέβαια λιγάκι απ' την αρχική ιδέα, αλλά δεν πειράζει. :)

Spoiler: show
Off topic:
Δεν μπόρεσα να κρατηθώ. :lol:
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 12 Απρ 2012, 21:16

Ilias95 έγραψε:
...
Ξεφεύγει βέβαια λιγάκι απ' την αρχική ιδέα, αλλά δεν πειράζει. :)

Καθόλου δεν πειράζει! Δικό σου είναι όπως θέλεις το κάνεις :)

έγραψε:
Spoiler: show
Off topic:
Δεν μπόρεσα να κρατηθώ. :lol:

:lol:
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 13 Απρ 2012, 02:37

Μια απορία.

Έστω ότι έχω την function insert() της άσκησης που συζητάμε, η οποία αναλαμβάνει να προσθέσει έναν κόμβο σε μία linked list.
Η συνάρτηση έχει return type bool. Επιστρέφει true αν ο κόμβος προστεθεί επιτυχώς, αλλιώς false.
Μέσα στην συνάρτηση επίσης γίνεται χρήση της malloc() η οποία υπάρχει περίπτωση να αποτύχει.
Σε εκείνο το σημείο η συνάρτηση πρέπει να επιστρέφει μια τιμή, αλλά θέλω αυτή η τιμή να είναι ξεχωριστή για να δηλώνει ότι επέστρεψε λόγω αποτυχίας της malloc().
Άρα όχι false.

Είναι εντάξει να χρησιμοποιήσω σαν τιμή επιστροφής το NULL macro παρ' όλα που η τιμή επιστροφής της συνάρτησης έχει δηλωθεί bool;
Αν όχι τι εναλλακτικές υπάρχουν;

Edit: Σίγουρα υπάρχει πρόβλημα γιατί η σύγκριση NULL == 0 δίνει 1.
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 13 Απρ 2012, 09:49

Ναι, δεν γίνεται... άλλαξε τον τύπο επιστροφής της insert() από bool σε int, και γύριζε διαφορετική τιμή για κάθε λάθος (συνήθως αρνητικές τιμές).
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 13 Απρ 2012, 14:18

Έγραψα το πρόγραμμα, αλλά τελικά αποφάσισα να μην το κουράσω πολύ πολύ.
Έμεινα σ' αυτό το post: viewtopic.php?p=239277#p239277
Μόλις τελειώσω την ύλη (δεν αργώ) θα επικεντρωθώ σε κάποιο πιο ουσιαστικό και ενδιαφέρον project. :)

Ο κώδικας: https://github.com/Ilias95/C-Exercises/ ... nal/hunt.c
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 14 Απρ 2012, 12:12

:)

ΥΓ. Παρεμπιπτόντως, η υλοποίηση εσωτερικής γραμμής εντολών είναι εντός (μέχρι τώρα) ύλης και πολύ ενδιαφέρουσα αν την κάνεις με λέξεις (εννοώ όχι με ένα γράμμα μόνο)... είναι επίσης πολύ χρήσιμη.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 14 Απρ 2012, 12:39

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

Σκέφτομαι τώρα να ξεκινήσω κάποιο πιο μεγάλο project, αλλά δεν μου έρχεται κάποια καλή ιδέα. :problem:
Πχ. όταν ξεκίνησα να μαθαίνω python υλοποίησα ένα address book, και ένα παιχνίδι με χαρτιά.

Καμιά όμορφη ιδέα για κάποιο project παρόμοιου ή μεγαλύτερου μεγέθους;


migf1 έγραψε:ΥΓ. Παρεμπιπτόντως, η υλοποίηση εσωτερικής γραμμής εντολών είναι εντός (μέχρι τώρα) ύλης και πολύ ενδιαφέρουσα αν την κάνεις με λέξεις (εννοώ όχι με ένα γράμμα μόνο)... είναι επίσης πολύ χρήσιμη.

Θα το αφήσω για αργότερα αυτό.
Μπορεί να πάει και ένα βήμα παρακάτω μάλιστα και να γίνει interpreter, αλλά είναι σίγουρα πολύ πιο δύσκολο. :)
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 14 Απρ 2012, 14:34

Ωραίος!

Προφανώς, χρειάζεται πλέον να τριφτείς γράφοντας κώδικα. Μιλάμε πάντα για κονσόλα, γιατί για GUI θα πρέπει να ξαναδιαβάσεις πάλι (την τεκμηρίωση του εκάστοτε API). Το βιβλίο καλύπτει μονάχα τα βασικά της γλώσσας και των στάνταρ βιβλιοθηκών της.

Μια ιδέα είναι να ξαναφτιάξεις το address-book και το παιχνίδι με τα χαρτιά, σε C. Καλύτερα το παιχνίδι με τα χαρτιά (ή κάποιο άλλο, αν βαριέσαι το ίδιο), γιατί console-based address-book δεν νομίζω να το χρησιμοποιήσει κανείς :lol: (εκτός αν θες να το κάνεις απλώς για να δυναμώσεις το προγραμματιστικό σου υπόβαθρο σε C).

Το βασικό τώρα κατά την άποψή μου είναι να τριφτείς στη χρήση των struct/enum/πινάκων (προφανώς σε συνδυασμό με τη χρήση δεικτών & δυναμικής διαχείρισης μνήμης, αλλά όχι απαραίτητα από το 1ο κιόλας project).

Θα μπορούσες για παράδειγμα να αναβαθμίσεις το Hunt ώστε να είναι αλληλοεπιδραστικό. Δηλαδή ας πούμε να εμπλουτίσεις/ζωντανέψεις την σκηνή στην οποία εξελίσσεται η δράση, βάζοντας για παράδειγμα "διάθεση" (mood) στο κάθε ζώο... π.χ. επιθετικό, φοβισμένο, ουδέτερο. Αν είναι επιθετικό θα μπορεί να επιτίθεται στον παίκτη μέσα σε 1-2 κινήσεις αν δεν το έχει πυροβολήσει. Αν είναι φοβισμένο να φεύγει από την σκηνή μετά από 1-2 κινήσεις (οπότε ο παίκτης θα χάνει την ευκαιρία να το συλλάβει).

Μπορείς να σκεφτείς 1002 ακόμα πράγματα για να εμπλουτίσεις το Hunt. Προσθήκη αντικειμένων που θα μπορεί να μαζέψει για να χρησιμοποιήσει ο παίκτης, όπως το χρυσάφι που σκέφτηκες, ή ας πούμε διάφορα είδη όπλων διαφορετικής δυναμικής/εμβέλειας κλπ... ας πούμε: σφεντόνα, ακόντιο, δίκανο, καραμπίνα.

Θα μπορούσες επίσης να προσθέσεις health στον παίκτη, που θα του την "τρώνε" ζώα που θα του επιτίθενται (πάνω σε αυτό θα μπορούσες να προσθέσεις και "attacking power" στο κάθε ζώο, ώστε το καθένα να προκαλεί διαφορετικού μεγέθους ζημιά).

Και... και... και... η λίστα είναι ατέλειωτη!

Αν αποφασίσεις να ασχοληθείς με κάτι σαν το παραπάνω, θα "αναγκαστείς" να μάθεις πως μπορείς να κάνεις Object Oriented προγραμματισμό με C. Εννοώ περισσότερο ως οργάνωση του κώδικα, σε αρχεία, δομές, κλπ, και όχι στο να προσπαθήσεις να μιμηθείς επακριβώς τις υλοποιήσεις κλάσεων, πολυμορφισμού, κληρονομικότητας, κλπ των OOP γλωσσών (κάτι τέτοιο προϋποθέτει εμπειρία που αυτή τη στιγμή σου λείπει).

Θα σου δώσω ένα απλό παράδειγμα, για να καταλάβεις περίπου τι εννοώ. Ας πούμε ότι για κάθε ζώο θέλεις να υπάρχουν γενικά χαρακτηριστικά που θα ισχύουν πάντα (typeid, name, description, attacking power) καθώς και χαρακτηριστικά που θα μεταβάλλονται ανά σκηνή (health, mood, distance from player).

Μπορείς λοιπόν να έχεις το βασικό struct όλων σου των ζώων (την base-class σύμφωνα με την OOP ορολογία) AnimalType ...

Μορφοποιημένος Κώδικας: Επιλογή όλων
/* */
enum AniTypeId {
ATID_INVALID = -1,
ATID_BEAR,
ATID_DEER,
ATID_DUCK,
ATID_FERRET,
ATID_FOX,
ATID_RABBIT,
ATID_RACOON,
ATID_WLDBOAR,
ATID_WOLF,
MAX_ANIMALTYPES
};

/** Base class for all animals **/
typedef struct AnimalType {
enum AniTypeId id;
char *name;
int attpower; /* 50 to 100 */
char *desc;
}AnimalType;


Κατόπιν μπορείς να φτιάξεις μια άλλη δομή, SceneAnimal που θα "κληρονομεί" τα γενικά χαρακτηριστικά της AnimalType και θα προσθέτει τα πιο εξειδικευμένα για την (εκάστοτε) σκηνή...

Μορφοποιημένος Κώδικας: Επιλογή όλων
typedef enum ScenAniMood { SAM_SCARED = -1, SAM_NEUTRAL, SAM_AGGRESSIVE } ScenAniMood ;

/** extends AnimalType class **/
typedef struct SceneAnimal {
AnimalType type; /* general characteristics of a SceneAnimal (inhereted from AnimalType) */
int id; /* for identification in the scene */
ScenAniMood mood;
int health; /* 0 to 100 */
int dist; /* distance from player */
} SceneAnimal;


Κατόπιν η δομή της (εκάστοτε) σκηνής...

Μορφοποιημένος Κώδικας: Επιλογή όλων
typedef struct Scene {
int nanimals; /* number of animals in scene */
SceneAnimal *animals; /* will be allocated dynamically to nanimals * sizeof(SceneAnimal) */
} Scene;


Στην main() θα αρχικοποιείς έναν πίνακα με όλους του τύπους ζώων, και θα ορίζεις και μια μεταβλητή για την σκηνή,
π.χ...

Μορφοποιημένος Κώδικας: Επιλογή όλων
#define MAX_SCENE_ANIMALS	4

int main( void )
{
AnimalType attable[ MAX_ANIMALTYPES ] = {
/* .id .name .attpower .desc */
{ ATID_BEAR, "bear", 100, "a general bear description goes here" },
{ ATID_DEER, "deer", 75, "a general deer description goes here"},
{ ATID_DUCK, "duck", 50, "a general duck description goes here" },
{ ATID_FERRET, "ferret", 55, "a general ferret description goes here" },
{ ATID_FOX, "fox", 60, "a general fox description goes here" },
...
{ ATID_WOLF, "wolf", 90, "a general wolf description goes here" }
};

Scene scene = {0, NULL};
...


Στη ρουτίνα που θα χτίζει την σκηνή όταν ξεκινάει το game, θα περνάς by-reference την μεταβλητή scene. Μέσα στη ρουτίνα θα παράγεις τυχαία έναν αριθμό από 0 έως MAX_SCENE_ANIMALS για το: scene->nanimals και θα δεσμεύεις χώρο για τόσα ζώα στη σκηνή.

Μορφοποιημένος Κώδικας: Επιλογή όλων
scene->nanimals = rand() % MAX_SCENE_ANIMALS;
scene->animals = calloc( scene->nanimals, sizeof(SceneAnimal) );
/* chack for calloc) failure here */


Κατόπιν, στην ρουτίνα που θα βάζει αρχικές τιμές στο κάθε ζώο της σκηνής, θα ξεκινάς παράγοντας έναν τυχαίο αριθμό από 0 έως MAX_ANIMAL_TYPES για το πεδίο: type του κάθε SceneAnimal, και θα αντιγράφεις μέσα του τα γενικά χαρακτηριστικά του τύπου, κάνοντας indexing με τον τυχαίο που παρήγαγες τον πίνακα των τύπων... θα αντιγράφεις δηλαδή τα γενικά χαρακτηριστικά του ζώου από τον πίνακα των τύπων. Μετά θα βάζεις τιμές και στα υπόλοιπα, εξειδικευμένα για την σκηνή, χαρακτηριστικά (πεδία).

Μορφοποιημένος Κώδικας: Επιλογή όλων
AniTypeId temp = ATID_INVALID;

for (int i=0; i < scene->nanimals; i++) {
temp = rand() % MAX_ANIMAL_TYPES;
memcpy( &scene->animals[i].type, &attable[temp], sizeof(AnimalType) );
/* init remaining fields of scene->animals[i] here */
}


Αν είσαι αρκετά ορεξάτος, μπορείς προφανώς να έχεις map από σκηνές ( έναν μικρό κόσμο δηλαδή, π.χ. έναν πίνακα από scenes) τις οποίες είτε θα τις αρχικοποιέις εξαρχής, ή μια-μια όταν την επισκέπτεται για 1η φορά ο παίκτης.

Αν αποφασίσεις να ασχοληθείς, μη κάνεις κόσμο γιατί θα χάσεις την μπάλα τελείως (επειδή αυτό προϋποθέτει και κίνηση σε κατευθύνσεις του ορίζοντα). Φτιάξε μια μόνο σκηνή, εμπλούτισέ την αν θες και με άλλα στοιχεία (π.χ. όπλα, λεφτά, κλπ) δίνε στον παίκτη έναν fixed αριθμό κινήσεων και μετά αντί για νέα σκηνή, κάνε randomize τα περιεχόμενα της ίδιας σκηνής (στο παραπάνω παράδειγμα, νέο πλήθος και είδος ζώων).

ΥΓ. Όλα τα παραπάνω τα προτείνω για να εντρυφήσεις στο C programming (και στο programming γενικότερα). Για τη δημιουργία adventures (text ή μη) υπάρχουν εξειδικευμένα Rapid Development Tools ή/και Γλώσσες (Π.χ. TADS3, Inform7, κλπ)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 14 Απρ 2012, 15:01

Με έψησες πάρα πολύ άσχημα! :)
Ακούγεται δελεαστικότατο...

Ξεκινάω αμέσως το σχεδιασμό του παιχνιδιού (όχι του κώδικα) στο μυαλό μου.
Μετά αφού αποφασίσω τι ακριβώς θα κάνω, θα ξεκινήσω τον σχεδιασμό και την οργάνωση του κώδικα.
Εδώ πιθανώς θα χρειαστώ κάποια βοήθεια γιατί δεν έχω ξανακάνει κάτι τέτοιο και δη σε C και πρέπει να γίνει απ' την αρχή σωστά.

Ευχαριστώ πολύ! :clap:
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 14 Απρ 2012, 15:52

Ilias95 έγραψε:Με έψησες πάρα πολύ άσχημα! :)
Ακούγεται δελεαστικότατο...

Ξεκινάω αμέσως το σχεδιασμό του παιχνιδιού (όχι του κώδικα) στο μυαλό μου.
Μετά αφού αποφασίσω τι ακριβώς θα κάνω, θα ξεκινήσω τον σχεδιασμό και την οργάνωση του κώδικα.
Εδώ πιθανώς θα χρειαστώ κάποια βοήθεια γιατί δεν έχω ξανακάνει κάτι τέτοιο και δη σε C και πρέπει να γίνει απ' την αρχή σωστά.

Ευχαριστώ πολύ! :clap:

Αρχηγέ μου, δεν περίμενα πως θα τ αποφάσιζες... respect! :)

Κοίτα, επειδή δεν είναι εύκολο πράγμα, ξεκίνα το απλά. Δηλαδή, σκέψου και φτιάξε τις δομές σωστά, κλπ αλλά μην τις γεμίσεις πολλά πεδία (άρα και συμπεριφορές) για να εστιάζεις αρχικά στην οργάνωση (δομές, συναρτήσεις, ακόμα και πηγαία αρχεία).

Θα σου πρότεινα για αρχή η σκηνή να έχει μόνο ζώα και τίποτα άλλο. Στα SceneAnimals βάλε αρχικά μόνο type, id & health (το οποίο το έχεις έτσι κι αλλιώς υλοποιήσει με τ αστεράκια, οπότε απλώς θα το προσαρμόσεις). Βάλε τους επίσης και mood, αλλά μη τα κάνεις ακόμα να επιτίθενται... υλοποίησε μονάχα τα SCARED & NΕUTRAL, γιατί άμα βάλεις και AGGRESSIVE θα πρέπει να βάλεις και health και στον παίκτη, και αρχίζει να μπλέκει το πράγμα... btw, θα χρειαστείς έτσι κι αλλιώς και δομή Player (π.χ. με πεδία name, score και capedanimals (τα ζώα που έχει συλλάβει σε κάθε σκηνή) ).

Κράτα το σε αυτά αρχικά, κι εστίασε στο interface που θα φτιάξεις για τις δομές σου, δηλαδή τις συναρτήσεις που θα λειτουργούν πάνω στην κάθε δομή.

Για παράδειγμα το interface της δομής Scene θα μπορούσε να περιέχει τις συναρτήσεις...

Μορφοποιημένος Κώδικας: Επιλογή όλων
scene_build();
scene_cleanup();

και το interface της δομής SceneAnimal να περιέχει τις συναρτήσεις...

Μορφοποιημένος Κώδικας: Επιλογή όλων
sceneAnimal_add();
sceneAnimal_delete();
...

τις οποίες μπορεί να τις χρησιμοποιούν οι συναρτήσεις του interface της δομής Scene. Οι 2ες λέμε πως βρίσκονται σε χαμηλότερο (νοηματικό) layers από τις πρώτες. Ανάλογα πως και με πόσες συναρτήσεις θα υλοποιήσεις τα interfaces των δομών σου (δεν είναι απαραίτητο να το κάνεις για όλες τις δομές) ίσως αποφασίσεις ότι σε εξυπηρετεί ένα interface με πολλές συναρτήσεις να το βάλεις σε ξεχωριστό αρχείο .c (ενδεχομένως με αντίστοιχο header file).

Η διαδικασία από αυτή είναι παραπάνω από ικανή να σε πονοκεφαλιάσει για αρκετές μέρες, οπότε δεν χρειάζεται να έχεις και πολύπλοκες δομές εξαρχής ;) Αν τα οργανώσεις σωστά και όμορφα, θα σου είναι εύκολο μετά να προσθέτεις πεδία στις δομές και απλά να ενημερώνεις τις συναρτήσεις που ασχολούνται με τη συγκεκριμένη δομή (η/και να προσθέτεις κι άλλες για το νέο πεδίο στο interface της δομής).

Πάντως δεν χρειάζεται να το παρακάνεις και με την οργάνωση και τον διαχωρισμό σε δομές/συναρτήσεις/αρχεία γιατί από ένα σημείο και μετά αντί να βοηθάει, σε μπερδεύει περισσότερο.

Π.χ. το παράδειγμα που έδωσα παραπάνω με τα interfaces των δομών Scene και SceneAnimal, μπορεί να γίνει σε ένα επίπεδο, μόνο για την Scene (με τον κώδικα των συναρτήσεων build & cleanup να περιέχουν απευθείας τον κώδικα των add και delete)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι