Conquest is a turn-based strategy game loader and front-end menu system that manages game setup, saving, loading, map editing, and commander statistics tracking. The program uses a series of machine code routines loaded from an external CODE file (“conque.C1”), with RANDOMIZE USR calls at addresses such as 59950, 60000 (6E4), 53500, and two stored in variables ky and kz to invoke gameplay logic. Player names are encoded into memory starting at address 31514 using a delimiter scheme where the last character of each name has 128 (kh) added to its ASCII code to mark boundaries. A commander hall-of-fame system tracks up to 20 players across games, recording games played, wins, and win percentage in DIM arrays that persist between sessions via the game save/load CODE mechanism.
Program Structure
The program is organized as a dispatcher menu at lines 1–10, with numbered subroutine blocks handling each menu option:
| Lines | Function | Menu Option |
|---|---|---|
| 100–199 | New Game setup | 1 |
| 200–210 | Load Game | 2 |
| 300–399 | Save Game | 3 |
| 400–499 | Map Editor | 4 |
| 500–505 | Save Map | 5 |
| 600–620 | View Commanders | 6 |
| 800–891 | Game-end / winner determination | (internal) |
| 999 | Stats display subroutine | (internal) |
Dispatch is handled at line 9 with GO SUB a*kc, where kc is a constant representing 100, so each menu selection (1–6) maps to a subroutine at a multiple of 100. Option 7 simply executes STOP.
Symbolic Constants via Short Variable Names
The program makes heavy use of single-letter or two-letter variables as numeric constants, a common technique to shorten tokenized BASIC lines and reduce memory usage. Based on context, the inferred mappings are:
k0= 0k1= 1k2= 2k3= 3k5= 5k9= 9kc= 100kh= 128 (used as a name-delimiter marker)kl= 21 (screen rows)km= address of the music-on/off flag in machine codekw= map start address (checked against 16 for city verification)kx= line number for the game launch jump targetky,kz= USR addresses for machine code entry points
These constants are presumably set by the loaded machine code block or a prior initialization section not shown here.
Machine Code Integration
Line 1 POKEs addresses 23730–23731 to relocate or configure the system channel, then immediately loads the machine code file conque.C1. Multiple RANDOMIZE USR calls throughout invoke machine code routines:
RANDOMIZE USR ky— called in both the Map Editor (line 400) and game-end handler (line 800)RANDOMIZE USR VAL "6E4"— shorthand for address 60000, in the Map Editor block (line 405)RANDOMIZE USR VAL "59950"— gives computer players map knowledge during New Game (line 151)RANDOMIZE USR 53500— called at game-end (line 805)RANDOMIZE USR kz— called in both Map Editor and game-end blocks
The use of VAL "6E4" (scientific notation) to express 60000 is a memory-saving trick: the tokenized number literal 60000 takes more bytes than the short string "6E4".
Player Name Encoding
Lines 112–118 implement a compact encoding scheme for storing player names into a contiguous memory block starting at address 31514. The last character of each name has 128 added to its ASCII code (using constant kh), acting as an end-of-name delimiter. This allows the machine code to parse variable-length names without storing explicit length bytes. Lines 825–855 reverse this process, reconstructing a$, b$, and c$ by scanning the block and detecting the high-bit marker.
Commander Hall of Fame
The game maintains a persistent leaderboard in arrays s$, g, w, and p (referenced in line 872’s REM as dimensioned to 20 entries). Line 600 computes win percentages, and lines 868–891 update the table after a game ends. The logic searches for a matching name in s$(x); if not found and the slot is blank (" "), it inserts the new commander. If the table is full, line 871 prints “NO ROOM IN TABLE” and pauses. Lines 875–891 also update games-played counts for non-winning players using the h$ string as a two-character flag encoding which players (a, b, c) lost.
Winner Determination Logic
Lines 815–865 contain non-trivial winner detection. The code PEEKs address 31541 for the number of players and 51361 and 52360 for game-state flags. The conditional logic at lines 855–860 handles both two-player and three-player endings, computing the winner index a (1, 2, or 3) through a series of boolean additions — a technique that exploits the fact that BASIC boolean expressions evaluate to 1 (true) or 0 (false).
Input Handling Idioms
Lines 6–7 use a standard debounce pattern: line 6 loops on empty INKEY$ and line 7 captures a valid keypress only when a digit 1–7 is detected. The interactive stats-entry loop at lines 123–127 uses FLASH 1 to highlight the current field and accepts single-character commands (u, d, o) for up, down, and okay, a clean approach to cursor-driven numeric input without a full INPUT statement.
Notable Anomalies
- Line 130 computes
c(b,1) = 20 - c(b,1), inverting the starting resource value, which suggests the UI displays remaining capacity but the machine code stores consumed units (or vice versa). - Line 812 checks
NOT PEEK 52360and returns early, acting as a guard against running the winner-announcement code when no winner flag is set. - The
REMat line 872 documents array dimensions that must be set elsewhere (likely in the machine code initialization or a prior BASIC section), serving as inline developer documentation rather than executable code.
Source Code
1 POKE VAL "23730", VAL "24":POKE VAL "23731", VAL "123":LOAD "conque.C1"CODE
4 LET h$="":BORDER k0:PAPER k0:INK VAL "7"
5 LET a=k0:CLS :PRINT ' TAB 12;"CONQUEST";''' TAB k5;"1. New Game";'' TAB k5;"2. Load Game";'' TAB k5;"3. Save Game";'' TAB k5;"4. Map Editor";'' TAB k5;"5. Save Map";'' TAB k5;"6. View Commanders";'' TAB k5;"7. Quit"
6 IF INKEY$="" THEN GO TO k3+k3
7 IF INKEY$ >="1" AND INKEY$ <="7" THEN LET a= VAL INKEY$
8 IF a=7 THEN STOP
9 GO SUB a*kc
10 GO TO k5-k1
100 CLS :PRINT '"How many Players? (2 or 3)"
101 INPUT a:IF a <>k2 AND a <>k3 THEN GO TO kc+k1
102 LET x= VAL "31541":POKE x,a:PRINT '"How many Human Players? (0-3)"
103 INPUT a:IF a>(PEEK x) THEN GO TO kc+k3
106 POKE (x-k1),a: LET a$="Yellow":LET b$="Red":LET c$="White"
107 IF a=k0 THEN GO TO VAL "112"
108 IF a >=k1 THEN PRINT ''"First Player's Name?":INPUT a$
109 IF a >=k2 THEN PRINT ''"Second Player's Name?":INPUT b$
110 IF a=k3 THEN PRINT ''"Third Player's Name?":INPUT c$
112 LET b= CODE a$(LEN a$)+kh:LET d$=a$:LET d$(LEN d$)= CHR$ b
114 LET b= CODE b$(LEN b$)+kh:LET d$=d$+b$:LET d$(LEN d$)= CHR$ b
116 LET b= CODE c$(LEN c$)+kh:LET d$=d$+c$:LET d$(LEN d$)= CHR$ b
117 LET x= VAL "31514":POKE x,kh:LET x=x+k1:FOR b=k1 TO LEN d$
118 POKE x, CODE d$(b):LET x=x+k1:NEXT b
120 CLS :PRINT '"First Player ";a$;'' TAB k5;e$;'' TAB k5;f$;''"Second Player ";b$;'' TAB k5;e$;'' TAB k5;f$;''"Third Player ";c$;'' TAB k5;e$;'' TAB k5;f$
121 PRINT AT kl-k1,k0;"u=UP; d=Down; o=Okay"
122 DIM c(k3,k2):LET a= PEEK VAL "31541":FOR b=k1 TO a:FOR d=k1 TO k2:LET c(b,d)= VAL "10":NEXT d:NEXT b:GO SUB VAL "999"
123 LET m=k3:FOR l=k1 TO a:FOR n=k1 TO k2:PRINT AT m,k3; FLASH k1;"\::"
125 INPUT h$:IF h$="u" THEN LET c(l,n)=c(l,n)+ SGN PI:GO SUB VAL "999":GO TO VAL "124"
126 IF h$="d" THEN LET c(l,n)=c(l,n)- SGN PI:GO SUB VAL "999":GO TO VAL "124"
127 IF h$="o" THEN PRINT AT m,k3;" ":LET m=m+k2:NEXT n:LET m=m+k2:NEXT l
128 PRINT AT VAL "21",k0;"Okay? (y OR n)":INPUT h$:IF h$="n" THEN GO TO VAL "122"
130 FOR b=k1 TO k3:LET c(b,k1)=20-c(b,k1):NEXT b
131 LET m= VAL "31544":FOR b=k1 TO a:FOR d=k2 TO k1 STEP -k1:POKE m,c(b,d):LET m=m+ SGN PI:NEXT d:NEXT b
133 PRINT AT kl,k0;"Music on? (y OR n)":INPUT h$:IF h$="n" THEN POKE km,k0
135 PRINT AT kl,k0;"Random map? (y OR n)":INPUT h$:IF h$="y" THEN GO TO kx
150 CLS :PRINT "Which map number?":INPUT b$:LET a$="map"+b$+".C1":LOAD a$ CODE
151 PRINT ''"Give computer players map? (y OR n)":INPUT h$:IF h$="y" THEN RANDOMIZE USR VAL "59950"
155 GO TO kx
199 RETURN
200 CLS :PRINT "Which game number?":INPUT b$:LET a$="game"+b$+".C1":LOAD a$ CODE
210 PRINT AT kl,k0;"Music on? (y OR n)":INPUT h$:IF h$="n" THEN POKE km,k0:GO TO kx
300 CLS :PRINT "Game number please.":INPUT h$:LET a$="game"+h$+".C1":SAVE a$ CODE VAL "31514", VAL "20882"
320 PRINT ''"Continue game? (y OR n)":INPUT h$:IF h$="y" THEN GO TO kx
399 RETURN
400 RANDOMIZE USR ky
405 RANDOMIZE USR VAL "6E4"
410 RANDOMIZE USR kz
499 RETURN
500 CLS : LET a= PEEK kw:IF a<16 THEN PRINT ''"Cities not verified":RETURN
505 PRINT "what number please.":INPUT h$:LET a$="map"+h$+".C1":SAVE a$ CODE kw, VAL "4097":RETURN
600 FOR x=k1 TO kl-k1:IF g(x)=k0 THEN GO TO 603
601 LET p(x)=w(x)/g(x)*kc
603 NEXT x
605 CLS :PRINT TAB k5+k9;"COMMANDERS"," NAME GAMES WINS PERCENT"
610 FOR x=k1 TO kl-k1:PRINT AT x+k1,k0;s$(x); TAB 15;g(x); TAB kl;w(x); TAB kl+k5;p(x):NEXT x
620 PAUSE 4E4:RETURN
800 RANDOMIZE USR ky
805 RANDOMIZE USR 53500
810 RANDOMIZE USR kz
812 IF NOT PEEK 52360 THEN RETURN
815 LET a= PEEK 31541:LET d= PEEK 51361:IF a=k3 AND d <>k0 AND d <>255 THEN RETURN
820 LET d$="":LET a$=" ":LET b$=a$:LET c$=a$
825 FOR x=31515 TO 31538:LET d$=d$+ CHR$ (PEEK x):NEXT x
830 FOR x=k1 TO LEN d$:IF CODE d$(x)<kh THEN LET a$(x)=d$(x):NEXT x
835 LET a$(x)= CHR$ (CODE d$(x)-kh):LET b=x
840 FOR x=x+1 TO LEN d$:IF CODE d$(x)<kh THEN LET b$(x-b)=d$(x):NEXT x
845 LET b$(x-b)= CHR$ (CODE d$(x)-kh):IF a=k2 THEN GO TO 860
850 LET b=x:FOR x=x+1 TO LEN d$:IF CODE d$(x)<kh THEN LET c$(x-b)=d$(x):NEXT x
855 LET c$(x-b)= CHR$ (CODE d$(x)-kh):LET b= PEEK 52360:IF a=k2 THEN LET a=k1+(b=k1):GO TO 865
860 LET a=k1+(b=k1)+(d=k1):IF a=k2 THEN LET a=a+(b=k2)+(d=k2)
865 CLS :PRINT AT k5,k5;"CONGRATULATIONS"; AT k5+k2,k5;"COMMANDER ";(a$ AND a=k1);(b$ AND a=k2);(c$ AND a=k3)
866 LET w$="":LET w$=w$+(a$ AND a=k1)+(b$ AND a=k2)+(c$ AND a=k3)
868 FOR x=k1 TO kl-k1:IF w$=s$(x) THEN LET g(x)=g(x)+k1:LET w(x)=w(x)+k1:GO TO 875
869 IF s$(x)=" " THEN LET s$(x)=w$:GO TO 868
870 NEXT x
871 PRINT AT kl,k0;"NO ROOM IN TABLE":PAUSE 4E4:RETURN
872 REM DIM s$(20,10),g,w AND p to 20
875 IF w$=a$ THEN LET h$="bc"
876 IF w$=b$ THEN LET h$="ac"
877 IF w$=c$ THEN LET h$="ab"
878 LET l$="":LET l$=l$+(a$ AND h$(k1)="a")+(b$ AND h$(k1)="b")
880 FOR x=k1 TO kl-k1:IF s$(x)=l$ THEN LET g(x)=g(x)+k1:GO TO 886
881 IF s$(x)=" " THEN LET s$(x)=l$:LET g(x)=g(x)+k1:GO TO 886
882 NEXT x
883 GO TO 871
886 LET l$="":LET l$=l$+(b$ AND h$(k2)="b")+(c$ AND h$(k2)="c")
888 FOR x=k1 TO kl-k1:IF s$(x)=l$ THEN LET g(x)=g(x)+k1:RETURN
889 IF s$(x)=" " THEN LET s$(x)=l$:LET g(x)=g(x)+k1:RETURN
890 NEXT x
891 GO TO VAL "871"
950 STOP
999 LET e=k3:FOR b=k1 TO a:FOR d=k1 TO k2:PRINT AT e,17;" ":LET e=e+k2:NEXT d:LET e=e+k2:NEXT b:LET e=k3:PRINT AT e,17;:FOR b=k1 TO a:FOR d=k1 TO k2:PRINT c(b,d);:LET e=e+k2:PRINT AT e,17;:NEXT d:LET e=e+k2:PRINT AT e,17;:NEXT b:RETURN
1000 SAVE "conquest" LINE 1Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
