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

Παιχνίδι 2048 σε C


johnny.tifosi

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

Βασικά έκανα edit γιατί τα είχα λίγο μαντάρα (ανέβασα και νέο zip).

 

Που λες, λέγοντας ui abstraction εγώ εννοούσα αυτό που έγραφα σε προηγούμενο ποστ. Δηλαδή abstract event-queue, abstract event-messaging, abstract widgets, κλπ... ζήσε Μάη μου να φας τριφύλλι δηλαδή :P

 

EDIT:

 

Πάντως κι αυτό εδώ νομίζω έχει ρεαλιστικό potential.

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

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

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

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

Δημοσιευμένες Εικόνες

Α, εσύ το πήγες λίγο πιο μακριά...

Η αλήθεια είναι ότι εγώ είχα στο νου μου κάτι πιο απλό. Το οποίο βέβαια επίσης χρειάζεται το ανάλογο decoupling.

 

 

Πάντως κι αυτό εδώ νομίζω έχει ρεαλιστικό potential.

 

Δεν ξέρω αν το διαβάζω σωστά, αλλά εκεί μου φαίνεται ότι η engine οδηγεί το ui, κι όχι το αντίστροφο. Είναι "σωστό" αυτό;

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

Α, εσύ το πήγες λίγο πιο μακριά...

Η αλήθεια είναι ότι εγώ είχα στο νου μου κάτι πιο απλό. Το οποίο βέβαια επίσης χρειάζεται το ανάλογο decoupling.

 

Δεν ξέρω αν το διαβάζω σωστά, αλλά εκεί μου φαίνεται ότι η engine οδηγεί το ui, κι όχι το αντίστροφο. Είναι "σωστό" αυτό;

Ε, αυτό είναι το βασικό δίλημμα. Δεν νομίζω όμως πως υπάρχει σωστό και λάθος, γιατί στη γενική περίπτωση υπάρχει αλληλο-επίδραση. Ας πούμε για παράδειγμα πως θέλουμε να δείξουμε στον χρήστη ένα dilaog με τα settings του παιχνιδιού, τα οποία μπορεί να τα αλλάξει.

 

Ο manager πρέπει να πάρει από το engine τα τρέχοντα settings, και να τα στείλει στο ui. Το ui θα τα εμφανίσει στον user, μετά θα διαβάσει τις νέες τιμές των settings που θα βάλει ο user, τις οποίες θα πρέπει κατόπιν να τις περάσει πίσω στο manager. Κι ο manager με τη σειρά του να τις περάσει πίσω στο engine.

 

Οπότε ποιος οδηγεί ποιον? :)

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

Δεν νομίζω ότι υπάρχει αλληλεπίδραση, με τη "διαλογική" έννοια. Ο ένας έχει την πρωτοβουλία, και ο άλλος "εξυπηρετεί" (serves). Νομίζω ότι την πρωτοβουλία έχει το ui, το οποίο αλληλεπιδρά με τη σειρά του με τον χρήστη. Η engine απλά κάθεται εκεί και περιμένει εντολές, οι οποίες έχουν σκοπό τη διαχείριση του state της.

 

( Το "τρίτο πρόσωπο" εδώ είναι ο manager, ο οποίος δεν ξέρω ακριβώς τι δουλειά κάνει. Μπορώ να υποθέσω ότι προέκυψε ακριβώς από την ανάγκη αυτής της αλληλεπίδρασης; )

 

Παλιότερα έφτιαχνα plugins για το winamp. Εκεί λοιπόν υπήρχε το ui, --> το οποίο "οδηγούσε" μία plugin engine --> η οποία με τη σειρά της χρησιμοποιούσε plugins για να κάνει τη δουλειά της (να απαντά στις αιτήσεις του ui). Από εκείνη την εποχή έχω "κληρονομήσει" αυτό το μοντέλο, γιατί θεωρώ ότι είναι το πιο "ορθολογικά" δομημένο.

 

Για το παράδειγμά σου, σκέψου ότι, αν θέλουμε να δείξουμε τα settings, αυτό θα γίνει κατά πάσα πιθανότητα μετά από κάποιο interaction του χρήστη με το ui (πχ επιλογή μίας επιλογής menu "Preferences"). Άρα, αν η engine υποστηρίζει κάποια μέθοδο get_settings() και μία άλλη set_settings(), το ui πολύ άνετα μπορεί να εκτελέσει πρώτα τη μία, να δείξει το dialog του, και τέλος να εκτελέσει τη δεύτερη. Κανένας manager δεν παρεμβάλλεται, και το gui "οδηγεί" την engine, με την έννοια ότι αποφασίζει πότε θα γίνει τι (με τους ανάλογους περιορισμούς της engine φυσικά -- αν παίζεις πχ σκάκι, η engine αποφασίζει αν είναι η σειρά των άσπρων ή των μαύρων!)

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

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

 

Όταν ένα object εξωγενές της engine επικοινωνεί μαζί της και με getter και με setter, τότε αυτόματα μιλάμε για αμφίδρομη σχέση και όχι για απλό serving της engine προς το εξωγενές object. Ουσιαστικά δεν έχουμε server εδώ, αλλά αλληλεπιδρώντα objects που επικοινωνούν μεταξύ τους (ιδανικά μέσω κάποιου well-defined messaging protocol... που στη δική μας περίπτωση δεν υπάρχει και δεν ξέρω κιόλας αν αξίζει να επενδυθεί χρόνος και κόπος για να φτιαχτεί).

 

Ο manager στη γενική περίπτωση είναι αυτός που συντονίζει/δρομολογεί τα messages ανάμεσα στα διάφορα objects.

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

Όταν ένα object εξωγενές της engine επικοινωνεί μαζί της και με getter και με setter, τότε αυτόματα μιλάμε για αμφίδρομη σχέση και όχι για απλό serving της engine προς το εξωγενές object. Ουσιαστικά δεν έχουμε server εδώ, αλλά αλληλεπιδρώντα objects που επικοινωνούν μεταξύ τους (ιδανικά μέσω κάποιου well-defined messaging protocol... που στη δική μας περίπτωση δεν υπάρχει και δεν ξέρω κιόλας αν αξίζει να επενδυθεί χρόνος και κόπος για να φτιαχτεί).

 

Μα αυτό χρειάζεται μόνο στην περπίπτωση που και οι δύο οντότητες δημιουργούν (ή προωθούν) events. Εδώ, τα μόνα events που δημιουργούνται είναι από το ui. Εκτός κι αν υπάρχει κάποια άλλη ανάγκη, δεν βλέπω άλλο λόγο για δημιουργία messaging protocol.

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

Μα δεν δημιουργούνται μόνο από το ui οι αλλαγές. Π.χ. το ai-engine δεν θα δημιουργεί αλλαγή στο state του board η οποία θα πρέπει να περαστεί ως redraw event στο ui? Ή το auto-generation των tiles (που μάλιστα στην αρχή είναι 2πλάσιο από τις επόμενες φορές) δεν πρέπει να δημιουργήσει redraw event?

 

Βασικά είμαστε ελεύθεροι να επιλέξουμε ανάμεσα σε διάφορα μοντέλα υλοποίησης. Δεν υπάρχει σωστό και λάθος. Π.χ. κι αυτό που περιγράφεις αποτελεί μια χαρά επιλογή, και ουσιαστικά πατάει κι αυτό πάνω στην αρχή του loose-coupling .

 

Δηλαδή έχουμε ένα ας το πούμε server-client μοντέλο, όπου ο server θα είναι η λογική και ο client το ui. Η λογική (το engine στο παράδειγμά σου) δεν έχει ιδέα για το ui (δεν υπάρχει τίποτα σχετικό με ui στον κώδικά της) αλλά το ui και χτίζεται με γνώμονα τη λογική, και έχει περαιτέρω πρόσβαση στις πληροφορίες της λογικής και μπορεί να κάνει invoke κομμάτια της λογικής (και προφανώς ο κώδικάς του είναι πήχτρα από αναφορές στην υλοποίηση της λογικής).

 

Αυτό που με"χαλάει" (τρόπος του λέγειν) σε αυτή την προσέγγιση είναι πως το game-loop αντί να υλοποιείται από τον manager (controller, ή όπως αλλιώς θέλουμε να τον ονοματίσουμε) υλοποιείται μέσα στο εκάστοτε ui.

 

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

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

Μα δεν δημιουργούνται μόνο από το ui οι αλλαγές. Π.χ. το ai-engine δεν θα δημιουργεί αλλαγή στο state του board η οποία θα πρέπει να περαστεί ως redraw event στο ui?

 

Χμμμμ... Όχι απαραίτητα. Όπως το βλέπω, το AI enngine είναι απλά άλλο ένα "u"i. Ή καλύτερα, υλοποιείται μέσω ενός άλλου ui. Ακόμα κι αν υλοποιείται κεντρικά, σαν ένα άλλο engine, το εκάστοτε ui κάνει τον "μεσάζοντα" μεταξύ των δύο, χρησιμοποιώντας τις ήδη γνωστές του λειτουργίες.

 

Με άλλα λόγια, προσομοιώνει την επικοινωνία με τον παίκτη, μόνο που λαμβάνει εντολές από το ai.

 

Ή το auto-generation των tiles (που μάλιστα στην αρχή είναι 2πλάσιο από τις επόμενες φορές) δεν πρέπει να δημιουργήσει redraw event?

 

Εδώ δεν είμαι σίγουρος σε ποιο πράγμα αναφέρεσαι, αλλά θα το ψάξω στον κώδικα. Σε κάθε περίπτωση, αυτό το auto generation δεν γίνεται μετά από κάποιο event του χρήστη; Ή "ξεκάρφωτα" σε τυχαία χρονική στιγμή;

 

Βασικά είμαστε ελεύθεροι να επιλέξουμε ανάμεσα σε διάφορα μοντέλα υλοποίησης. Δεν υπάρχει σωστό και λάθος. Π.χ. κι αυτό που περιγράφεις αποτελεί μια χαρά επιλογή, και ουσιαστικά πατάει κι αυτό πάνω στην αρχή του loose-coupling .

 

Σε αυτό νομίζω συμφωνούσαμε εξ αρχής.

 

Δηλαδή έχουμε ένα ας το πούμε server-client μοντέλο, όπου ο server θα είναι η λογική και ο client το ui. Η λογική (το engine στο παράδειγμά σου) δεν έχει ιδέα για το ui (δεν υπάρχει τίποτα σχετικό με ui στον κώδικά της) αλλά το ui και χτίζεται με γνώμονα τη λογική, και έχει περαιτέρω πρόσβαση στις πληροφορίες της λογικής και μπορεί να κάνει invoke κομμάτια της λογικής (και προφανώς ο κώδικάς του είναι πήχτρα από αναφορές στην υλοποίηση της λογικής).

 

Κάπως έτσι. Τώρα, για το "πήχτρα", προφανώς δεν θα είναι αναφορές στην υλοποίηση της λογικής, αλλά στα κομμάτια της που το ενδιαφέρουν, αφαιρετικά (πχ στις move_tiles_left() ή get_score(), κι όχι στο πως υλοποιούνται αυτά).

 

Αυτό που με"χαλάει" (τρόπος του λέγειν) σε αυτή την προσέγγιση είναι πως το game-loop αντί να υλοποιείται από τον manager (controller, ή όπως αλλιώς θέλουμε να τον ονοματίσουμε) υλοποιείται μέσα στο εκάστοτε ui.

 

Είναι διότι θεωρείς ότι θα υπάρχει πάντα game loop ;)

Αυτό δεν ισχύει πάντα. Πχ φαντάσου ένα gui, ή ένα δικτυακό interface (για να πλατιάσουμε κι άλλο :D) τα οποία όπως είπες πριν είναι event-driven. Για να μπορείς να υποστηρίξεις όλα αυτά τα πράγματα, δεν σε συμφέρει η loop-προσέγγιση, αλλά περισσότερο μία Finite State Machine, που θα σου καλύψει όλες τις πιθανές περιπτώσεις.

 

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

 

Από διάθεση, έχω ήδη. Από χρόνο... που θα μου πάει;;; :)

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

Χμμμμ... Όχι απαραίτητα. Όπως το βλέπω, το AI enngine είναι απλά άλλο ένα "u"i. Ή καλύτερα, υλοποιείται μέσω ενός άλλου ui. Ακόμα κι αν υλοποιείται κεντρικά, σαν ένα άλλο engine, το εκάστοτε ui κάνει τον "μεσάζοντα" μεταξύ των δύο, χρησιμοποιώντας τις ήδη γνωστές του λειτουργίες.

 

Με άλλα λόγια, προσομοιώνει την επικοινωνία με τον παίκτη, μόνο που λαμβάνει εντολές από το ai.

Ναι, κάνεις embed το game-loop μέσα στο ui.

 

Εδώ δεν είμαι σίγουρος σε ποιο πράγμα αναφέρεσαι, αλλά θα το ψάξω στον κώδικα. Σε κάθε περίπτωση, αυτό το auto generation δεν γίνεται μετά από κάποιο event του χρήστη; Ή "ξεκάρφωτα" σε τυχαία χρονική στιγμή;

Η 1η κίνηση (τα αρχικά auto-generated tiles) γίνονται χωρίς user-interation. Στη συνέχεια γίνονται auto-generate μετά από κάθε κίνηση του παίκτη (αλλά δια 2... δηλαδή π.χ. σε 4χ4 ταμπλό, στην αρχή δημιουργούνται 2 και κατόπιν 1 μετά από κάθε κίνηση).

 

Είναι διότι θεωρείς ότι θα υπάρχει πάντα game loop ;)

Αυτό δεν ισχύει πάντα. Πχ φαντάσου ένα gui, ή ένα δικτυακό interface (για να πλατιάσουμε κι άλλο :D) τα οποία όπως είπες πριν είναι event-driven. Για να μπορείς να υποστηρίξεις όλα αυτά τα πράγματα, δεν σε συμφέρει η loop-προσέγγιση, αλλά περισσότερο μία Finite State Machine, που θα σου καλύψει όλες τις πιθανές περιπτώσεις.

Προφανώς θεωρώ πως θα υπάρχει πάντα game-loop. Αφού μιλάμε για το συγκεκριμένο πρότζεκτ. Οπότε, το fsm δεν είναι λίγο too much?

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

Η 1η κίνηση (τα αρχικά auto-generated tiles) γίνονται χωρίς user-interation. Στη συνέχεια γίνονται auto-generate μετά από κάθε κίνηση του παίκτη (αλλά δια 2... δηλαδή π.χ. σε 4χ4 ταμπλό, στην αρχή δημιουργούνται 2 και κατόπιν 1 μετά από κάθε κίνηση).

 

Μα κι αυτό δεν είναι συνέπεια κάποιου (re)start_game() το οποίο στην τελική γίνεται trigger από κάποια ενέργεια του "χρήστη";

 

Προφανώς θεωρώ πως θα υπάρχει πάντα game-loop. Αφού μιλάμε για το συγκεκριμένο πρότζεκτ. Οπότε, το fsm δεν είναι λίγο too much?

 

Εξαρτάται πόσο θέλεις να το επεκτείνεις, και προς ποια κατεύθυνση.

Αν πχ θέλεις gui και να κρατήσεις το game-loop και αυτό να μην είναι μέσα στο ui, τότε δεν αποφεύγεις το manager, τα messages, το protocol και όλο το αντίστοιχο overhead.

 

Είναι θέμα σχεδιαστικής επιλογής.

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

Μα κι αυτό δεν είναι συνέπεια κάποιου (re)start_game() το οποίο στην τελική γίνεται trigger από κάποια ενέργεια του "χρήστη";

Ναι, αλλά όταν πρωτο-ξεκινάς γίνεται triggered μόνο του.

 

Είναι θέμα σχεδιαστικής επιλογής.

Εμ τι λέμε τόσην ώρα; :P

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

Λοιπόν, ανέβηκε νέα έκδοση 0.3a3 η οποία online βρίσκεται στο github: https://github.com/geomagas/2048cc (ρίξτε της κάνα αστεράκι αν σας αρέσει :) )

 

Η νέα έκδοση εμφανίζει και την επόμενη κίνηση από την τρέχουσα (μαζί με την προηγούμενη) κατά την παρακολούθηση των replays. Λόγω της νέας αυτής προσθήκης, τα παλαιά replays δεν λειτουργούν πλέον σε αυτή την έκδοση (έχω βάλει νέα sample-replay files στον φάκελο replays/).

 

Εκείνο το a στην αρίθμηση των εκδόσεων σημαίνει alpha-version, δηλαδή όχι εξαντλητικά τεσταρισμένη! Αν βρείτε κάνα bug, κάντε το report εδώ προς το παρόν, να το φτιάξουμε. Αν δεν βρείτε bug και σας αρέσει το game, διαδώστε το, είτε συχνάζετε σε Windows στέκια, είτε σε Linux στέκια, είτε σε Unix στέκια, είτε σε MacOSX στέκια :)

 

Have fun!

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

Καλημέρα,

 

έκανα σχετικά ποστς σε 2 ακόμα δημοφιλή ελληνικά φόρουμ προγραμματισμού, σχετικά με το game παροτρύνοντας όσους κι εάν θέλουν να συμβάλλουν στην περαιτέρω ανάπτυξή του:

 

Ubuntu-gr.org

adslgr.com

 

 

ΥΓ. Τα παρατάω όλα για σήμερα, παίρνω τη γυναίκα και φεύγω για μπανάκι :)

 

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

Καλημέρα,

 

έκανα σχετικά ποστς σε 2 ακόμα δημοφιλή ελληνικά φόρουμ προγραμματισμού, σχετικά με το game παροτρύνοντας όσους κι εάν θέλουν να συμβάλλουν στην περαιτέρω ανάπτυξή του:

 

Ubuntu-gr.org

adslgr.com

Ωραίος!

 

 

 

ΥΓ. Τα παρατάω όλα για σήμερα, παίρνω τη γυναίκα και φεύγω για μπανάκι :)

Ωραιότερος!

 

 

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

Συνεχίζω εδώ την κουβέντα από το άλλο νήμα, νομίζω είναι πιο κατάλληλο αυτό το νήμα.

 

Κατόπιν ωριμότερης σκέψης, είπα να αφήσω την s_fixeol() όπως ήταν, μιας και εξασφαλίσαμε πλέον πως τα replays  έχουν πάντα CRLF ως τέλη γραμμών, Διόρθωσα επίσης την... bug-άρα που εξαντλούσε την μνήμη όταν κάναμε save μεγάλα replays. Ουσιαστικά κατάργησα όλες τις xxx_to_text() συναρτήσεις και τις αντικατέστησα με αντίστοιχες xxx_append_to_fp() οι οποίες αντί να φτιάχνουν τεράστια strings, τα γράφουν απευθείας στο αρχείο που αντιστοιχεί στον file-pointer fp.

 

Έκανα και pull-request και πάω να δω την Αργεντινή σε φιλικό σπίτι (δύσκολα τα πράγματα σήμερα).

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

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

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

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

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

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

Σύνδεση

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

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

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