En el código fuente de Secret Valley (Sinclair BASIC interpretado) he empleado los siguientes códigos de colores:
Este juego, programado íntegramente en BASIC, fue publicado hacia agosto de 1982 por Newsoft Products, véase la ficha en SpectrumComputing.
Se trata de un programa de muy primera hora (el ZX Spectrum había sido lanzado al mercado en abril de 1982) y junto a The Valley es un temprano ejemplo de proto-RPG gráfico (frente a los proto-RPG que empleaban interfaces de texto estilo aventura conversacional) en el Spectrum.
El juego presenta una perspectiva 2D top-down en una única pantalla sin scroll.
verde , salidas/entradas de saltos GO TO/ GO SUB spaguetti-like;
azul , salidas/entradas de subrutinas GO SUB claramente estructuradas y encapsuladas;
rojo , salidas entradas de saltos calculados.
Los números de línea seguidos del símbolo " ? " significan puntos de entrada teóricos desde saltos GO TO que no tienen número de línea real en el listado, por lo que el intérprete simplemente busca la línea siguiente.
1 LET l3=20
2 FOR n=0 TO 7 3 READ r: POKE USR "U"+n,r 4 NEXT n 5 DATA 33,2,116,120,112,32,32,248
6 FOR n=0 TO 6 STEP 2: POKE USR "B"+n,85: POKE USR "B"+n+1,170: NEXT n 9 BORDER 5: PAPER 6: INK 9 10 LOAD "SV" SCREEN$ #Carga fondo (escenario) 15 GO SUB 9010 #Sub clearbox_&_BEEP 35 GO TO 9100 #TO input_name
El código es bastante simple y entendible. Inicializa alguna variable y define algunos UDG, carga la pantalla que sirve de escenario, ejecuta la subrutina clearbox_&_BEEP y salta a input_name, desde, tras varias peripecias, salta a la línea 60 (que no existe).
60?
80? 88 PRINT AT a,b; INK 2; BRIGHT 1;"U" 90 PRINT AT 17,0;"N,S,E,W?": BEEP .5,40 92 LET aa=a: LET bb=b 94 INPUT b$ 96 IF (b$<>"n" AND b$<>"s" AND b$<>"e" AND b$<>"w") THEN GO TO 94 97 IF tw=1 THEN GO TO 99 98 LET a=a+(b$="s" AND a<=14)-
(b$="n" AND a>=2) 99 LET b=b+(b$="e" AND b<=29)-
(b$="w" AND b>=2) 100 IF tw=1 THEN LET x=95 101 PRINT AT aa,bb;CHR$ x: POKE (22528+(32*aa+bb)),xx 102 LET x= CODE SCREEN$ (a,b): LET xx=ATTR (a,b) 103 IF tw=0 THEN GO TO 106 104 IF tw=1 AND T(3)=1 AND a=2 AND b=7 THEN GO TO 9600 #TO end_win 105 IF x=46 THEN
LET a=a-2: PRINT AT a+2,b;"_" 106 PRINT AT a,b; INK 2; BRIGHT 1;"U" 107 GO SUB 111: #Sub main_sub GO SUB 9900: #Sub BORDER_&_BEEP PRINT AT 18,0;s$: LET s$="" 110 GO SUB 9900: #Sub BORDER_&_BEEP GO TO 90 #TO main(loop)
El bucle principal. Hasta aquí llegamos desde varios puntos del programa. Si es desde el inicio, llega tras pedir al usuario que introduzca su nombre y ejecutar algunas otras subrutinas. Presenta al jugador el input para que introduca un movimiento (líneas 90-94) .
111? 112 IF x=94 THEN LET s$="You are not safe in the forests!" 114 IF x=58 THEN LET s$="Beware of Sprites and Kraken! " 116 IF x=32 THEN LET s$="You are not safe on the plains. " 118 IF x=119 THEN LET s$="swim quickly,you are in danger!" 120 IF x=127 THEN LET s$="dark beasts await in the CAVERNS" 122 IF x=64 THEN LET s$="all may be lost in the GREY KEEP" 124 IF x=33 THEN GO TO 5000 #TO dark_tower 126 IF x=84 THEN LET s$="NO SANCTUARY IN THIS TEMPLE!! " 127 PRINT AT 18,0; PAPER 5; INK 9;s$ 129 LET R=INT (RND*10)+1 130 IF R>7 THEN GO TO 500 #TO finds 132 IF R>4 THEN RETURN
Presenta un texto en función del suelo sobre el que está el usuario. Comprube si estamos en dark_tower y emplea RND para tesoros encontrados en la casilla y para continuar hasta encounter o regresar a main.
140 RESTORE 150: FOR n=1 TO INT (RND*9)+1: READ l$: NEXT n 150 DATA "a Hob-Goblin","a Balrog","a Harpy","a Rock Troll","a Wyvern",
"a Kraken","a Wraith","a Barrow Wight","a Fire Dragon"
200 GO SUB 9010 #Sub clearbox_&_BEEP 202 PRINT AT 17,0;"You are in trouble now.........."
204 RESTORE 206: FOR n=1 TO INT (RND*6)+1: READ j$: NEXT n 206 DATA "smelt","heard","seen","tasted","felt","esped"
220 PRINT PAPER 0; INK 9;"Your approach has been ";j$ 222 PRINT PAPER 0; INK 9;"by ";l$ 250 PRINT AT 21,0;"ATTACK OR RETREAT?" 252 INPUT k$ 253 LET l3=20: GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 254 IF k$(1)="a" THEN GO TO 1000 #TO attack 256 PRINT AT 17,0; PAPER 6; INK 9;"Knavish coward,thee will suffer!" 257 LET RT=RT-1 258 IF RT<=1 THEN
LET RT=1 259 LET COW=COW+1 260 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 262 IF COW<=20 THEN GO TO 400 #TO rating 263 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 264 GO TO 7000 #end_lose
265 FOR c=1 TO 3 267 LET R=INT (RND*4)+1 270 GO TO 270+2*R 272 LET F$="YOU MISSED IT!": GO TO 290 274 LET F$="YOU HAVE HURT IT!": GO TO 290 276 LET F$="A HIT,BUT LITTLE DAMAGE!": GO TO 290 278 LET F$="A SMASHING BLOW!": GO TO 290
290 LET R=INT (RND*6)+1: GO TO 292+2*R
294 LET G$="IT SWINGS AT YOU AND MISSES!": GO TO 310 296 LET G$="YOUR BLADE DEFLECTS IT'S ATTACK!": GO TO 310 298 LET G$="IT HESITATES,UNSURE": GO TO 310 300 LET G$="IT STRIKES YOUR HEAD!": GO TO 310 302 LET G$="A SLASH TO YOUR THIGH!": GO TO 310 304 LET G$="A DESPERATE PSI BLAST!": GO TO 310
310 LET R=INT (RND*2)+1: GO TO 310+2*R
312 LET R$="STAGGERING": GO TO 350 314 LET R$="WEAKER": GO TO 350 350 GO SUB 9900 #Sub BORDER_&_BEEP 352 PRINT AT (RND*4)+17,0;F$ 354 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 356 PRINT AT (RND*4)+17,0;G$ 358 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 360 PRINT AT (RND*4)+17,0;R$ 362 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 364 IF RND<.05 THEN GO TO 7000 #TO end_lose 366 NEXT c 368 GO SUB 9900 #Sub BORDER_&_BEEP 370 PRINT AT 17,0;"SUCCESS! THE ";L$(3 TO ) 372 PRINT "HAS USED IT'S LAST ENERGY IN TRYING TO KILL YOU,
AND DIED IN THE ATTEMPT." 374 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 376 GO SUB 9900 #Sub BORDER_&_BEEP 378 PRINT AT 17,0;"BEWARE,THERE ARE OTHER MONSTERS NEARBY!" 379 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 380 LET M=M+1 382 GO SUB 9900 #Sub BORDER_&_BEEP 390 LET RT=INT (M/2)+1
Subrutina para el resultado del combate, si el jugados no ha muerto continua hasta rating.
400 REM RATING 401 IF RT<=1 THEN LET RT=1 402 IF RT>=20 THEN LET RT=20 403 LET L=450 404 GO TO 404+RT*2 406 LET A$="MONSTER FODDER": GO TO L
408? 410 LET A$="PATH WALKER": GO TO L
412? 414 LET A$="ADVENTURER": GO TO L
416? 418 LET A$="SWORD MASTER": GO TO L
420? 422 LET A$="SUPERHERO": GO TO L
424? 426 LET A$="KNIGHT OF THE VALLEY": GO TO L
428? 430 LET A$="GUARDIAN OF THE VALLEY": GO TO L
432?
434?
436?
438?
440?
442? 444 LET A$="MASTER OF DESTINY": GO TO L 450 GO TO 9500 #TO print_stats
500 REM FINDS 501 LET L=540 502 LET R=INT (RND*8)+1: GO TO 504+2*R
506 LET S$="A CIRCLE OF EVIL,DEPART IN HASTE": LET TR=ABS (TR*.9): GO TO L 508 LET S$="A PRECIOUS HOARD OF DRAGON GOLD!": LET TR=TR+500: GO TO L 510 LET S$="AN AURA OF DEEP MAGIC SURROUNDS.": LET TR=TR+50: GO TO L 512 LET S$="A HOARD OF SILVER COINS.": LET TR=TR+150: GO TO L 514 LET S$="A PLACE OF ANCIENT POWER.": LET TR=TR+50: GO TO L 516 LET S$="A TROVE OF GLEAMING DIAMONDS.": LET TR=TR+100: GO TO L 518 LET S$="A RUBY NECKLACE.": LET TR=TR+100: GO TO L 520 LET S$="AN EVIL PLACE,BEWARE!.": LET TR=TR-250: GO TO L 540 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 542 GO SUB 9010 #Sub clearbox_&_BEEP 545 PRINT AT 18,0; PAPER 5; INK 9;s$ 550 IF TR<=0 THEN LET TR=0 551 IF RND<.8 THEN RETURN 552 IF T(1)=6 THEN GO TO 560 554 LET S$="LUCK AT LAST! A SPELLSTONE! " 556 LET T(1)=T(1)+1 558 GO TO 600 560 IF T(2)=1 THEN GO TO 570 562 LET S$=" YOU HAVE THE SWORD OF POWER! " 564 LET T(2)=1 566 GO TO 600 570 IF RND<.1 THEN GO TO 60 #TO main 572 IF T(3)=1 THEN GO TO 60 #TO main 574 LET T(3)=1 576 LET S$="YOU HAVE FOUND THE CROWN OF LIFE" 578 GO TO 600 600 LET TR=TR-100*(T(1)+T(2)+T(3)) 610 PRINT AT 18,0;s$ 615 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP] 620 GO SUB 9010 #Sub clearbox_&_BEEP 630 GO TO 9500 #TO print_stats
1000 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP]1010 PRINT AT 17,0;"SWORD,MAGIC,OR BRIBE?"1015 PRINT AT 21,0;"S,M,B"1020 INPUT B$: GO SUB 9900 #Sub BORDER_&_BEEP1022 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP]1025 IF B$="s" THEN GO TO 265 #TO fight1030 IF B$="m" THEN GO TO 1100 #TO magic1035 IF B$="b" THEN GO TO 1050 #TO bribe1040 GO TO 1000 #TO attack(loop)
1050 REM bribe 1055 PRINT AT 17,0; PAPER 2; INK 9;"To bribe this monster you will have too
offer ",;rt*500;" Gold pieces","y/n?"1060 INPUT B$ 1065 IF B$="n" THEN GO TO 1000 #TO attack1070 IF B$="y" THEN GO TO 10801075 GO TO 10601080 IF tr=0 THEN GO TO 10821081 IF TR>=rt*1000 THEN GO TO 10901082 PRINT "Thou haste not the wherewithal."1085 BEEP 1,-101087 GO TO 1000 #TO attack1090 LET TR=TR-(rt*1000)1095 GO TO 9500 #TO print_stats
1100 REM magic 1105 IF T(1)>=1 THEN GO TO 11201110 PRINT AT 17,0; PAPER 4; INK 9;"Thou art a poor magician,lackingspells,wit
and wherewithal."1112 PAUSE 1001115 GO TO 1000 #TO attack1120 LET T(1)=T(1)-11125 PRINT AT 17,0;"THE INFALLIBLE ";N$;,"WINS AGAIN"1130 BEEP 1,-151135 LET rt=rt+11140 GO TO 400 #TO rating
5000 REM dark tower 5002 IF T(3)=1 THEN GO TO 5010 #TO dark_tower_in5005 PRINT AT 17,0;"Thou needs both SWORD OF POWER and CROWN OF LIFE to enter
the DARK TOWER. BEGONE!"5006 BEEP 2,-255007 LET rt=rt-1: IF rt<=1 THEN LET rt=15008 GO TO 9500 #TO print_stats
5010 CLS5015 PRINT AT 10,5;"Welcome to the DARK TOWER"5020 PAUSE 1005025 CLS5030 PRINT AT 10,0;"FROM WHICH THERE IS NO ESCAPE!"5035 PAUSE 1005040 CLS5050 LET tw=15100 PRINT " \:. \.:\:. \.:\:. \.:\:. \.:\:. \.:"5110 FOR i=1 TO 3: PRINT " \ :\::\:. \''\''\''\''\''\''\''\''\''\''\''\::\: ": PRINT " \::\::\::\:."; INK 8;".___________";"\::\::": PRINT " \ :\::\::\::\::\''\''\''\''\''\''\''\''\'' \.:\::\::\: ": PRINT " \ :\::__________.\.:\::\::\: ": NEXT i 5120 PRINT "\t\t\t\.:\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\:.
\t\t\t\t\t\t\t\t\t\t\t\t"5130 LET a=12:\ LET b=105135 LET x=955138 LET s$=""5140 GO TO 80 #TO main
7000 REM lose 7001 GO SUB 9010 #Sub clearbox_&_BEEP7002 PRINT AT 17,0;"You were warned when you entered
The SECRET VALLEY that
you mightnot live long."7003 BEEP 4,-307004 PRINT AT 21,10;"YOU DIDN'T"7005 BEEP 1.5,-407007 IF tw=1 THEN NEW 7008 GO SUB 9010 #Sub clearbox_&_BEEP7009 PRINT AT a,b;CHR$ x: POKE (22528+(32*a+b)),xx 7010 GO TO 9100 #TO input_name
Subrutina al terminar el juego perdiendo. Salta a input_name y empieza de nuevo.
9000?9002 FOR i=1 TO 10: BEEP .025,INT (RND*30)-20: NEXT i 9010?9011 FOR i=17 TO 21: BEEP .05,i: PRINT AT i,0;" ": NEXT i 9014 RETURN
Hasta aquí un grupo de subrutinas.
9100 PRINT AT 17,0;"WHAT IS THY GIVEN NAME?"9102 INPUT N$ 9104 IF N$="" THEN GO TO 91009106 LET R=INT (RND*3)+1: GO TO 9106+r*2 9108 LET C$="WIZARD": GO TO 91209110 LET C$="THINKER": GO TO 91209112 LET C$="BARBARIAN": GO TO 91209114 LET C$="WARRIOR" 9120?9122 LET RT=1: LET A$="MONSTER FODDER"9123 LET COW=09124 LET M=09125 DIM T(3)9126 LET xx=40: LET x=329127 LET TR=09128 LET a=2: LET b=a 9129 LET tw=09130 GO SUB 9500 #Sub print_stats9140 GO TO 60 #TO main
9500 GO SUB 9010 #Sub clearbox_&_BEEP9501 PRINT AT 17,0;N$;" THE ";C$ 9502 PRINT A$ 9503 IF tr<=0 THEN LET tr=09504 PRINT "TREASURE ";tr 9505 PRINT "MONSTERS KILLED ";M 9506 PAUSE 100: GO SUB 9010 #Sub clearbox_&_BEEP9507 PRINT AT 17,0;"SPELLSTONES ";T(1)9508 PRINT "SWORDS OF POWER ";T(2)9510 PRINT "CROWNS OF DESTINY ";T(3)9512 GO SUB 9000 #Sub BEEP_&[clearbox_&_BEEP]9514 GO SUB 9010 #Sub clearbox_&_BEEP9516 IF T(3)=1 THEN GO TO 9600 #TO end_win9520 RETURN
9600 CLS9605 PRINT AT 10,0; PAPER 2; INK 0; FLASH 1;"THOU HASTE FULFILLED THY QUEST!"9610 LET l3=60: GO SUB 9900 #Sub BORDER_&_BEEP9620 FOR i=20 TO 1 STEP -1: BEEP .1,i: NEXT i 9630 GO TO 9610
Subrutina al terminar el juego ganando.
9900 LET l2=-INT (RND*40)+1: FOR i=l2 TO l2+l3/2: BORDER RND*6+1: BEEP .025,i: BEEP .025,INT (RND*10): NEXT i 9910 RETURN9990 STOP