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

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

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

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

Δημοσίευσηαπό pc_magas » 14 Απρ 2012, 19:07

Καλό είναι να κάνεις UML διάγραμμα ροής με σενάρια και κανά UML καταστάσεων
My blog|Κυπριακή Κοινότητα Ελευθέρου Λογισμικού Λογισμικού ανοικτού Κώδικα
Γνώσεις Linux:Ποτέ αρκετές|Προγραμματισμός: Php, javascript, nodejs, python, bash |Aγγλικά:Καλά
Οι υπολογιστές μου:
Spoiler: show
Ubuntu 16.04 64 bit σεIntel(R) Pentium(R) CPU G4400 @ 3.30GHz, 16Gib Ram, 500Gib Hard Disk, και κάρτα γραφικών Nvidia Geforce GT610
Lubuntu 14.04 σε Dell Inspiron mini 10(1010) intel Atom Z500 1Gb ram και gma500 (εδώθη σε άλλον)
Kubuntu 16.04 Lenovo G70 Intel i5 Nvidia Grapgics Card, Intel Graphics card (έχει 2) με Nouveau, 16Gb RAM, 126GB SSD Σκληρό Δίσκο
Άβαταρ μέλους
pc_magas
powerTUX
powerTUX
 
Δημοσιεύσεις: 2599
Εγγραφή: 12 Απρ 2009, 18:55
Τοποθεσία: Αχαρναί Αττικής
Launchpad: pc_magas
IRC: pc_magas
Εκτύπωση

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

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

pc_magas έγραψε:Καλό είναι να κάνεις UML διάγραμμα ροής με σενάρια και κανά UML καταστάσεων

Θα κάνω διαγράμματα ροής, αλλά... στο χαρτί.
Δεν σκοπεύω να μάθω UML προς το παρών.

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

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

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

Έχεις παίξει ποτέ text-adventure, Ηλία (εννοώ για να δεις περίπου πως πάει το πράγμα );

Θα χρειαστείς πάντως εσωτερική γραμμή εντολών, οπότε θα έλεγα να ξεκινήσεις από αυτήν ;)
Ξεκίνα με 5-6 εντολές, π.χ.

Κώδικας: Επιλογή όλων
look, shoot, help, exit

Κάποιες από αυτές θα μπορούν να δέχονται 0 ή περισσότερες παραμέτρους.

Για παράδειγμα, σκέτη look χωρίς παραμέτρους θα βγάζει μια γενική περιγραφή της σκηνής, π.χ. πληροφορίες για τα υπάρχοντα ζώα...
Κώδικας: Επιλογή όλων
4 animals | 0:wolf, 1:racoon, 2:rabbit, 3:duck

H look wolf θα δίνει έξτρα πληροφορίες για το ζώο που δόθηκε...
Κώδικας: Επιλογή όλων
0:Wolf (health=100, distance=200 meters, mood=neutral )

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

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

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

migf1 έγραψε:Έχεις παίξει ποτέ text-adventure, Ηλία (εννοώ για να δεις περίπου πως πάει το πράγμα );

Όχι, ποτέ. Αν έχεις κανένα παράδειγμα πρόχειρο πες μου. Αλλά δεν νομίζω ότι είναι απαραίτητο.
Ναι, θα υλοποιήσω και μία (mini) γραμμή εντολών.

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

ΥΓ. Χάρη, πολύ ωραία η ιδέα σου! :D
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

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

Ξεκίνα με την υλοποίηση της εσωτερικής γραμμής εντολών, που θέλει δουλιτσα. Έναν parser που θα σκανάρει την εσωτερική γραμμή εντολών, θα ξεχωρίζει τις εντολές από τις παραμέτρους και θα τις αποθηκεύει με κάποιον δομημένο τρόπο, για να μπορέσει κατόπιν να τις εφαρμόσει.

Μπορείς ξανά να έχεις στην main() αρχικοποιημένο έναν πίνακα με όλες τις εντολές που θες να αναγνωρίζεις, μαζί με έξτρα πληροφορίες.

Ας πούμε για παράδειγμα πως θέλεις οι εντολές να έχουν και aliases (συνώνυμα), δηλαδή είτε σου γράψει "exit", είτε "quit", είτε "bye", κλπ να το εκλαμβάνεις ως εντολή εξόδου

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

Δες ένα παράδειγμα κώδικα που χρησιμοποιεί πάνω κάτω την ίδια προσέγγιση με το AnimalTypes...

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

enum ComTypeId {
CMDID_INVALID = -1,
CMDID_EXIT,
CMDID_HELP,
CMDID_LOOK,
CMDID_GO,
CMDID_SHOOT,
CMDID_GET,
CMDID_DROP,
MAX_COMMANDS
};

typedef struct CommandType {
enum ComTypeId id;
char *aliases[ MAX_CMD_ALIASES ]; /* array of char ptrs (μπορείς να το κάνεις στατικό πίνακα αν σε βολεύει καλύτερα) */
int nparams; /* */
char *params[ MAX_CMD_PARAMS ]; /* array of char ptrs (κι αυτό μπορείς να το κάνεις στατικό πίνακα) */
} CommandType;

...
int main( void )
{
CommandType cmdtable[ MAX_COMMANDS ] = {
/* .id .aliases .nparams .params */
{ CMDID_EXIT, {"exit", "x", "quit", "q"}, 0, {NULL, NULL} },
{ CMDID_HELP, {"help", "h", "?", NULL}, 0, {NULL, NULL} },
{ CMDID_LOOK, {"look", NULL, NULL, NULL}, 1, {NULL, NULL} },
{ CMDID_GO, {"go", "walk", NULL, NULL}, 0, {NULL, NULL} },
{ CMDID_SHOOT, {"shoot", "hit", NULL, NULL}, 1, {NULL, NULL} },
{ CMDID_GET, {"get", "pick", NULL, NULL}, 1, {NULL, NULL} },
{ CMDID_DROP, {"drop", NULL, NULL, NULL}, 2, {NULL, NULL} }
};

CommandType command = { CMDID_INVALID, {NULL, NULL, NULL, NULL}, 0, {NULL, NULL} };
...

Στην συνάρτηση του parser, θα περνάς π.χ. την stdin που σου έγραψε ο χρήστης, καθώς επίσης και την μεταβλητή command (by-reference). Θα σπας την stdin σε tokens, και θα ενημερώνεις κατάλληλα την μεταβλητή command.

Δηλαδή, μέσω μιας ακόμα συνάρτησης, ας πούμε...

Μορφοποιημένος Κώδικας: Επιλογή όλων
enum ComTypeId cmdtable_lookup_alias( const CommandType cmdtable[], const char *alias );

θα κοιτάς αν το 1ο token (τριμαρισμένο από κενά διαστήματα & τροποιημένο σε πεζά γράμματα) αντιστοιχεί στις εντολές που αναγνωρίζεις.

Προφανώς το κοίταγμα θα γίνεται πιάνοντας τον πίνακα εντολών από την αρχή του και ψάχνοντας για κάθε εντολή, την λίστα με τα aliases μέχρι να ταιριάξει κάποιο με το 1ο token (που στο παραπάνω πρότυπο είναι το όρισμα alias)
Αν βρεθεί, η συνάρτηση θα σου επιστρέφει...

Μορφοποιημένος Κώδικας: Επιλογή όλων
cmdtable[found].id (όπου found, η τιμή του μετρητή από το loop που σκανάρει τις γραμμές του πίνακα)

αλλιώς θα σου επιστρέφει CMDID_INVALID.

Βρισκόμαστε ακόμα στη συνάρτηση του parser... αν λοιπόν υπάρχει το 1ο token, θα κοπιάρεις μέσα στην command τη αντίστοιχη γραμμή του πίνακα...

Μορφοποιημένος Κώδικας: Επιλογή όλων
parser( char *input, Command *command )
{
...
ComTypeId try = cmdtable_lookup_alias( cmdtable, token1st );
if ( CMDID_INVALID != try )
memcpy( command, &cmdtable[ try ], sizeof(Command) );
...
}

Κατόπιν, με έγκυρο πλέον command , θα κοιτάς πόσες παραμέτρους περιμένει max, ώστε όσες έχουν δοθεί να τις περάσεις στο πεδίοparams της command.

Μορφοποιημένος Κώδικας: Επιλογή όλων
...
for (int i=0; i < command->nparams && more_stuff_in_stdin; i++ )
strncpy( command->params[ i ], next_token_from_stdin, MAXLEN_PARAM];
...

Με λίγα λόγια, όταν θα τελειώσει η parser() θα έχει βάλει μέσα στην μεταβλητή command το id της δοθείσας εντολής, καθώς και τις παραμέτρους που δόθηκαν (αν δόθηκαν... όσες δεν δόθηκαν μπορείς να τις έχεις ως NULL στο command.nparams.

Από εδώ και πέρα, μπορείς να χρησιμοποιήσεις την μεταβλητή command σε ξεχωριστές συναρτήσεις για τη διαχείριση της κάθε εντολή σου.

Για παράδειγμα...

Μορφοποιημένος Κώδικας: Επιλογή όλων
...
get_input( input );
parse_input( input, cmdtable, &command);

switch ( command.id )
{
case CMDID_LOOK:
do_cmd_lookup( command );
break;

case CMDID_HELP:
do_cmd_help( command );
break;
...
}

Μπορείς στον πίνακα των εντολών, να προσθέσεις άλλο ένα πεδίο που θα είναι δείκτης σε συνάρτηση, για κάθε εντολή δηλαδή θα έχεις μέσα στο struct της έναν δείκτη στη συνάρτηση που διαχειρίζεται την εντολή σου. Oπότε μόλις τελειώσει η parser() θα κάνεις μονάχα έναν έλεγχο να μην είναι command.id == CMDID_INVALID, κι όταν δεν είναι θα καλείς την συνάρτηση μέσα από την command...

Μορφοποιημένος Κώδικας: Επιλογή όλων
...
get_input( input );
parse_input( input, cmdtable, &command);

if ( CMDID_INVALID == command.id )
/* handle error here */
else
command.funcptr( command );

Αυτό προϋποθέτει όμως πως ΟΛΕΣ οι συναρτήσεις διαχείρισης εντολών παίρνουν ίδιο πλήθος & τύπο ορισμάτων, καθώς και ότι επιστρέφουν ίδιο τύπο. Κάτι που στο παραπάνω παράδειγμα ισχύει (επειδή το έκανα να ισχύει :lol: ).

Άρα...

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

typedef struct CommandType {
enum ComTypeId id;
char *aliases[ MAX_CMD_ALIASES ]; /* array of char ptrs (μπορείς να το κάνεις στατικό πίνακα αν σε βολεύει καλύτερα) */
int nparams; /* */
char *params[ MAX_CMD_PARAMS ]; /* array of char ptrs (κι αυτό μπορείς να το κάνεις στατικό πίνακα) */
void (*funcptr)( struct CommandType command );
} CommandType;
...
int main( void )
{
CommandType cmdtable[ MAX_COMMANDS ] = {
/* .id .aliases .nparams .params */
{ CMDID_EXIT, {"exit", "x", "quit", "q"}, 0, {NULL, NULL}, &do_exit },
{ CMDID_HELP, {"help", "h", "?", NULL}, 0, {NULL, NULL} &do_help },
{ CMDID_LOOK, {"look", NULL, NULL, NULL}, 1, {NULL, NULL}, &do_look },
{ CMDID_GO, {"go", "walk", NULL, NULL}, 0, {NULL, NULL}, &do_go },
{ CMDID_SHOOT, {"shoot", "hit", NULL, NULL}, 1, {NULL, NULL}, &do_shoot },
{ CMDID_GET, {"get", "pick", NULL, NULL}, 1, {NULL, NULL}, &do_get },
{ CMDID_DROP, {"drop", NULL, NULL, NULL}, 2, {NULL, NULL}, &do_drop }
};

CommandType command = { CMDID_INVALID, {NULL, NULL, NULL, NULL}, 0, {NULL, NULL}, NULL };
...

Και προφανώς τις συναρτήσεις void do_xxx( Command comamnd ) υλοποιημένες και γνωστοποιημένα τα πρότυπά τους πριν την αρχικοποίηση του πίνακα ;)
Τελευταία επεξεργασία από migf1 και 14 Απρ 2012, 22:07, έχει επεξεργασθεί 7 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

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

Διόρθωσα λίγο τα παραδείγματα με τα function pointers. Έβαλα την parse() να κάνει memcpy() στην command τη έγκυρη γραμμή του πίνακα, οπότε μετά την parse() δεν χρειάζεται να ξανακάνουμε index τον πίνακα, καλούμε απευθείας τη συνάρτηση μέσα από την μεταβλητή command...

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

Νομίζω δεν έχει πρόβλημα να καλέσει τη συνάρτηση με όρισμα τον εαυτό της (θα πρέπει να το τσεκάρω όμως).

Αλλιώς, όπως πριν...
Μορφοποιημένος Κώδικας: Επιλογή όλων
cmdtable[ command.id ].funcptr( command );
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

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

Λοιπόν παραθέτω ότι έχω σκεφτεί μέχρι τώρα σε μορφή σημειώσεων:
Spoiler: show
Ο παίκτης αρχικά θα έχει ένα μενού 4 επιλογών: Go to jungle, go to store, info, quit

Οι κύριες δομές:

User
------------
health:
xp: # εμπειρία
gold:
weapons: μέχρι 5 # λίστα με όπλα
bullets:
capedanimals: # λίστα από ζώα που αιχμαλώτισε

Animal
-----------
health:
attack:
mood: aggresive, neutral ή scared
value_money: # η τιμή πώλησης του ζώου
value_xp: # η xp που θα πάρει ο χρήστης αν αιχμαλωτίσει το ζώο
distance from player: 0 - 100 m

Weapon (5 διαφορετικά)
-----------------------
value: # πόσο κοστίζει η αγορά του
attack:
distance: # η απόσταση μέχρι την οποία μπορεί να πυροβολήσει


JUNGLE - SCENE
----------------------------
Κάθε φορά ο που ο παίκτης θέλει να μπει στην ζούγκλα πρέπει να πληρώσει ένα ποσό.
Επίσης πριν μπει ο παίκτης πρέπει να αποφασίσει ένα όπλο θα πάρει μαζί του.

Η σκηνή έχει 5 τυχαία ζώα (μπορεί κάποιο ζώο δύο ή παραπάνω φορές).
Τυχαία για κάθε ζώο θα ορίζεται και η διάθεση, απόσταση απ' τον παίχτη.
Τα στατιστικά του κάθε ζώου είναι κρυφά απ' τον παίκτη αρχικά.

Ο παίκτης μπορεί να παραμείνει στη σκηνή μέχρι 15 γύρους.
Σε κάθε γύρο κάνει μία κίνηση ο παίκτης και μία το ΚΑΘΕ ζώο.

Όσο ο παίκτης βρίσκεται στην ζούγκλα θα χρησιμοποιεί μια εσωτερική γραμμή εντολών με τις παρακάτω διαθέσιμες εντολές:
shoot, capture, look, help, leave


Σε κάθε γύρο ο παίκτης μπορεί να:

-χτυπήσει ζώο (με την εντολή shoot)
-αιχμαλωτίσει ζώο (με την εντολή capture)
-δει τα χαρακτηριστικά όλων των ζώων (με την εντολή look)
-αποχωρήσει απ' την ζούγκλα (με την εντολή leave)

Η ζημιά που μπορεί να πάθει ένα ζώο θα εξαρτάται από την απόσταση που βρίσκεται από τον παίκτη, και απ' τα χαρακτηριστικά του weapon (attack, distance).
Αν ο χρήστης επιλέξει να αιχμαλωτίσει ένα ζώο τότε εφόσον το ζώο έχει κάτω από x health τότε μπορεί, αλλιώς το ζώο θα του επιτεθεί (χωρίς να μετράει σαν γύρος για το ζώο).


Σε κάθε γύρο κάθε ζώο μπορεί να:

-επιτεθεί στον παίκτη
-πλησιάσει ή απομακρυνθεί απ' τον παίκτη

Η κίνηση του ζώου εξαρτάται από τη διάθεση του και απ' την... τύχη!
Ένα ζώο μπορεί να χτυπήσει μόνο όταν βρίσκεται σε κοντινή απόσταση.
Αν ένα ζώο απομακρυνθεί αρκετά απ' τον παίκτη μπορεί να βγει εντελώς απ' τη σκηνή.
Η ζημιά που μπορεί να προκαλέσει ένα ζώο εξαρτάται απ' το attack του, την υγεία του, την xp του παίκτη και την απόσταση απ' τον παίκτη.

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


STORE
---------------

Ο παίκτης μπορεί να αγοράσει:

-Φάρμακα: Κάθε μπουκαλάκι ανεβάζει την ζωή κατά 10, και κοστίζει 50. # ενδεικτικές τιμές
-Όπλα

Ο παίκτης μπορεί να πουλήσει:

-Ζώα
-Όπλα

Τα όπλα πωλούνται στην μισή τιμή απ' αυτήν που αγοράστηκαν.


INFO
---------------
Πέρα από πληροφορίες για το πως παίζεται το παιχνίδι ο παίκτης θα μπορεί να δει πόσα και τι ζώα έχει αιχμαλωτίσει απ' την αρχή του παιχνιδιού.

Πιο συγκεκριμένα πράγματα θα τα αποφασίσω αργότερα, αλλά πλέον έχω κάτι για να κινηθώ.

Την εσωτερική γραμμή εντολών λέω να την αφήσω για αργότερα.
Θα τεστάρω αρχικά το πρόγραμμα απλά καλώντας τις συναρτήσεις χειροκίνητα.

Ζόρικο το project για αρχάριο και ειδικά σε C.
Θα πάρει κάποιο καιρό αλλά αξίζει πιστεύω. :)
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

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

Ζόρικο ναι (αλλά εντός ύλης ;) )

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

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

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

migf1 έγραψε:Νομίζω έχεις βάλει πάρα πολλά πράγματα για αρχή! Αλλά μιλάμε για πάααρα πολλά :lol:

Indeed.
Αλλά αν βγάλω κάτι, αναγκαστικά πρέπει να βγάλω και κάτι άλλο και τελικά μου φαίνεται... πολύ απλό. :lol: :lol: :lol:

Δεν με πιέζει ο χρόνος ή κάτι άλλο όμως και αφού σκοπός είναι να μάθω I' ll go for it...

ΥΓ. Καλή Ανάσταση!
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

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

Αν θες να κάνει ένα break, γράψε στο γκούγκλ "text adventures" ή "interactive fiction" και θα βρεις πολλά (είτε για κατέβασμα είτε online).

Π.χ. αυτά εδώ είναι online: http://www.ifiction.org/games/index.php?cat=44
(το: Mission Impossible ακούγεται ενδιαφέρον)

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

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

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