Переглянути джерело

WIP: report part 2

tags/v1.0b1
Christos Choutouridis 4 роки тому
джерело
коміт
70ae98f31a
5 змінених файлів з 137 додано та 3 видалено
  1. +1
    -1
      report/config
  2. BIN
      report/images/Graph.png
  3. BIN
      report/images/concepts.png
  4. BIN
      report/report.pdf
  5. +136
    -2
      report/report.tex

+ 1
- 1
report/config

@@ -1 +1 @@
Subproject commit c27d16e915615bc56a7b09f56e882661ac69b860
Subproject commit 665a0fc185084bed02af44177b27a855bfb64580

BIN
report/images/Graph.png Переглянути файл

Перед Після
Ширина: 3686  |  Висота: 1665  |  Розмір: 226 KiB

BIN
report/images/concepts.png Переглянути файл

Перед Після
Ширина: 3146  |  Висота: 3160  |  Розмір: 538 KiB

BIN
report/report.pdf Переглянути файл


+ 136
- 2
report/report.tex Переглянути файл

@@ -8,7 +8,7 @@

% Document configuration
\newcommand{\ClassName}{Δομές δεδομένων}
\newcommand{\DocTitle}{Λαβύρινθος: Ο Θησέας και ο Μινώταυρος}
\newcommand{\DocTitle}{Λαβύρινθος: Ο Θησέας και ο Μινώταυρος 1}
\newcommand{\InstructorName}{Σιάχαλου Σταυρούλα}
\newcommand{\InstructorMail}{ssiachal@auth.gr}
\newcommand{\CurrentDate}{\today}
@@ -32,7 +32,141 @@
%\listoffigures
%\listoftables

\section{Εισαγωγή}
\section{Εισαγωγή}
Η παρούσα εργασία αφορά τη δημιουργία ενός παιχνιδιού λαβυρίνθου με θέμα \textit{“Μια νύχτα στο μουσείο”}.
Στο συγκεκριμένο παιχνίδι καλούμαστε να δημιουργήσουμε ένα λαβύρινθο μέσα στον οποίο κινούνται με τυχαίο τρόπο δύο παίχτες, ο Θησέας και ο Μινώταυρος.
Στόχος του Μινώταυρου είναι να “πιάσει” τον Θησέα και στόχος του Θησέα είναι να βρει όλα τα εφόδια που είναι τυχαία κατανεμημένα στο ταμπλό πριν ξημερώσει και πριν τον πιάσει ο Μινώταυρος.
Στο παιχνίδι αυτό υπάρχουν δύο βασικά προβλήματα τα οποία χρειάζεται να λύσουμε.
Το πρόβλημα τις δημιουργίας του λαβύρινθου και το πρόβλημα της λειτουργίας του παιχνιδιού.

\par Κατά την άποψή μας η δημιουργία του ταμπλό είναι το κυριότερο από τα δύο προβλήματα.
Το ταμπλό αποτελείται από πλακίδια και τοίχους.
Τα πλακίδια είναι διατεταγμένα σε τετραγωνικό σχήμα και ανάμεσά τους τοποθετούνται οι τοίχοι.
Το πρόβλημα έγκειται στην επιλογή και τοποθέτηση τοίχων με τέτοιο τρόπο ώστε να πληρούνται οι προδιαγραφές του παιχνιδιού όπως πχ κάθε πλακίδιο να μπορεί να έχει το πολύ δύο τοίχους ή τα εξωτερικά πλακίδια να έχουν τοίχο από την έξω μεριά.
Μετά από μια πιο λεπτομερή ανάλυση του προβλήματος, διαπιστώσαμε πως οι δοθείσες προδιαγραφές δεν αποτρέπουν τη δημιουργία κλειστών δωματίων, κάτι που θεωρήσαμε άδικο, με αποτέλεσμα, όπως περιγράφουμε και αναλυτικά παρακάτω, \textbf{να προσθέσουμε έναν ακόμη περιορισμό.
Την αποτροπή κλειστών δωματίων στο ταμπλό.}

\par Το πρόβλημα της λειτουργίας του υπόλοιπου παιχνιδιού έχει να κάνει με τη δημιουργία των παιχτών καθώς και τις κινήσεις τους.
Οι προδιαγραφές αφορούν περιορισμούς στην κίνηση των παιχτών και τον τρόπο με τον οποίο λειτουργεί το παιχνίδι.
Για παράδειγμα οι παίχτες δεν μπορούν να περάσουν μέσα από τοίχους, ή οι παίχτες κινούνται κατά ένα πλακίδιο τη φορά κλτ.
Σε αντίθεση με τη λύση στο πρόβλημα του ταμπλό εδώ δεν απαιτήθηκαν ιδιαίτερες τεχνικές.

\section{Παραδοτέα}
Τα επισυναπτόμενα παραδοτέα αποτελούνται από:
\begin{itemize}
\item Τον \eng{\textbf{root}}κατάλογο στον οποίο υπάρχει και το \eng{project}του \eng{eclipse.}
Αυτός ο κατάλογος μπορεί να γίνει \eng{import}στο \eng{eclipse.}

\item Ένας υποκατάλογος \eng{\textbf{src/}}με τον κώδικα της \eng{java,}αποτελούμενο από ένα αριθμό αντικειμένων ενσωματωμένο στο πακέτο \eng{host.labyrinth.}
Αναφορά σε αυτό τον κατάλογο υπάρχει στο \eng{eclipse project.}

\item Ένας υποκατάλογος \eng{\textbf{out/}} που περιέχει το παραγόμενο \eng{command line jar}του παιχνιδιού.

\item Ένας υποκατάλογος \eng{\textbf{doc/}}με την τεκμηρίωση του κώδικα όπως αυτή έχει παραχθεί από τα σχόλια, με το εργαλείο \eng{doxygen.}
Το αρχείο ρυθμίσεων του \eng{doxygen}είναι στον \eng{root} με το όνομα \eng{Doxyfile.}
Η πλοήγηση στην τεκμηρίωση μπορεί να γίνει ανοίγοντας το αρχείο \eng{doc/index.html}

\item Ένας υποκατάλογος \eng{\textbf{report/}} που περιέχει την \textbf{παρούσα αναφορά}.
\end{itemize}
Εκτός από τα επισυναπτόμενα αρχεία διαθέσιμο υπάρχει και το \textbf{\eng{git}αποθετήριο} ολόκληρης της εργασίας \href{https://git.hoo2.net/hoo2/Labyrinth}{εδώ}.
Αυτό περιέχει τόσο τον κώδικα της εφαρμογής όσο και τον κώδικα της αναφοράς.

\section{Υλοποίηση}
Η όλη υλοποίηση έγινε σε \eng{java.}
Πριν ασχοληθούμε όμως με τα ζητηθέντα αντικείμενα του προγράμματος, θα πρέπει να αναφερθούμε σε ορισμένες δομές που προστέθηκαν, αλλά και κάποιες σχεδιαστικές επιλογές που έγιναν για να απλοποιήσουν τον κώδικα.

\subsection{\eng{Accessor - mutator idiom}}
Στις προδιαγραφές της εργασίας αφήνεται να εννοηθεί πως ζητείται η χρήση του \eng{\textit{accessor - mutator idiom.}}
Θα πρέπει να παραδεχτούμε όμως, πως \textbf{θεωρούμε το συγκεκριμένο ιδίωμα ιδιαίτερα προβληματικό}.
Ο κύριος λόγος είναι πως παραβιάζει θεμελιακά τις αφαιρέσεις.
Αντ' αυτού \textbf{τα αντικείμενα που υλοποιούνται ως αφαιρέσεις μπορούν να προσφέρουν μεθόδους που εκτελούν κάποια λειτουργία, κρύβοντας τελείως τις εσωτερικές λεπτομέρειες τις υλοποίησης}.
Αυτός είναι και ο δρόμος που διαλέξαμε για το σχεδιασμό του προγράμματος.
Η κάθε τάξη προσφέρει δημόσια ένα αριθμό από μεθόδους που είναι απαραίτητες για την απαιτούμενη λειτουργικότητα της και κρύβει όσο καλύτερα γίνεται την εσωτερική υλοποίηση.
Ενώ λοιπόν υλοποιήσαμε το ζητηθέν \eng{get-set}ζευγάρι για την κάθε μεταβλητή των τάξεων, δεν το χρησιμοποιήσαμε πουθενά μέσα στο πρόγραμμα.

\subsection{Ενοποιημένο σύστημα συντεταγμένων}
Στις προδιαγραφές της εργασίας περιγράφεται επίσης ένα διπλό σύστημα συντεταγμένων, τόσο για τα πλακίδια όσο και για τα εφόδια.
Ένα καρτεσιανό που διευθυνσιοδοτεί ως προς δύο άξονες και περιέχει ένα ζευγάρι γραμμής και στήλης και ένα μονοδιάστατο που αποτελείται από τον γραμμικό συνδυασμό του καρτεσιανού.
Το μονοδιάστατο αντικατοπτρίζει και την απεικόνιση στη μνήμη ενός πίνακα 2 διαστάσεων σε \eng{row major order.}

\par Γενικά θεωρούμε ότι κάτι τέτοιο δημιουργεί πλεονασμό δεδομένων και επομένως είναι κακή πρακτική.
Αυτό γιατί μεταξύ άλλων μειονεκτημάτων, που κυρίως αφορά τον πολυνηματικό προγραμματισμό, οδηγεί και σε προγραμματιστικά λάθη που πιθανώς θα αφήνουν τα δύο συστήματα ασυγχρόνιστα.
Για να λύσουμε αυτό το πρόβλημα \textbf{δημιουργήσαμε την τάξη\eng{Position,}}στην οποία εσωτερικά χρησιμοποιούμε μόνο το ένα από τα δύο συστήματα, για την ακρίβεια το μονοδιάστατο και ταυτόχρονα παρέχουμε μεθόδους για την πρόσβαση στη θέση και από τα δύο συστήματα.
Η τάξη μεταξύ άλλων προσφέρει και \textbf{στατικές μεθόδους για τις μετατροπές} προσφέροντας έτσι μια είδους εργαλειοθήκη για την εφαρμογή.
Έτσι χρησιμοποιήσαμε την \eng{Position}όπου ήταν δυνατό μέσα στον κώδικα.

\section{Αναβάθμιση της τάξης\eng{Tile}}
Κατά τον προγραμματισμό του παιχνιδιού παρατηρήσαμε πως τόσο η τάξη\eng{Tile}όσο και η\eng{Supply}έχουν πληροφορίες για τη θέση τους στο ταμπλό.
Αυτό σημαίνει πως και τα πλακίδια όσο και τα εφόδια ανήκουν στο ταμπλό.
Κάτι τέτοιο γίνεται αντιληπτό ακόμα και από τις προδιαγραφές της\eng{Board}η οποία είναι αυτή που περιέχει τους πίνακες αναφορών τόσο των πλακιδίων όσο και των εφοδίων.
Μια ποιο διαισθητική προσέγγιση βέβαια θα ήθελε τα εφόδια να ανήκουν στα πλακάκια και όχι στο ταμπλό.

\par Όπως είναι φυσικό θελήσαμε να υλοποιήσουμε αυτή την αίσθηση.
Αν όμως μετακινούσαμε τις αναφορές των εφοδίων στην\eng{Tile}θα αλλοιώναμε τις προδιαγραφές της εκφώνησης.
Έτσι επιλέξαμε μια μέση οδό.
Εμπλουτίσαμε την\eng{Tile}με μεθόδους που αφορούν τα εφόδια.
Αυτές είναι οι:
\begin{itemize}
\item \eng{\textbf{\textit{int hasSupply (Supply[] supplies)}}}\\
που δίνει την δυνατότητα να ελέγξουμε αν ένα πλακίδιο έχει κάποιο ενεργό εφόδιο. Και
\item \eng{\textbf{\textit{void pickSupply (Supply[] supplies, int supplyId)}}}\\
που δίνει την δυνατότητα σε κάποιο παίκτη να “σηκώσει” το εφόδιο.
\end{itemize}
Έτσι έχουμε ομοιομορφία με τις αντίστοιχες μεθόδους \eng{\textit{boolean hasWall(int direction)}}και\eng{\textit{int hasWalls()}}της\eng{Tile.}
\par Ένας παρατηρητικός αναγνώστης θα διαπιστώσει πως οι συναρτήσεις για τα εφόδια είναι αναγκασμένες να πάρουν τον πίνακα αναφορών στα εφόδια ως όρισμα.
Αυτό είναι το τίμημα που πρέπει να πληρώσουμε προωθώντας τις μεθόδους αυτές στην\eng{Tile.}

\section{\eng{Concepts}}
Η δημιουργία της\eng{Board}αποτέλεσε τον μεγαλύτερο όγκο του κώδικα της παρούσας εργασίας.
Για να κάνουμε τον κώδικα καθαρότερο αλλά και ευκολότερο στην κατανόηση επινοήσαμε κάποια\eng{\textbf{concepts}.}
Η ιδέα των\eng{concepts}προέρχεται από την\eng{C++}όπου τα\eng{concepts}είναι ένα είδους \eng{compile time predicate}και εφαρμόζεται στους τύπους δεδομένων.
Εμείς για την εργασία υλοποιήσαμε κάποια\eng{concepts} σε μορφή\eng{predicate.}
Στο σχήμα \ref{fig:concepts} φαίνεται μια οπτικοποιημένη έκδοση τους.

\subsection{\eng{Sentinel tile}}
\WrapFigure{0.5}{r}{fig:concepts}{images/concepts.png}{Οπτική αναπαράσταση των\eng{concepts}που χρησιμοποιούμε σε ένα ταμπλό $7x7$}
Πρόκειται για\eng{concept}που μας επιτρέπει να ελέγξουμε αν το πλακίδιο είναι \textbf{“πλακίδιο φρουρός”}.
Αν δηλαδή βρίσκεται στα εξωτερικά άκρα του ταμπλό.
Η υλοποίηση αυτού του\eng{concept}γίνεται μέσω τεσσάρων συναρτήσεων που ελέγχουν χωριστά τις τέσσερεις διευθύνσεις του ταμπλό.
\par Για την παράδειγμα η \eng{\textit{boolean isLeftSentinel (int tileId)}}μας δίνει την δυνατότητα να ελέγξουμε αν το πλακίδιο είναι “πλακίδιο φρουρού” αριστερά του ταμπλό.
Αυτό είναι χρήσιμο για λειτουργίες όπως για παράδειγμα αν θέλουμε να δούμε μήπως χρειάζεται να τοποθετηθεί τοίχος αριστερά του πλακιδίου.
Αντίστοιχα υπάρχουν και οι υπόλοιπες συναρτήσεις για τις υπόλοιπες διευθύνσεις.

\subsection{\eng{Walkable direction}}
Πρόκειται για\eng{predicate}που μας επιτρέπει να ελέγξουμε αν μια διεύθυνση σε κάποιο πλακίδιο είναι \textbf{“διασχίσημη”}.
Για να ισχύει κάτι τέτοιο θα πρέπει:
\begin{itemize}
\item Η διεύθυνση να μην έχει τοίχο.
\item Η διεύθυνση να μην είναι η “Κάτω” διεύθυνση του πλακιδίου εισόδου στο λαβύρινθο.
\end{itemize}

\subsection{\eng{Wallable direction}}
Πρόκειται για\eng{predicate}που μας επιτρέπει να ελέγξουμε αν μια διεύθυνση κάποιου πλακιδίου είναι \textbf{”χτίσιμη”}.
Αυτό το\eng{concept}είναι πολύ χρήσιμο κατά τη δημιουργία των τοίχων.
Για να είναι μια διεύθυνση χτίσιμη θα πρέπει:
\begin{itemize}
\item Η διεύθυνση να μην έχει τοίχο.
\item Η διεύθυνση να μην είναι η “Κάτω” διεύθυνση του πλακιδίου εισόδου στο λαβύρινθο.
\item Το γειτονικό πλακίδιο σε αυτή τη διεύθυνση να μην περιέχει ήδη τον μέγιστο αριθμό πλακιδίων.
\item Ο τοίχος να μην δημιουργεί κάποιο κλειστό δωμάτιο.\\
Αυτή η απαίτηση δεν υπάρχει στις προδιαγραφές και την παίρνουμε υπόψιν μόνο αν ο χρήστης την έχει ζητήσει από την γραμμή εντολών.
Ο λόγος είναι γιατί ο υπολογισμός της κοστίζει και αυτό μπορεί να μην παίζει ρόλο για ταμπλό μεγέθους $15x15$, αλλά αν ζητηθεί κάποιο πολύ μεγαλύτερο τότε ο χρόνος είναι υπολογίσιμος.
Φυσικά στον κώδικα κάνουμε χρήση αυτού του \eng{concept}μόνο κατά τη δημιουργία του ταμπλό.
\end{itemize}

\subsection{\eng{Wallable tile}}
Πρόκειται για\eng{predicate}που μας επιτρέπει να ελέγξουμε αν κάποιο πλακιδίο είναι \textbf{”χτίσιμo”}.
Για να ισχύει αυτό θα πρέπει:
\begin{itemize}
\item Το πλακίδιο να μην έχει ήδη τον μέγιστο αριθμό τοίχων.
\item Να υπάρχει τουλάχιστον μία “χτίσιμη” διεύθυνση στο πλακίδιο.
\end{itemize}

\subsection{Εύρεση κλειστών δωματίων}
Όπως αναφέραμε και παραπάνω οι προδιαγραφές της εργασίας δεν αποτρέπουν τη δημιουργία κλειστών δωματίων, κάτι που θεωρήσαμε άδικο.
Για το λόγο αυτό υλοποιήσαμε ένα αλγόριθμο που ανιχνεύει την πιθανότητα δημιουργίας κλειστών δωματίων του οποίου η ενεργοποίηση γίνεται κατόπιν επιλογής του χρήστη από τη γραμμή εντολών.

\InsertFigure{0.6}{fig:graph}{images/graph.png}{Γράφος.}

% References
% ============================


Завантаження…
Відмінити
Зберегти