1 |
#LyX 1.2 created this file. For more info see http://www.lyx.org/ |
#LyX 1.2 created this file. For more info see http://www.lyx.org/ |
2 |
\lyxformat 220 |
\lyxformat 220 |
3 |
\textclass article |
\textclass scrbook |
4 |
\language spanish |
\language spanish |
5 |
\inputencoding auto |
\inputencoding auto |
6 |
\fontscheme pslatex |
\fontscheme pslatex |
9 |
\paperfontsize default |
\paperfontsize default |
10 |
\spacing single |
\spacing single |
11 |
\papersize a4paper |
\papersize a4paper |
12 |
\paperpackage a4wide |
\paperpackage widemarginsa4 |
13 |
\use_geometry 0 |
\use_geometry 0 |
14 |
\use_amsmath 0 |
\use_amsmath 0 |
15 |
\use_natbib 0 |
\use_natbib 0 |
19 |
\tocdepth 3 |
\tocdepth 3 |
20 |
\paragraph_separation indent |
\paragraph_separation indent |
21 |
\defskip medskip |
\defskip medskip |
22 |
\quotes_language english |
\quotes_language swedish |
23 |
\quotes_times 2 |
\quotes_times 2 |
24 |
\papercolumns 1 |
\papercolumns 1 |
25 |
\papersides 1 |
\papersides 1 |
38 |
\series bold |
\series bold |
39 |
\size small |
\size small |
40 |
\emph default |
\emph default |
41 |
versión 0.92 |
versión 0.9 |
42 |
|
\series default |
43 |
|
3 |
44 |
|
\series bold |
45 |
|
|
46 |
\newline |
\newline |
47 |
Siempre actualizada en http://eutherpe.org |
Siempre actualizada en http://eutherpe.org |
48 |
\layout Author |
\layout Author |
62 |
y Diego Moya Velázquez |
y Diego Moya Velázquez |
63 |
\emph on |
\emph on |
64 |
Hizgael |
Hizgael |
65 |
\layout Standard |
\layout Dedication |
66 |
|
|
67 |
|
|
68 |
\begin_inset LatexCommand \tableofcontents{} |
\size footnotesize |
69 |
|
\emph on |
70 |
|
Ancho, alto y profundo es el reino de los cuentos de hadas, y lleno todo |
71 |
|
él de cosas diversas: hay allí toda suerte de bestias y pájaros; mares |
72 |
|
sin riberas e incontables estrellas; belleza que embelesa y un peligro |
73 |
|
siempre presente; la alegría, lo mismo que la tristeza, son afiladas como |
74 |
|
espadas. |
75 |
|
Tal vez un hombre pueda sentirse dichoso de haber vagado por ese reino, |
76 |
|
pero su misma plenitud y condición arcana atan la lengua del viajero que |
77 |
|
desee describirlo. |
78 |
|
Y mientras está en él le resulta peligroso hacer demasiadas preguntas, |
79 |
|
no vaya a ser que las puertas se cierren y desaparezcan las llaves. |
80 |
|
|
81 |
|
\size default |
82 |
|
\emph default |
83 |
|
|
84 |
\end_inset |
\newline |
85 |
|
|
86 |
|
\size normal |
87 |
|
\SpecialChar ~ |
88 |
|
|
89 |
\layout Standard |
\newline |
90 |
|
\SpecialChar ~ |
91 |
|
\SpecialChar ~ |
92 |
|
\SpecialChar ~ |
93 |
|
\SpecialChar ~ |
94 |
|
\SpecialChar ~ |
95 |
|
\SpecialChar ~ |
96 |
|
\SpecialChar ~ |
97 |
|
\SpecialChar ~ |
98 |
|
\SpecialChar ~ |
99 |
|
\SpecialChar ~ |
100 |
|
\SpecialChar ~ |
101 |
|
\SpecialChar ~ |
102 |
|
\SpecialChar ~ |
103 |
|
\SpecialChar ~ |
104 |
|
\SpecialChar ~ |
105 |
|
\SpecialChar ~ |
106 |
|
\SpecialChar ~ |
107 |
|
\SpecialChar ~ |
108 |
|
\SpecialChar ~ |
109 |
|
\SpecialChar ~ |
110 |
|
\SpecialChar ~ |
111 |
|
\SpecialChar ~ |
112 |
|
\SpecialChar ~ |
113 |
|
\SpecialChar ~ |
114 |
|
\SpecialChar ~ |
115 |
|
\SpecialChar ~ |
116 |
|
\SpecialChar ~ |
117 |
|
\SpecialChar ~ |
118 |
|
\SpecialChar ~ |
119 |
|
\SpecialChar ~ |
120 |
|
\SpecialChar ~ |
121 |
|
\SpecialChar ~ |
122 |
|
\SpecialChar ~ |
123 |
|
\SpecialChar ~ |
124 |
|
\SpecialChar ~ |
125 |
|
\SpecialChar ~ |
126 |
|
|
127 |
|
\series bold |
128 |
|
Sobre los Cuentos de Hadas, JRR Tolkien |
129 |
|
\layout Standard |
130 |
|
|
|
\begin_inset ERT |
|
|
status Open |
|
131 |
|
|
132 |
\layout Standard |
\begin_inset LatexCommand \tableofcontents{} |
133 |
|
|
|
\backslash |
|
|
newpage |
|
134 |
\end_inset |
\end_inset |
135 |
|
|
136 |
|
|
137 |
\layout Section |
\layout Chapter |
138 |
|
|
139 |
Introducción |
Introducción |
140 |
\layout Standard |
\layout Standard |
164 |
La única restricción que imponemos es que las modificaciones realizadas |
La única restricción que imponemos es que las modificaciones realizadas |
165 |
a una copia privada del código fuente de Minë han de acogerse también a |
a una copia privada del código fuente de Minë han de acogerse también a |
166 |
la Licencia Pública General (visite http://www.gnu.org). |
la Licencia Pública General (visite http://www.gnu.org). |
167 |
\layout Section |
\layout Standard |
168 |
|
|
169 |
|
Esperamos que de alguna forma u otra (jugando, informando de fallos, escribiendo |
170 |
|
áreas o código) disfrutéis de Minë tanto como nosotros. |
171 |
|
\layout Chapter |
172 |
|
|
173 |
Construcción de un área |
Construcción de un área |
174 |
\layout Standard |
\layout Standard |
260 |
\layout Itemize |
\layout Itemize |
261 |
|
|
262 |
Salidas posibles |
Salidas posibles |
263 |
\layout Subsection |
\layout Section |
264 |
|
|
265 |
Cómo dar forma a la imaginación |
Cómo dar forma a la imaginación |
266 |
\layout Standard |
\layout Standard |
325 |
\end_inset |
\end_inset |
326 |
|
|
327 |
|
|
328 |
\layout Subsection |
\layout Section |
329 |
|
|
330 |
Pasamos a la acción. |
Pasamos a la acción. |
331 |
¿Cómo escribo una habitación? |
¿Cómo escribo una habitación? |
352 |
Dentro de este directorio vamos creando diferentes ficheros con diferentes |
Dentro de este directorio vamos creando diferentes ficheros con diferentes |
353 |
nombres, siempre de acuerdo al manual mencionado. |
nombres, siempre de acuerdo al manual mencionado. |
354 |
Veamos nuestro ejemplo. |
Veamos nuestro ejemplo. |
355 |
\layout Subsubsection |
\layout Subsection |
356 |
|
|
357 |
Planta baja |
Planta baja |
358 |
\layout Paragraph |
\layout Paragraph |
364 |
\family typewriter |
\family typewriter |
365 |
\size small |
\size small |
366 |
|
|
367 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-recibidor01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-recibidor01.xml} |
368 |
|
|
369 |
\end_inset |
\end_inset |
370 |
|
|
378 |
\family typewriter |
\family typewriter |
379 |
\size small |
\size small |
380 |
|
|
381 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-almacen01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-almacen01.xml} |
382 |
|
|
383 |
\end_inset |
\end_inset |
384 |
|
|
392 |
\family typewriter |
\family typewriter |
393 |
\size small |
\size small |
394 |
|
|
395 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-salon01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-salon01.xml} |
396 |
|
|
397 |
\end_inset |
\end_inset |
398 |
|
|
406 |
\family typewriter |
\family typewriter |
407 |
\size small |
\size small |
408 |
|
|
409 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-cocina01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-cocina01.xml} |
410 |
|
|
411 |
\end_inset |
\end_inset |
412 |
|
|
420 |
\family typewriter |
\family typewriter |
421 |
\size small |
\size small |
422 |
|
|
423 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-servicio01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-servicio01.xml} |
424 |
|
|
425 |
\end_inset |
\end_inset |
426 |
|
|
434 |
\family typewriter |
\family typewriter |
435 |
\size small |
\size small |
436 |
|
|
437 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-servicio_letrinas01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-servicio_letrinas01.xml} |
438 |
|
|
439 |
\end_inset |
\end_inset |
440 |
|
|
448 |
\family typewriter |
\family typewriter |
449 |
\size small |
\size small |
450 |
|
|
451 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-escaleras01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-escaleras01.xml} |
452 |
|
|
453 |
\end_inset |
\end_inset |
454 |
|
|
455 |
|
|
456 |
\layout Subsubsection |
\layout Subsection |
457 |
|
|
458 |
Planta de arriba |
Planta de arriba |
459 |
\layout Paragraph |
\layout Paragraph |
465 |
\family typewriter |
\family typewriter |
466 |
\size small |
\size small |
467 |
|
|
468 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-escaleras02.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-escaleras02.xml} |
469 |
|
|
470 |
\end_inset |
\end_inset |
471 |
|
|
479 |
\family typewriter |
\family typewriter |
480 |
\size small |
\size small |
481 |
|
|
482 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-distribuidor01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-distribuidor01.xml} |
483 |
|
|
484 |
\end_inset |
\end_inset |
485 |
|
|
493 |
\family typewriter |
\family typewriter |
494 |
\size small |
\size small |
495 |
|
|
496 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-cuarto_seroth01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-cuarto_seroth01.xml} |
497 |
|
|
498 |
\end_inset |
\end_inset |
499 |
|
|
507 |
\family typewriter |
\family typewriter |
508 |
\size small |
\size small |
509 |
|
|
510 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-tocador01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-tocador01.xml} |
511 |
|
|
512 |
\end_inset |
\end_inset |
513 |
|
|
521 |
\family typewriter |
\family typewriter |
522 |
\size small |
\size small |
523 |
|
|
524 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_salas/seroth/seroth-letrinas01.xml} |
\begin_inset Include \verbatiminput{../desc_salas/seroth/seroth-letrinas01.xml} |
525 |
|
|
526 |
\end_inset |
\end_inset |
527 |
|
|
528 |
|
|
529 |
\layout Subsection |
\layout Section |
530 |
|
|
531 |
¿Qué hay de los objetos? |
¿Qué hay de los objetos? |
532 |
\layout Standard |
\layout Standard |
580 |
\family typewriter |
\family typewriter |
581 |
\size small |
\size small |
582 |
|
|
583 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_objetos/tomillo01.xml} |
\begin_inset Include \verbatiminput{../desc_objetos/tomillo01.xml} |
584 |
|
|
585 |
\end_inset |
\end_inset |
586 |
|
|
594 |
\family typewriter |
\family typewriter |
595 |
\size small |
\size small |
596 |
|
|
597 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_objetos/cuchillo01.xml} |
\begin_inset Include \verbatiminput{../desc_objetos/cuchillo01.xml} |
598 |
|
|
599 |
\end_inset |
\end_inset |
600 |
|
|
608 |
\family typewriter |
\family typewriter |
609 |
\size small |
\size small |
610 |
|
|
611 |
\begin_inset Include \verbatiminput{/home/elfo/cvs/mine_cvs/desc_objetos/pluma_de_ave01.xml} |
\begin_inset Include \verbatiminput{../desc_objetos/pluma_de_ave01.xml} |
612 |
|
|
613 |
\end_inset |
\end_inset |
614 |
|
|
629 |
desc_objetos |
desc_objetos |
630 |
\series default |
\series default |
631 |
. |
. |
632 |
\layout Section |
\layout Chapter |
633 |
|
|
634 |
Contribuir con código |
Contribuir con código |
635 |
\layout Standard |
\layout Standard |
672 |
\series default |
\series default |
673 |
para los ficheros fuente de las salas, PNJs y objetos ya que apostamos |
para los ficheros fuente de las salas, PNJs y objetos ya que apostamos |
674 |
por estándares asentados y versátiles. |
por estándares asentados y versátiles. |
675 |
|
\layout Section |
676 |
|
|
677 |
|
El mapa del código |
678 |
\layout Standard |
\layout Standard |
679 |
|
|
680 |
El punto de comienzo para ayudar con el código de Minë es, sin duda, los |
Para no perdernos en el proceloso mar de líneas de código (actualmente los |
681 |
diagramas UML que encontrarás en la página electrónica de Minë, |
ficheros fuente de Minë ocupan cerca de 10.000 líneas), mantenemos a modo |
682 |
\series bold |
de mapa un diagrama de clases, hecho con UML. |
683 |
http://eutherpe.org/desarrollo.html |
La última versión está disponible en la página electrónica de Minë, http://euth |
684 |
\series default |
erpe.org/desarrollo.html. |
685 |
y que te darán una idea general del diseño que seguimos. |
\layout Standard |
686 |
Tras esto te recomendamos que eches un vistazo a un fichero de Minë que |
|
687 |
sea simplón como |
Los diagramas muestran el diseño de alto nivel del programa, y son imprescindibl |
688 |
\family typewriter |
es para conocer su estructura, antes de empezar a leer las clases de una |
689 |
ayuda.py |
en una. |
690 |
\family default |
Hay tres grandes bloques: |
691 |
o |
\layout Itemize |
692 |
\family typewriter |
|
693 |
idioma.py |
Modelo de datos |
694 |
\family default |
\begin_inset Formula $\longrightarrow $ |
695 |
y finalmente escudriña todo el código fuente de Minë (casi 10.000 líneas). |
\end_inset |
696 |
|
|
697 |
|
una representación abstracta del mundo y sus habitantes, independiente |
698 |
|
del interfaz (debería poder usarse tal cual si cambiáramos el interfaz, |
699 |
|
por ejemplo a uno gráfico). |
700 |
|
\layout Itemize |
701 |
|
|
702 |
|
Control |
703 |
|
\begin_inset Formula $\longrightarrow $ |
704 |
|
\end_inset |
705 |
|
|
706 |
|
el interfaz de usuario. |
707 |
|
Aquí se interactúa con los jugadores y se controla (o sea, se da órdenes) |
708 |
|
a los PJ y PNJ. |
709 |
|
\layout Itemize |
710 |
|
|
711 |
|
Infraestructura |
712 |
|
\begin_inset Formula $\longrightarrow $ |
713 |
|
\end_inset |
714 |
|
|
715 |
|
algunas clases no relacionadas entre sí, con utilidades genéricas usadas |
716 |
|
por el resto de módulos. |
717 |
|
\layout Standard |
718 |
|
|
719 |
|
|
720 |
|
\begin_inset Float figure |
721 |
|
placement htbp |
722 |
|
wide true |
723 |
|
collapsed false |
724 |
|
|
725 |
|
\layout Standard |
726 |
|
|
727 |
|
|
728 |
|
\begin_inset Graphics FormatVersion 1 |
729 |
|
filename mine.png |
730 |
|
BoundingBox 0 0 307bp 391bp |
731 |
|
display default |
732 |
|
size_type 2 |
733 |
|
scale 40 |
734 |
|
rotateOrigin center |
735 |
|
lyxsize_type 2 |
736 |
|
|
737 |
|
\end_inset |
738 |
|
|
739 |
|
|
740 |
|
\end_inset |
741 |
|
|
742 |
|
|
743 |
|
\layout Subsection |
744 |
|
|
745 |
|
Modelo de datos |
746 |
|
\layout Standard |
747 |
|
|
748 |
|
Este es el bloque más significativo, que contiene el diseño "conceptual". |
749 |
|
Cada clase de aquí representa una entidad del juego tal como lo ven los |
750 |
|
usuarios (personajes, salas, objetos...). |
751 |
|
\layout Standard |
752 |
|
|
753 |
|
|
754 |
|
\begin_inset Float figure |
755 |
|
placement htbp |
756 |
|
wide true |
757 |
|
collapsed false |
758 |
|
|
759 |
|
\layout Standard |
760 |
|
|
761 |
|
|
762 |
|
\begin_inset Graphics FormatVersion 1 |
763 |
|
filename mine-modelo.png |
764 |
|
display default |
765 |
|
size_type 2 |
766 |
|
scale 45 |
767 |
|
rotateOrigin center |
768 |
|
lyxsize_type 0 |
769 |
|
|
770 |
|
\end_inset |
771 |
|
|
772 |
|
|
773 |
|
\end_inset |
774 |
|
|
775 |
|
|
776 |
|
\layout Standard |
777 |
|
|
778 |
|
El diagrama se lee mejor de arriba a abajo. |
779 |
|
Al principio parece un poco confuso, pero todos los elementos tienen un |
780 |
|
sentido intuitivo. |
781 |
|
\layout Standard |
782 |
|
|
783 |
|
El Mundo es único y representa eso, todo el mundo de Minë y lo que hay en |
784 |
|
él. |
785 |
|
Contiene una lista de Salas (el rombo en UML significa contener), y cada |
786 |
|
Sala, a su vez, contiene personajes: los personajes que se encuentran dentro |
787 |
|
de esa sala. |
788 |
|
Los Objetos ahora no están modelados del todo, pero en principio podrán |
789 |
|
estar dentro de una Sala o de un Personaje. |
790 |
|
\layout Standard |
791 |
|
|
792 |
|
Un Personaje, a su vez, puede ser PersonajeJugador o PersonajeNoJugador |
793 |
|
(la línea de puntos con un triángulo, en UML, significa subclasificación). |
794 |
|
Todos los personajes conocen de 1 a 5 idiomas, y los jugadores tienen además |
795 |
|
una Raza y una Profesión. |
796 |
|
\layout Standard |
797 |
|
|
798 |
|
Finalmente, todo Personaje es manejado por un objeto Controlador, que es |
799 |
|
quien le da las ordenes de lo que debe hacer, y a quien informa de las |
800 |
|
cosas que le ocurren. |
801 |
|
Controlador no es una clase, sino un interfaz, lo que significa que no |
802 |
|
contiene código, sino sólo la declaración de qué métodos debe tener una |
803 |
|
clase que pueda controlar Personajes. |
804 |
|
Las clases que implementan ese interfaz pertenecen al siguiente bloque |
805 |
|
del diagrama. |
806 |
|
\layout Standard |
807 |
|
|
808 |
|
Hay algunas asociaciones más entre clases, que se pueden entender observando |
809 |
|
el código fuente. |
810 |
|
Las clases que tienen un único rectángulo (por ejemplo ConnectionHandler) |
811 |
|
no pertenecen a este diagrama, se muestran aquí sólo para poder ver las |
812 |
|
asociaciones. |
813 |
|
\layout Subsection |
814 |
|
|
815 |
|
Control. |
816 |
|
\layout Standard |
817 |
|
|
818 |
|
Este bloque es un poco más abstracto. |
819 |
|
Contiene las clases que llevan el control del programa y la interacción |
820 |
|
con el jugador. |
821 |
|
\layout Standard |
822 |
|
|
823 |
|
|
824 |
|
\begin_inset Float figure |
825 |
|
placement htbp |
826 |
|
wide true |
827 |
|
collapsed false |
828 |
|
|
829 |
|
\layout Standard |
830 |
|
|
831 |
|
|
832 |
|
\begin_inset Graphics FormatVersion 1 |
833 |
|
filename mine-control.png |
834 |
|
display default |
835 |
|
size_type 2 |
836 |
|
scale 50 |
837 |
|
rotateOrigin center |
838 |
|
lyxsize_type 0 |
839 |
|
|
840 |
|
\end_inset |
841 |
|
|
842 |
|
|
843 |
|
\end_inset |
844 |
|
|
845 |
|
|
846 |
|
\layout Standard |
847 |
|
|
848 |
|
La clase Mine es el programa en sí. |
849 |
|
Es el fichero que se ejecuta al inicio y contiene el bucle principal. |
850 |
|
Inicializa el Mundo y los InterfacesPJ (las flechas punteadas en UML representa |
851 |
|
n una asociación no permanente). |
852 |
|
\layout Standard |
853 |
|
|
854 |
|
Un InterfazPJ es el objeto que controla a un PersonajeJugador. |
855 |
|
Acepta conexiones telnet para recibir comandos de un jugador y enviarle |
856 |
|
sus respuestas, y también da órdenes al personaje y recibe los "sucesos" |
857 |
|
o "eventos" que éste genera. |
858 |
|
\layout Standard |
859 |
|
|
860 |
|
La funcionalidad de un InterfazPJ, al ser bastante complicada, está repartida |
861 |
|
en diferentes Diálogos. |
862 |
|
Cada Dialogo es una "máquina de estados" que representa una situación de |
863 |
|
diálogo con el jugador (por ejemplo, creación de un personaje nuevo, juego |
864 |
|
normal, modo combate, etc.). |
865 |
|
\layout Standard |
866 |
|
|
867 |
|
Una máquina de estados es un objeto que tiene un "estado" en cada momento, |
868 |
|
y responde a "sucesos" que le ocurren bien cambiando a otro estado o realizando |
869 |
|
una acción. |
870 |
|
Por ejemplo, en el dialogo "crear un pj", al entrar en estado 1 pregunta |
871 |
|
el nombre del pj, y espera que ocurra algo. |
872 |
|
Si el jugador teclea un nombre correcto, lo registra y pasa al estado 2. |
873 |
|
Si teclea un nombre incorrecto (que ya existe, por ejemplo), devuelve un |
874 |
|
mensaje de error y continúa en estado 1. |
875 |
|
\layout Standard |
876 |
|
|
877 |
|
Un InterfazPNJ tiene la misma misión, pero esta vez sobre un PersonajeNoJugador. |
878 |
|
La diferencia es que no tiene ningún socket telnet, sino que las órdenes |
879 |
|
a ejecutar las decide un programa de inteligencia artificial (más o menos |
880 |
|
"inteligente"). |
881 |
|
\layout Subsection |
882 |
|
|
883 |
|
Infraestructura |
884 |
|
\layout Standard |
885 |
|
|
886 |
|
En este bloque tenemos clases que representan conceptos genéricos que tienen |
887 |
|
más relación con el sistema operativo que con un juego MUD. |
888 |
|
\layout Standard |
889 |
|
|
890 |
|
|
891 |
|
\begin_inset Float figure |
892 |
|
placement htbp |
893 |
|
wide true |
894 |
|
collapsed false |
895 |
|
|
896 |
|
\layout Standard |
897 |
|
|
898 |
|
|
899 |
|
\begin_inset Graphics FormatVersion 1 |
900 |
|
filename mine-infraestructura.png |
901 |
|
display default |
902 |
|
size_type 2 |
903 |
|
scale 50 |
904 |
|
rotateOrigin center |
905 |
|
lyxsize_type 0 |
906 |
|
|
907 |
|
\end_inset |
908 |
|
|
909 |
|
|
910 |
|
\end_inset |
911 |
|
|
912 |
|
|
913 |
|
\layout Standard |
914 |
|
|
915 |
|
ConnectionHandler y Connection representan "sockets" TCP/IP, es decir, los |
916 |
|
canales de comunicación que implementan el protocolo telnet, usado para |
917 |
|
hablar con los jugadores. |
918 |
|
\layout Standard |
919 |
|
|
920 |
|
TimerHandler y Timer son temporizadores, o cronómetros, útiles para medir |
921 |
|
tiempos. |
922 |
|
\layout Standard |
923 |
|
|
924 |
|
Utils es un módulo "cajón de sastre" para meter funciones sencillitas y |
925 |
|
variadas. |
926 |
\layout Section |
\layout Section |
927 |
|
|
928 |
|
Entendiendo el código |
929 |
|
\layout Standard |
930 |
|
|
931 |
|
Hemos seguido unas reglas básicas de codificación, para mantener un estilo |
932 |
|
coherente en distintos ficheros hechos por diferentes programadores. |
933 |
|
En primer lugar, tenemos un fichero fuente por cada clase, con el mismo |
934 |
|
nombre de la clase en minúsculas (p. |
935 |
|
ej. |
936 |
|
la clase DialogoCrear está en dialogocrear.py). |
937 |
|
Todos los ficheros tienen al principio la nota de "CopyLeft", el comentario |
938 |
|
que indica su contenido, los import, y la clase. |
939 |
|
Todas las clases tienen un bloque de comentarios explicando la clase con |
940 |
|
detalle. |
941 |
|
Al final se incluye un trozo de código para pruebas unitarias del módulo. |
942 |
|
\layout Standard |
943 |
|
|
944 |
|
Al escribir el código se siguen unas normas de diseño, que se pueden consultar |
945 |
|
en el apéndice titulado 'Normas de diseño de código fuente de Minë'. |
946 |
|
\layout Standard |
947 |
|
|
948 |
|
Al leer el código es fundamental leer las clases siguiendo el diagrama, |
949 |
|
de arriba a abajo, y leer y entender en primer lugar la cabecera donde |
950 |
|
se explica qué representa, y cuales son sus atributos. |
951 |
|
\layout Standard |
952 |
|
|
953 |
|
El bucle principal del programa está en mine.py, pero casi no hace falta |
954 |
|
ni que lo mires. |
955 |
|
El programa se comporta como si todos los objetos del sistema estuvieran |
956 |
|
"vivos" y funcionando al mismo tiempo. |
957 |
|
Cuando ocurre cualquier cosa, el objeto correspondiente recibe un mensaje |
958 |
|
de "evento", es decir, "alguien" llama a un método de un objeto diciéndole |
959 |
|
que ha ocurrido algo (al principio no es necesario que sepas quién es ese |
960 |
|
alguien). |
961 |
|
Por ejemplo, si un jugador escribe algo desde su terminal, el objeto de |
962 |
|
tipo InterfazPJ correspondiente a ese jugador recibe una llamada al método |
963 |
|
comando_recibido(). |
964 |
|
\layout Chapter |
965 |
|
|
966 |
Apéndices |
Apéndices |
967 |
\layout Subsection |
\layout Section |
968 |
|
|
969 |
Descripción del sistema de conversaciones con los PNJ |
Descripción del sistema de conversaciones con los PNJ |
970 |
\layout Standard |
\layout Standard |
974 |
Son sus residentes naturales, los vecinos con los que puedes mantener una |
Son sus residentes naturales, los vecinos con los que puedes mantener una |
975 |
conversación formal pero agradable, y que te pueden revelar algún secreto |
conversación formal pero agradable, y que te pueden revelar algún secreto |
976 |
de la región que estás visitando. |
de la región que estás visitando. |
977 |
A continuación se describe el mecanismo que se incluriá en Minë para hablar |
A continuación se describe el mecanismo que se incluirá en Minë para hablar |
978 |
con ellos. |
con ellos. |
979 |
\layout Standard |
\layout Standard |
980 |
|
|
1142 |
\family typewriter |
\family typewriter |
1143 |
\size footnotesize |
\size footnotesize |
1144 |
- Si escribes: "Estoy de buen humor, ¿tú no?", dirás ese texto y te podrán |
- Si escribes: "Estoy de buen humor, ¿tú no?", dirás ese texto y te podrán |
1145 |
oir todos los que estén en la misma habitación. |
oír todos los que estén en la misma habitación. |
1146 |
También puedes escribir el comando: "+preguntar por supervivencia" para |
También puedes escribir el comando: "+preguntar por supervivencia" para |
1147 |
comenzar una conversación sobre ese tema. |
comenzar una conversación sobre ese tema. |
1148 |
\layout Standard |
\layout Standard |
1204 |
\size footnotesize |
\size footnotesize |
1205 |
- ¡Ah! Se llenaría un tratado entero para responder con propiedad esa pregunta. |
- ¡Ah! Se llenaría un tratado entero para responder con propiedad esa pregunta. |
1206 |
¿Por qué no me pides que te lo explique... |
¿Por qué no me pides que te lo explique... |
1207 |
en otra ocasion? |
en otra ocasión? |
1208 |
\layout Subsubsection |
\layout Subsection |
1209 |
|
|
1210 |
Creación de conversaciones |
Creación de conversaciones |
1211 |
\layout Standard |
\layout Standard |
1492 |
Si el personaje pregunta por un tema que no está en el mismo contexto ni |
Si el personaje pregunta por un tema que no está en el mismo contexto ni |
1493 |
está relacionado con los items utilizados, la pregunta está "fuera de contexto" |
está relacionado con los items utilizados, la pregunta está "fuera de contexto" |
1494 |
y el personaje no jugador se extrañará por el cambio brusco del diálogo. |
y el personaje no jugador se extrañará por el cambio brusco del diálogo. |
1495 |
\layout Subsubsection |
\layout Subsection |
1496 |
|
|
1497 |
Confianza entre el PNJ y los PJs |
Confianza entre el PNJ y los PJs |
1498 |
\layout Standard |
\layout Standard |
1520 |
de Carisma. |
de Carisma. |
1521 |
Ciertos contextos o items de la conversación sólo serán accesibles si la |
Ciertos contextos o items de la conversación sólo serán accesibles si la |
1522 |
confianza en el PJ está por encima de un umbral. |
confianza en el PJ está por encima de un umbral. |
1523 |
\layout Subsubsection |
\layout Subsection |
1524 |
|
|
1525 |
Salas llenas de gente |
Salas llenas de gente |
1526 |
\layout Standard |
\layout Standard |
1542 |
el que tenga más confianza. |
el que tenga más confianza. |
1543 |
Esto último refuerza la ambientación de la característica Carisma: los |
Esto último refuerza la ambientación de la característica Carisma: los |
1544 |
PNJs tenderán a hablar con los PJ más carismáticos. |
PNJs tenderán a hablar con los PJ más carismáticos. |
1545 |
\layout Subsubsection |
\layout Subsection |
1546 |
|
|
1547 |
Iniciativa de los PNJ |
Iniciativa de los PNJ |
1548 |
\layout Standard |
\layout Standard |
1569 |
|
|
1570 |
Este sistema puede forzar a que los jugadores hablen con el PNJ más interesante |
Este sistema puede forzar a que los jugadores hablen con el PNJ más interesante |
1571 |
de la sala, si antes les había pasado desapercibido. |
de la sala, si antes les había pasado desapercibido. |
1572 |
\layout Subsubsection |
\layout Subsection |
1573 |
|
|
1574 |
Efectos especiales durante la conversación |
Efectos especiales durante la conversación |
1575 |
\layout Standard |
\layout Standard |
1591 |
d aumenta. |
d aumenta. |
1592 |
\layout Standard |
\layout Standard |
1593 |
|
|
1594 |
Las frases de ambientación no necesariamente deben estar ligadas a un item |
Las frases de ambientación no necesariamente deben estar ligadas a un ítem |
1595 |
de texto concreto; habrá un mecanismo para que la frase se pueda activar |
de texto concreto; habrá un mecanismo para que la frase se pueda activar |
1596 |
automáticamente en momentos claves del diálogo, por ejemplo cada vez que |
automáticamente en momentos claves del diálogo, por ejemplo cada vez que |
1597 |
el humor del PNJ cambia, o bien cuando desciende por debajo de un cierto |
el humor del PNJ cambia, o bien cuando desciende por debajo de un cierto |
1610 |
no consigues apartarte lo bastante rápido y el garrotazo te alcanza en |
no consigues apartarte lo bastante rápido y el garrotazo te alcanza en |
1611 |
el cuerpo. |
el cuerpo. |
1612 |
¡Aï! ¡Ese último golpe parece haberte dejado sin respiración!' |
¡Aï! ¡Ese último golpe parece haberte dejado sin respiración!' |
1613 |
\layout Subsection |
\layout Section |
1614 |
|
|
1615 |
Cómo construir una sala |
Cómo construir una sala |
1616 |
\layout Standard |
\layout Standard |
1620 |
En Windows el mejor es el NotePad o clónicos (o incluso el EDIT de MSDOS) |
En Windows el mejor es el NotePad o clónicos (o incluso el EDIT de MSDOS) |
1621 |
mientras que en UNIX o GNU/Linux casi mejor dejarlo al gusto de cada uno. |
mientras que en UNIX o GNU/Linux casi mejor dejarlo al gusto de cada uno. |
1622 |
|
|
1623 |
\layout Subsubsection |
\layout Subsection |
1624 |
|
|
1625 |
Datos generales en toda sala |
Datos generales en toda sala |
1626 |
\layout Standard |
\layout Standard |
1784 |
El nombre debe contener un artículo y empezar por minúscula, ya que será |
El nombre debe contener un artículo y empezar por minúscula, ya que será |
1785 |
mostrado de la forma "Estás en la entrada a Moria". |
mostrado de la forma "Estás en la entrada a Moria". |
1786 |
|
|
1787 |
\layout Subsubsection |
\layout Subsection |
1788 |
|
|
1789 |
La descripción de la sala |
La descripción de la sala |
1790 |
\layout Standard |
\layout Standard |
2110 |
Podéis poner tantos items descriptivos como queráis, con o sin dificultad |
Podéis poner tantos items descriptivos como queráis, con o sin dificultad |
2111 |
pero intentad que el resultado final no sea excesivo o inundaréis de letras |
pero intentad que el resultado final no sea excesivo o inundaréis de letras |
2112 |
la pantalla del jugador (con la consiguiente desgana lectora de éste) |
la pantalla del jugador (con la consiguiente desgana lectora de éste) |
2113 |
\layout Subsubsection |
\layout Subsection |
2114 |
|
|
2115 |
Las salidas en una sala |
Las salidas en una sala |
2116 |
\layout Standard |
\layout Standard |
2275 |
|
|
2276 |
\family typewriter |
\family typewriter |
2277 |
\size footnotesize |
\size footnotesize |
2278 |
<oeste id=moria-cocina01">Cocina</oeste> |
<oeste id="moria-cocina01">Cocina</oeste> |
2279 |
\size default |
\size default |
2280 |
|
|
2281 |
\family default |
\family default |
2465 |
|
|
2466 |
\newline |
\newline |
2467 |
|
|
2468 |
\layout Subsubsection |
\layout Subsection |
2469 |
|
|
2470 |
Propiedades globales de la sala |
Propiedades globales de la sala |
2471 |
\layout Standard |
\layout Standard |
2520 |
ó mucho más si se trata de Minas Tirith pero recomendamos que a partir |
ó mucho más si se trata de Minas Tirith pero recomendamos que a partir |
2521 |
de 200 subdividáis la estancia en varias o incluso convirtáis una zona |
de 200 subdividáis la estancia en varias o incluso convirtáis una zona |
2522 |
con ambiente propio en un área diferente. |
con ambiente propio en un área diferente. |
2523 |
Es decir, es mejor escribir 'mintastirith_ciudad_plaza-norte01' volumen=80 |
Es decir, es mejor escribir 'minastirith_ciudad-plaza01_norte01' volumen=80 |
2524 |
'mintastirith_ciudad_plaza-sur01' volumen=90 que 'mintastirith-plaza' volumen=1 |
'minastirith_ciudad-plaza01_sur01' volumen=90 que 'mintastirith-plaza01' |
2525 |
70. |
volumen=170. |
2526 |
Siempre habrá excepciones, naturalmente, pero se apela al sentido común |
Siempre habrá excepciones, naturalmente, pero se apela al sentido común |
2527 |
del 'maestro de lugares'. |
del 'maestro de lugares'. |
2528 |
Un cuarto corriente estaría entre volumen=6 y volumen=15. |
Un cuarto corriente estaría entre volumen=6 y volumen=15. |
2615 |
Este valor también se tendrá en cuenta a la hora de intentar descubrir |
Este valor también se tendrá en cuenta a la hora de intentar descubrir |
2616 |
personajes escondidos en la sala. |
personajes escondidos en la sala. |
2617 |
|
|
2618 |
\layout Subsubsection |
\layout Subsection |
2619 |
|
|
2620 |
Objetos en la sala |
Objetos en la sala |
2621 |
\layout Standard |
\layout Standard |
2708 |
En cualquier caso, cada objeto tiene un fichero y tendrás que leerte el |
En cualquier caso, cada objeto tiene un fichero y tendrás que leerte el |
2709 |
'como_escribir_un_objeto.txt' para entender del todo cómo funcionan. |
'como_escribir_un_objeto.txt' para entender del todo cómo funcionan. |
2710 |
|
|
2711 |
\layout Subsubsection |
\layout Subsection |
2712 |
|
|
2713 |
Personajes no jugadores (en construcción) |
Personajes no jugadores (en construcción) |
2714 |
\layout Standard |
\layout Standard |
2762 |
El máximo funciona igual que en los objetos. |
El máximo funciona igual que en los objetos. |
2763 |
Luego está la descripción genérica para que sepáis cómo hacer referencia |
Luego está la descripción genérica para que sepáis cómo hacer referencia |
2764 |
a ellos en vuestras acciones de compra-venta, charla o combate. |
a ellos en vuestras acciones de compra-venta, charla o combate. |
2765 |
\layout Subsubsection |
\layout Subsection |
2766 |
|
|
2767 |
Finalmente... |
Finalmente... |
2768 |
\layout Standard |
\layout Standard |
2787 |
|
|
2788 |
\layout Standard |
\layout Standard |
2789 |
|
|
2790 |
ejemplo: moria_salanueva01.xml |
ejemplo: moria-entrada01.xml |
2791 |
\layout Standard |
\layout Standard |
2792 |
|
|
2793 |
Bien, un texto completo quedaría tal que así: |
Bien, un texto completo quedaría tal que así: |
3084 |
\layout Standard |
\layout Standard |
3085 |
|
|
3086 |
------------------------ |
------------------------ |
3087 |
\layout Subsubsection |
\layout Subsection |
3088 |
|
|
3089 |
Consejos |
Consejos |
3090 |
\layout Enumerate |
\layout Enumerate |
3200 |
\SpecialChar ~ |
\SpecialChar ~ |
3201 |
\SpecialChar ~ |
\SpecialChar ~ |
3202 |
<item>Un trozo de camino igual que tantos otros. |
<item>Un trozo de camino igual que tantos otros. |
3203 |
Algo de vegetación y surcos de ruedas en la blanda tierra.</item> |
Algo de vegetación y surcos de |
3204 |
|
\layout Standard |
3205 |
|
|
3206 |
|
|
3207 |
|
\family typewriter |
3208 |
|
\size footnotesize |
3209 |
|
\SpecialChar ~ |
3210 |
|
\SpecialChar ~ |
3211 |
|
\SpecialChar ~ |
3212 |
|
ruedas en la blanda tierra.</item> |
3213 |
\layout Standard |
\layout Standard |
3214 |
|
|
3215 |
|
|
3297 |
Ningún <id> debe contener '.xml' al final. |
Ningún <id> debe contener '.xml' al final. |
3298 |
sólo el fichero en donde se guardan esos datos. |
sólo el fichero en donde se guardan esos datos. |
3299 |
|
|
3300 |
\layout Subsection |
\layout Section |
3301 |
|
|
3302 |
Cómo fabricar un objeto |
Cómo fabricar un objeto |
3303 |
\layout Standard |
\layout Standard |
3313 |
\family default |
\family default |
3314 |
, etc. |
, etc. |
3315 |
|
|
3316 |
\layout Subsubsection |
\layout Subsection |
3317 |
|
|
3318 |
Inicialmente |
Inicialmente |
3319 |
\layout Standard |
\layout Standard |
3355 |
\size footnotesize |
\size footnotesize |
3356 |
<objeto version="1.0" autor="Hirunatan" comentario="una prueba que se me |
<objeto version="1.0" autor="Hirunatan" comentario="una prueba que se me |
3357 |
ha ocurrido" area="poblado"> |
ha ocurrido" area="poblado"> |
3358 |
\layout Subsubsection |
\layout Subsection |
3359 |
|
|
3360 |
Datos generales |
Datos generales |
3361 |
\layout Standard |
\layout Standard |
3389 |
\family typewriter |
\family typewriter |
3390 |
\size footnotesize |
\size footnotesize |
3391 |
<nombre>Pocion recuperadora</nombre> |
<nombre>Pocion recuperadora</nombre> |
3392 |
\layout Subsubsection |
\layout Subsection |
3393 |
|
|
3394 |
Descripción |
Descripción |
3395 |
\layout Standard |
\layout Standard |
3431 |
|
|
3432 |
\newline |
\newline |
3433 |
|
|
3434 |
\layout Subsubsection |
\layout Subsection |
3435 |
|
|
3436 |
Propiedades generales |
Propiedades generales |
3437 |
\layout Standard |
\layout Standard |
3503 |
" cargas="1" valor="10" estado="100"/> |
" cargas="1" valor="10" estado="100"/> |
3504 |
\newline |
\newline |
3505 |
|
|
3506 |
\layout Subsubsection |
\layout Subsection |
3507 |
|
|
3508 |
Usos |
Usos |
3509 |
\layout Standard |
\layout Standard |
4315 |
\family typewriter |
\family typewriter |
4316 |
\size footnotesize |
\size footnotesize |
4317 |
</objeto> |
</objeto> |
4318 |
|
\layout Section |
4319 |
|
|
4320 |
|
Normas de diseño de código fuente en Minë |
4321 |
|
\layout Itemize |
4322 |
|
|
4323 |
|
Es pérdida de tiempo escribir código para que haga cosas en seguida, y luego |
4324 |
|
borrarlo y volverlo a escribir para que haga cosas bien. |
4325 |
|
Esto sólo es válido para hacer prototipos de alguna técnica nueva que aún |
4326 |
|
no se conoce. |
4327 |
|
\layout Itemize |
4328 |
|
|
4329 |
|
Para el resto del código, hay que diseñar primero el interfaz de las clases |
4330 |
|
y luego el código. |
4331 |
|
El interfaz consiste en las declaraciones de clase y de métodos, incluyendo |
4332 |
|
los "doc comments". |
4333 |
|
\layout Itemize |
4334 |
|
|
4335 |
|
Dicho de otra manera, hay que escribir primero el "contrato" de la clase |
4336 |
|
y luego la implementación del contrato (para saber qué significa esto, |
4337 |
|
seguir leyendo). |
4338 |
|
El contrato es la parte más "creativa" de escribir, si está bien hecho, |
4339 |
|
la implementación es casi automática. |
4340 |
|
\layout Subsection |
4341 |
|
|
4342 |
|
Diseño por contrato |
4343 |
|
\layout Enumerate |
4344 |
|
|
4345 |
|
Tipos Abstractos de Datos |
4346 |
|
\begin_deeper |
4347 |
|
\layout Standard |
4348 |
|
|
4349 |
|
Según esta técnica, cada clase representa un Tipo Abstracto de Datos, en |
4350 |
|
el sentido matemático: es decir, una pieza de información, con propiedades |
4351 |
|
(o atributos), y operaciones que realizan cálculos sobre esas propiedades |
4352 |
|
o cambian el valor de las mismas. |
4353 |
|
El interfaz de la clase debe coincidir con el T.A.D., y el resto de la clase |
4354 |
|
debe ser oculto (privado). |
4355 |
|
|
4356 |
|
\layout Description |
4357 |
|
|
4358 |
|
ejemplo una Sala es una habitación o lugar del juego. |
4359 |
|
Sus propiedades son el id, autor, nombre, volumen, personajes que contiene, |
4360 |
|
etc. |
4361 |
|
Sus operaciones son crear una sala nueva, entrar y salir un personaje, |
4362 |
|
etc. |
4363 |
|
\layout Standard |
4364 |
|
|
4365 |
|
En Python, el mapa entre T.A.D. |
4366 |
|
y clase no está perfectamente definido, pero a grosso modo, las propiedades |
4367 |
|
corresponden a los atributos públicos, y las operaciones a las funciones |
4368 |
|
miembro, públicas también. |
4369 |
|
La parte privada de la clase no tiene reflejo en el T.A.D., y no debe ser |
4370 |
|
conocida por ningún otro trozo de código. |
4371 |
|
\layout Description |
4372 |
|
|
4373 |
|
ejemplo Sala.id, Sala.autor, etc. |
4374 |
|
son atributos, y Sala.__init__(), Sala.entrar_personaje(), etc. |
4375 |
|
son funciones miembro. |
4376 |
|
\end_deeper |
4377 |
|
\layout Enumerate |
4378 |
|
|
4379 |
|
Requisitos de las propiedades: dominios e invariantes |
4380 |
|
\begin_deeper |
4381 |
|
\layout Standard |
4382 |
|
|
4383 |
|
Las propiedades deben cumplir una serie de requisitos. |
4384 |
|
Por un lado, el DOMINIO o conjunto de valores que puede tomar (es decir, |
4385 |
|
el tipo: string, int, etc.). |
4386 |
|
\layout Description |
4387 |
|
|
4388 |
|
ejemplo El dominio del id de una Sala son los números enteros (int), el |
4389 |
|
del autor son las cadenas de caracteres (string), etc. |
4390 |
|
\layout Standard |
4391 |
|
|
4392 |
|
En Python, los tipos existen pero no son declarados (es un lenguaje dinámicament |
4393 |
|
e tipado), e incluso una variable puede adoptar valores de distintos tipos. |
4394 |
|
Esto puede ser cómodo en proyectos pequeños, pero en los medianos o grandes, |
4395 |
|
hay que indicar los tipos en el interfaz, y para ello se pueden usar los |
4396 |
|
strings de documentación. |
4397 |
|
Estoy buscando una forma más o menos estándar de hacerlo, pero de momento |
4398 |
|
lo haremos así (si un atributo puede tener distintos tipos, se comenta |
4399 |
|
también, pero no es algo tan frecuente): |
4400 |
|
\layout Standard |
4401 |
|
|
4402 |
|
|
4403 |
|
\family typewriter |
4404 |
|
\size footnotesize |
4405 |
|
> class Sala: |
4406 |
|
\layout Standard |
4407 |
|
|
4408 |
|
|
4409 |
|
\family typewriter |
4410 |
|
\size footnotesize |
4411 |
|
> """<descripción de la clase, una línea> |
4412 |
|
\layout Standard |
4413 |
|
|
4414 |
|
|
4415 |
|
\family typewriter |
4416 |
|
\size footnotesize |
4417 |
|
> |
4418 |
|
\layout Standard |
4419 |
|
|
4420 |
|
|
4421 |
|
\family typewriter |
4422 |
|
\size footnotesize |
4423 |
|
> <descripción más larga> |
4424 |
|
\layout Standard |
4425 |
|
|
4426 |
|
|
4427 |
|
\family typewriter |
4428 |
|
\size footnotesize |
4429 |
|
> |
4430 |
|
\layout Standard |
4431 |
|
|
4432 |
|
|
4433 |
|
\family typewriter |
4434 |
|
\size footnotesize |
4435 |
|
> Contiene los siguientes atributos: |
4436 |
|
\layout Standard |
4437 |
|
|
4438 |
|
|
4439 |
|
\family typewriter |
4440 |
|
\size footnotesize |
4441 |
|
> - id (string): <descripción> |
4442 |
|
\layout Standard |
4443 |
|
|
4444 |
|
|
4445 |
|
\family typewriter |
4446 |
|
\size footnotesize |
4447 |
|
> - luz (int): <descripción> |
4448 |
|
\layout Standard |
4449 |
|
|
4450 |
|
|
4451 |
|
\family typewriter |
4452 |
|
\size footnotesize |
4453 |
|
> [...] |
4454 |
|
\layout Standard |
4455 |
|
|
4456 |
|
|
4457 |
|
\family typewriter |
4458 |
|
\size footnotesize |
4459 |
|
> """ |
4460 |
|
\layout Standard |
4461 |
|
|
4462 |
|
Por otro, las propiedades tienen restricciones o condiciones que deben cumplirse |
4463 |
|
siempre. |
4464 |
|
A estas condiciones se les denomina INVARIANTES. |
4465 |
|
Una instancia cuyas propiedades cumplen todas las invariantes es una instancia |
4466 |
|
válida. |
4467 |
|
NO SE ADMITEN INSTANCIAS NO VÁLIDAS EN NINGÚN MOMENTO, excepto durante |
4468 |
|
la creación de la instancia o la ejecución de una única de sus funciones |
4469 |
|
miembro públicas. |
4470 |
|
A la salida de cualquier función miembro pública, el código debe asegurar |
4471 |
|
que ninguna invariante se ha roto, en ningún caso (esto no es necesario |
4472 |
|
en las privadas). |
4473 |
|
\layout Description |
4474 |
|
|
4475 |
|
ejemplo son invariantes Sala.area != None, aura in range(0,100), n_jugadores |
4476 |
|
>= 0, n_jugadores <= len(personajes), etc. |
4477 |
|
El__init__() debe dar valores a todos los atributos que satisfagan todas |
4478 |
|
las invariantes. |
4479 |
|
No se admite, por ejemplo, crear una sala con area == None, y luego darle |
4480 |
|
un valor más tarde. |
4481 |
|
Sí se admite que el __init__ la inicialice a None y más tarde llame a una |
4482 |
|
función que lee el área de un fichero y actualice el valor, siempre y cuando |
4483 |
|
todo ello ocurra dentro de la ejecución de __init__. |
4484 |
|
\layout Standard |
4485 |
|
|
4486 |
|
En Python no hay ningún mecanismo para expresar invariantes, así que lo |
4487 |
|
haremos también en la documentación. |
4488 |
|
También estoy buscando una forma estándar. |
4489 |
|
De momento será como sigue. |
4490 |
|
Durante la depuración, si se quiere verificar algunas invariantes, se puede |
4491 |
|
usar la instrucción assert justo antes del return de todas las funciones |
4492 |
|
(no hacerlo sistemáticamente con todas, porque puede cargar mucho). |
4493 |
|
\layout Standard |
4494 |
|
|
4495 |
|
|
4496 |
|
\family typewriter |
4497 |
|
\size footnotesize |
4498 |
|
> class Sala: |
4499 |
|
\layout Standard |
4500 |
|
|
4501 |
|
|
4502 |
|
\family typewriter |
4503 |
|
\size footnotesize |
4504 |
|
> """[...] |
4505 |
|
\layout Standard |
4506 |
|
|
4507 |
|
|
4508 |
|
\family typewriter |
4509 |
|
\size footnotesize |
4510 |
|
> [...] |
4511 |
|
\layout Standard |
4512 |
|
|
4513 |
|
|
4514 |
|
\family typewriter |
4515 |
|
\size footnotesize |
4516 |
|
> Invariantes: |
4517 |
|
\layout Standard |
4518 |
|
|
4519 |
|
|
4520 |
|
\family typewriter |
4521 |
|
\size footnotesize |
4522 |
|
> id != None |
4523 |
|
\layout Standard |
4524 |
|
|
4525 |
|
|
4526 |
|
\family typewriter |
4527 |
|
\size footnotesize |
4528 |
|
> aura in range(0,100) |
4529 |
|
\layout Standard |
4530 |
|
|
4531 |
|
|
4532 |
|
\family typewriter |
4533 |
|
\size footnotesize |
4534 |
|
> n_jugadores <= len(personajes) |
4535 |
|
\layout Standard |
4536 |
|
|
4537 |
|
|
4538 |
|
\family typewriter |
4539 |
|
\size footnotesize |
4540 |
|
> [...] |
4541 |
|
\layout Standard |
4542 |
|
|
4543 |
|
|
4544 |
|
\family typewriter |
4545 |
|
\size footnotesize |
4546 |
|
> """ |
4547 |
|
\layout Standard |
4548 |
|
|
4549 |
|
|
4550 |
|
\family typewriter |
4551 |
|
\size footnotesize |
4552 |
|
> |
4553 |
|
\layout Standard |
4554 |
|
|
4555 |
|
|
4556 |
|
\family typewriter |
4557 |
|
\size footnotesize |
4558 |
|
> def entrar_personaje(self, personaje): |
4559 |
|
\layout Standard |
4560 |
|
|
4561 |
|
|
4562 |
|
\family typewriter |
4563 |
|
\size footnotesize |
4564 |
|
> [...] |
4565 |
|
\layout Standard |
4566 |
|
|
4567 |
|
|
4568 |
|
\family typewriter |
4569 |
|
\size footnotesize |
4570 |
|
> assert self.n_jugadores <= len(self.personajes) |
4571 |
|
\layout Standard |
4572 |
|
|
4573 |
|
|
4574 |
|
\family typewriter |
4575 |
|
\size footnotesize |
4576 |
|
> |
4577 |
|
\layout Standard |
4578 |
|
|
4579 |
|
|
4580 |
|
\family typewriter |
4581 |
|
\size footnotesize |
4582 |
|
> def salir_personaje(self, personaje): |
4583 |
|
\layout Standard |
4584 |
|
|
4585 |
|
|
4586 |
|
\family typewriter |
4587 |
|
\size footnotesize |
4588 |
|
> [...] |
4589 |
|
\layout Standard |
4590 |
|
|
4591 |
|
|
4592 |
|
\family typewriter |
4593 |
|
\size footnotesize |
4594 |
|
> assert self.n_jugadores <= len(self.personajes) |
4595 |
|
\end_deeper |
4596 |
|
\layout Enumerate |
4597 |
|
|
4598 |
|
Requisitos de las operaciones: declaración, precondiciones y postcondiciones |
4599 |
|
\begin_deeper |
4600 |
|
\layout Standard |
4601 |
|
|
4602 |
|
Las operaciones también tienen requisitos. |
4603 |
|
Por un lado, está la DECLARACIÓN (el nombre y tipo de los parámetros, y |
4604 |
|
el tipo de valor devuelto). |
4605 |
|
\layout Description |
4606 |
|
|
4607 |
|
ejemplo, la operación "entrar personaje en una sala" tiene un parámetro |
4608 |
|
que es la sala y otro que es el personaje que entra; sus tipos son las |
4609 |
|
clases Sala y Personaje. |
4610 |
|
No devuelve ningún valor. |
4611 |
|
\layout Standard |
4612 |
|
|
4613 |
|
En Python los parámetros vienen explícitos, y los tipos se pueden poner |
4614 |
|
en el comentario, si no son obvios. |
4615 |
|
Pueden ser obvios en los siguientes casos: si el nombre coincide con el |
4616 |
|
de una clase, el tipo es esa clase; si coincide con el de un atributo de |
4617 |
|
la clase actual, el tipo es el mismo que el del atributo; si el tipo es |
4618 |
|
int o string, en muchos casos queda claro con sólo el nombre. |
4619 |
|
Lo mismo con el valor de retorno. |
4620 |
|
\layout Standard |
4621 |
|
|
4622 |
|
|
4623 |
|
\family typewriter |
4624 |
|
\size footnotesize |
4625 |
|
> def entrar_personaje(self, personaje): |
4626 |
|
\layout Standard |
4627 |
|
|
4628 |
|
|
4629 |
|
\family typewriter |
4630 |
|
\size footnotesize |
4631 |
|
> """[...] |
4632 |
|
\layout Standard |
4633 |
|
|
4634 |
|
|
4635 |
|
\family typewriter |
4636 |
|
\size footnotesize |
4637 |
|
> self(Sala) -- obvio, el self siempre está claro |
4638 |
|
\layout Standard |
4639 |
|
|
4640 |
|
|
4641 |
|
\family typewriter |
4642 |
|
\size footnotesize |
4643 |
|
> personaje(Personaje) -- obvio, mismo nombre que clase |
4644 |
|
\layout Standard |
4645 |
|
|
4646 |
|
|
4647 |
|
\family typewriter |
4648 |
|
\size footnotesize |
4649 |
|
> """ |
4650 |
|
\layout Standard |
4651 |
|
|
4652 |
|
|
4653 |
|
\family typewriter |
4654 |
|
\size footnotesize |
4655 |
|
> |
4656 |
|
\layout Standard |
4657 |
|
|
4658 |
|
|
4659 |
|
\family typewriter |
4660 |
|
\size footnotesize |
4661 |
|
> def mensaje_filtrado(self, mensaje, idioma, oyente): |
4662 |
|
\layout Standard |
4663 |
|
|
4664 |
|
|
4665 |
|
\family typewriter |
4666 |
|
\size footnotesize |
4667 |
|
> """[...] |
4668 |
|
\layout Standard |
4669 |
|
|
4670 |
|
|
4671 |
|
\family typewriter |
4672 |
|
\size footnotesize |
4673 |
|
> mensaje(string) -- puede ser obvio, no hay clase mensaje así que |
4674 |
|
\layout Standard |
4675 |
|
|
4676 |
|
|
4677 |
|
\family typewriter |
4678 |
|
\size footnotesize |
4679 |
|
> será un string |
4680 |
|
\layout Standard |
4681 |
|
|
4682 |
|
|
4683 |
|
\family typewriter |
4684 |
|
\size footnotesize |
4685 |
|
> idioma(Idioma) -- obvio, nombre de clase |
4686 |
|
\layout Standard |
4687 |
|
|
4688 |
|
|
4689 |
|
\family typewriter |
4690 |
|
\size footnotesize |
4691 |
|
> oyente(Personaje) -- en principio no es obvio, pero se sabe |
4692 |
|
\layout Standard |
4693 |
|
|
4694 |
|
|
4695 |
|
\family typewriter |
4696 |
|
\size footnotesize |
4697 |
|
> por la descripción del método |
4698 |
|
\layout Standard |
4699 |
|
|
4700 |
|
|
4701 |
|
\family typewriter |
4702 |
|
\size footnotesize |
4703 |
|
> |
4704 |
|
\layout Standard |
4705 |
|
|
4706 |
|
|
4707 |
|
\family typewriter |
4708 |
|
\size footnotesize |
4709 |
|
> Devuelve string -- puede ser obvio también por la descripción |
4710 |
|
\layout Standard |
4711 |
|
|
4712 |
|
|
4713 |
|
\family typewriter |
4714 |
|
\size footnotesize |
4715 |
|
> """ |
4716 |
|
\layout Standard |
4717 |
|
|
4718 |
|
Las PRECONDICIONES son requisitos que hay que cumplir antes de llamar a |
4719 |
|
una operación. |
4720 |
|
Pueden referirse a los parámetros de la operación o a las propiedades de |
4721 |
|
la clase. |
4722 |
|
Su comprobación es responsabilidad del código llamante (lo puede hacer |
4723 |
|
bien explícitamente, con algún if, o bien apoyandose en una invariante |
4724 |
|
o postcondición). |
4725 |
|
La función debe asumir que las precondiciones se cumplen, y no debe volverlas |
4726 |
|
a chequear. |
4727 |
|
Así se asegura que cada chequeo se realiza sólo una vez, y se evitan redundanci |
4728 |
|
as. |
4729 |
|
\layout Description |
4730 |
|
|
4731 |
|
ejemplo, la sala tiene una invariante que dice que el aura es mayor que |
4732 |
|
0. |
4733 |
|
Si el constructor lee los datos de la sala de un fichero, al leer el aura |
4734 |
|
debe comprobar que cumple la invariante, y si no, dar un error y no crear |
4735 |
|
la sala. |
4736 |
|
A partir de ahí, todo el resto del código asume que el aura es mayor que |
4737 |
|
0, y se puede pasar como parámetro a una función que tenga esto como precondici |
4738 |
|
ón. |
4739 |
|
\layout Standard |
4740 |
|
|
4741 |
|
En Python las precondiciones las colocaremos en el texto del comentario, |
4742 |
|
de la |
4743 |
|
\layout Standard |
4744 |
|
|
4745 |
|
siguiente manera. |
4746 |
|
Durante la depuración, también se puede usar assert para |
4747 |
|
\layout Standard |
4748 |
|
|
4749 |
|
comprobar algunas precondiciones, justo al principio de la función: |
4750 |
|
\layout Standard |
4751 |
|
|
4752 |
|
|
4753 |
|
\family typewriter |
4754 |
|
\size footnotesize |
4755 |
|
> def salir_personaje(self, personaje): |
4756 |
|
\layout Standard |
4757 |
|
|
4758 |
|
|
4759 |
|
\family typewriter |
4760 |
|
\size footnotesize |
4761 |
|
> """[...] |
4762 |
|
\layout Standard |
4763 |
|
|
4764 |
|
|
4765 |
|
\family typewriter |
4766 |
|
\size footnotesize |
4767 |
|
> Requiere: |
4768 |
|
\layout Standard |
4769 |
|
|
4770 |
|
|
4771 |
|
\family typewriter |
4772 |
|
\size footnotesize |
4773 |
|
> personaje != None |
4774 |
|
\layout Standard |
4775 |
|
|
4776 |
|
|
4777 |
|
\family typewriter |
4778 |
|
\size footnotesize |
4779 |
|
> personaje in self.personajes.values() |
4780 |
|
\layout Standard |
4781 |
|
|
4782 |
|
|
4783 |
|
\family typewriter |
4784 |
|
\size footnotesize |
4785 |
|
> [...] |
4786 |
|
\layout Standard |
4787 |
|
|
4788 |
|
|
4789 |
|
\family typewriter |
4790 |
|
\size footnotesize |
4791 |
|
> """ |
4792 |
|
\layout Standard |
4793 |
|
|
4794 |
|
|
4795 |
|
\family typewriter |
4796 |
|
\size footnotesize |
4797 |
|
> assert personaje in self.personajes.values() |
4798 |
|
\layout Standard |
4799 |
|
|
4800 |
|
Las POSTCONDICIONES son requisitos que una operación se compromete a asegurar |
4801 |
|
que se cumplen una vez que la misma haya terminado con éxito. |
4802 |
|
Pueden referirse a las propiedades de la clase o al valor de retorno, si |
4803 |
|
lo hay. |
4804 |
|
El código llamante no debe volverlos a chequear. |
4805 |
|
En cierta forma, las postcondiciones representan la información semántica |
4806 |
|
de la operación (su utilidad prevista), frente a la información sintáctica |
4807 |
|
de la declaración. |
4808 |
|
\layout Description |
4809 |
|
|
4810 |
|
ejemplo, la operación salir personaje de una sala asegura que si se completa |
4811 |
|
con éxito, el personaje ya no está dentro de la sala. |
4812 |
|
\layout Standard |
4813 |
|
|
4814 |
|
En Python, se colocan de forma similar a las precondiciones. |
4815 |
|
Si se usa el assert, se puede poner justo antes de volver, o en el código |
4816 |
|
llamante justo después de hacer la llamada: |
4817 |
|
\layout Standard |
4818 |
|
|
4819 |
|
|
4820 |
|
\family typewriter |
4821 |
|
\size footnotesize |
4822 |
|
> def salir_personaje(self, personaje): |
4823 |
|
\layout Standard |
4824 |
|
|
4825 |
|
|
4826 |
|
\family typewriter |
4827 |
|
\size footnotesize |
4828 |
|
> """[...] |
4829 |
|
\layout Standard |
4830 |
|
|
4831 |
|
|
4832 |
|
\family typewriter |
4833 |
|
\size footnotesize |
4834 |
|
> Asegura: |
4835 |
|
\layout Standard |
4836 |
|
|
4837 |
|
|
4838 |
|
\family typewriter |
4839 |
|
\size footnotesize |
4840 |
|
> personaje not in self.personajes.values() |
4841 |
|
\layout Standard |
4842 |
|
|
4843 |
|
|
4844 |
|
\family typewriter |
4845 |
|
\size footnotesize |
4846 |
|
> """ |
4847 |
|
\end_deeper |
4848 |
|
\layout Enumerate |
4849 |
|
|
4850 |
|
El contrato |
4851 |
|
\begin_deeper |
4852 |
|
\layout Standard |
4853 |
|
|
4854 |
|
El conjunto de requisitos de propiedades y operaciones se conoce como el |
4855 |
|
CONTRATO del T.A.D. |
4856 |
|
Se llama así porque se asemeja a un contrato real: existe un proveedor |
4857 |
|
(la clase), clientes (cualquiera que lea sus propiedades o use sus operaciones) |
4858 |
|
y cláusulas (los requisitos). |
4859 |
|
\layout Standard |
4860 |
|
|
4861 |
|
Igual que en un contrato real, cada parte se compromete a cumplir su obligación, |
4862 |
|
y hay un sistema para tratar los incumplimientos. |
4863 |
|
El cliente se compromete a asegurar las precondiciones. |
4864 |
|
Si no se puede cumplir alguna de ellas, no debe llamar a la operación en |
4865 |
|
ningún caso. |
4866 |
|
Una función no debe añadir código para protegerse contra precondiciones |
4867 |
|
no cumplidas (puede permitirse incluso dejar el ordenador colgado o matar |
4868 |
|
el programa si quiere), ya que nunca se va a dar el caso cuando el programa |
4869 |
|
esté depurado (durante la depuración se puede usar assert). |
4870 |
|
\layout Standard |
4871 |
|
|
4872 |
|
El constructor de la clase debe asegurar todas las invariantes. |
4873 |
|
Si no es posible cumplir alguna de ellas, debe lanzar una EXCEPCIÓN y abortar |
4874 |
|
la creación de la instancia. |
4875 |
|
En ese caso el cliente debe tirar la instancia a medias sin usarla. |
4876 |
|
\layout Standard |
4877 |
|
|
4878 |
|
Finalmente, las operaciones de la clase se comprometen a verificar tanto |
4879 |
|
las invariantes como las postcondiciones. |
4880 |
|
Si no pueden cumplir alguna, se debe lanzar una EXCEPCIÓN. |
4881 |
|
En ese caso, puede que algunas postcondiciones estén cumplidas y otras |
4882 |
|
no (no se puede asegurar), pero al menos la instancia tiene que seguir |
4883 |
|
siendo válida y la operación tiene que restaurar todas las invariantes |
4884 |
|
que puedan estar temporalmente deshabilitadas. |
4885 |
|
\layout Standard |
4886 |
|
|
4887 |
|
Las excepciones no son un mecanismo de control de flujo. |
4888 |
|
Sólo deberían ocurrir en caso de incumplimiento de invariantes o postcondicione |
4889 |
|
s, y en casos excepcionales (tipo disco duro lleno, datos corruptos, versiones |
4890 |
|
incompatibles, etc.). |
4891 |
|
Para situaciones que puedan ocurrir en una ejecución normal del programa |
4892 |
|
(por ejemplo, el usuario introduce un nombre que no existe, se ha llegado |
4893 |
|
al final de una lista, etc.) es mejor usar condiciones explícitas (con if, |
4894 |
|
while, etc.). |
4895 |
|
Del mismo modo, las excepciones sólo se deben capturar en dos casos: cuando |
4896 |
|
haya que restaurar alguna invariante, y luego seguir pasando la excepción |
4897 |
|
hacia arriba, o cuando se llegue a un punto en el que se pueda volver a |
4898 |
|
intentar la operación. |
4899 |
|
En particular está prohibido capturar una excepción y luego hacer return |
4900 |
|
normal, devolviendo un valor falso o que no cumple las postcondiciones. |
4901 |
\the_end |
\the_end |