La forma que más memoria ahorra con las fuentes es usar LOAD ""CODE
Elaborando un poco el tema... La norma 4 yo diría que está mal del todo. La norma debería decir:
4) NUNCA DEFINAS BINARIOS EN BASIC...
Meter un montón de DATAs y las instrucciones que las cargan en memoria ocupa un montón de BASIC que podrías usar para otras cosas. En el caso concreto de Vindius, son como 2K. Comparado con un simple LOAD "" CODE (4 bytes, 8 bytes si va solo en una línea) el ahorro es brutal.
4a) ...PERO PUEDES INCRUSTARLOS EN LÍNEAS REM
Es una técnica que se usa en algunos cargadores de juegos. Las ventajas son ahorrarse ese LOAD ""CODE y no necesitar el uso de CLEAR para reservar memoria al código.
El problema (y gordo) es que una vez hecho esto, el BASIC pasa a ser casi ilegible.
En el caso del Vindius, los DATA de la línea 132 también son buenos candidatos a cargarlos como CODE (en cuyo caso tendrías que leerlos con PEEK). Los BEEP del principio (línea 16) son otra cosa, ya que no son enteros (ese 0.3 no puede codificarse en un solo byte).
Otros cambios y sugerencias...
1) USO DE VARIABLES PARA ELEMENTOS QUE SE REPITEN MUCHO
Además de para las frases, puedes utilizarlo para números. Por ejemplo, LET z=0 ocupa 8 bytes, pero usar z a posteriori te ocupará solo 1. Cero y uno son bastante comunes, puedes ahorrar montones de bytes con ellos.
5) USO DE EXPRESIONES PARA AHORRAR MEMORIA
Viejo conocido cuando andas muy escaso de memoria, en realidad intercambias memoria de BASIC por uso del calculador. El ejemplo más típico es usar NOT PI en vez de 0, ahorras 3 bytes. Combinado con la anterior, podrías usar estas dos instrucciones
LET Z=NOT PI: LET U=PI/PI y ahorrar mucha memoria cada vez que necesites un cero o un uno suelto.
Otro ejemplo (discutible) se puede usar jugando con tu ejemplo del monstruo y el hacha:
Código: Seleccionar todo
10 PRINT "Te encuentras con un mostruo horrible, ¿qué vas a hacer) 1) Ataca con espada 2) Ataca con hacha 3) Ataca con lanza"
20 INPUT A
30 IF A=1 THEN GO TO 100
40 IF A=2 THEN GO TO 150
50 IF A=3 THEN GO TO 150
100 PRINT "Enhorabuena derrotas al monstro"
150 PRINT "El monstruo te ha matado"
Si lo modificas a algo así, se ahorra "algo" de memoria a cambio de mayor complejidad:
Código: Seleccionar todo
10 PRINT "Te encuentras con un mostruo horrible, ¿qué vas a hacer) 1) Ataca con espada 2) Ataca con hacha 3) Ataca con lanza"
20 INPUT A
30 GO TO 50*A+50
100 PRINT "Enhorabuena derrotas al monstro"
200 PRINT "El monstruo te ha matado"
Al evaluar A, el Spectrum saltará a las líneas 100, 150 (que no existe) y 200, ahorrándote las líneas 40 y 50. El problema de esta técnica es que tienes que ordenar el código bien y que va a ser incompatible con los renumeradores de líneas (que no evalúan ni sustituyen expresiones). En este caso, puede que la mayor complejidad no compense.
Por último, recordar que cada número "a pelo" va acompañado por otros 5 bytes que lo expresan en coma flotante. Usando la expresión VAL "60000" (por ejemplo", el número 64000 deja de tener esa coletilla. Poner VAL por todas partes es un peñazo, aunque ahorras algunos bytes, y tiene la pega de que necesita memoria en el calculador. Si tienes un CLEAR muy bajo, puede que usar VAL haga que casque el programa.
Eso sí, en algunos casos puede ahorrar bastante memoria. En la línea 129, la expresión 1/51 ocupa 16 bytes, mientras que VAL "1/51" ocuparía solo 7.
6) PRECARGA DE VARIABLES
Otra técnica compleja, a usar en combinación con la técnica 1 y únicamente si no vas a usar CLEAR en todo el programa.
En un Spectrum, las variables nunca se borran hasta que sucede un CLEAR o un RUN (lógico). Otro asunto interesante es que SAVE no graba el programa, sino el programa y las variables que estuvieran definidas en ese momento. De manera que yo podría hacer una "burrada" tal que esta...
Código: Seleccionar todo
10 LET a$ = "Pulsa X para continar"
20 LET b$ = "¿Qué camino vas a elegir"
30 LET c$ = Recuerdos de Constantinopla
40 STOP
50 REM El programa real empieza aquí
En las líneas 10 a 30 se definen las variables, y la línea 40 para el programa con las variables ya definidas. La línea 50 y posteriroes serían tu aventura.
En este punto ejecuto el programa que acaba con un STOP. Ahora borro las líneas 10 a 40 y hago un SAVE. El programa que he grabado tendrá en memoria a$, b$ y c$ pero no habré gastado ni un byte de BASIC en definirlas, ahorrándome unos cuantos bytes más.
7) NO HAGAS OPERACIONES QUE NO NECESITAS
Concretamente, mirando la línea 2 del Vinius:
Código: Seleccionar todo
2 POKE 23606,64000-256*INT(64000/256): POKE 23607, INT (64000/256)
Esta forma de calcular POKEs está muy bien si partes de una variable, pero no si es una constante. Es algo que podrías haber hecho con una calculadora y ahorrarte bytes. Resumiendo, esta línea debería ser la siguiente:
Los valores los he calculado con una calculadora, y con eso me he ahorrado (a bulto) unos 50 bytes. Lo mismo pasa en las líneas 128 y 129 (las que calculan ciertas constantes para los BEEP). En el caso de la línea 129 LET MININ=1/(51+0) el cero sobra y podría haberse puesto como 129 LET MININ=1/51 (te ahorras los paréntesis, el cero y su representación en coma flotante).
Otros caso es la línea 101 (hay más como esta) que tiene un PRINT "";F$;"detuvo a...". Estás imprimiento una cadena vacía. Esto es equivalente a PRINT F$;"detuvo a..." y te ahorras 3 bytes (las dos comillas y el punto y coma).
SUBRUTINAS
Si tienes conjuntos de operaciones que se repiten constantemente (p.ej.: esos conjuntos CLS:PRINT:PAUSE) quizás puedas ahorrar algo usando GO SUB.
En el caso concreto del Vindius, "arreglar" esos PRINT para convertirlos en variables y pasarlos a las rutinas GOSUB haría que el programa resultante ocupara más espacio (por los códigos de control)... no merece la pena.