Kingdom

This file is part of and Timex Sinclair Public Domain Library Tape 1003. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000

Kingdom is a multi-player resource-management game in which each player governs a village over five years (twenty seasons), balancing population, money, and corn while defending against floods, starvation, and thieves. Each turn players allocate workers to three jobs—dyke mending, planting, and defence—then deal with randomly triggered disasters. The program stores per-player state in parallel arrays (M, C, Q, D, N, Z, X, T) and uses string slicing on N$(A,11) to pack both a player’s name and gender code into a single dimensioned string. A notable optimisation at line 8000 pre-builds a 22-line screen image string in FAST mode before the game begins. The listing includes an embedded note at line 9005 acknowledging that the program crashes at line 470.


Program Analysis

Program Structure

The program is divided into a title/intro section, initialisation, a main game loop, and several subroutines:

  1. Lines 1–57: Title screen, rules display, player registration (GOSUB 7000), and array initialisation.
  2. Lines 100–630: Main seasonal loop. S cycles 1–4 (seasons); Y counts years 1–5. The outer loop at line 170 iterates over players (P).
  3. Lines 640–730: End-of-game winner announcement.
  4. Lines 1000–1110: Flood/dyke subroutine.
  5. Lines 2000–2180: Thieves/defence subroutine.
  6. Lines 3000–3040: Starvation subroutine.
  7. Lines 4000–4220: Corn-buying subroutine.
  8. Lines 5000–5140: Corn-selling subroutine.
  9. Lines 7000–7190: Player registration loop.
  10. Lines 8000–8050: Pre-build screen background string in FAST mode.
  11. Lines 9000–9010: SAVE and RUN.

Data Model

All per-player state is held in parallel numeric arrays dimensioned to A (number of players). The packed name/gender string array N$(A,11) uses the 11th character as a gender flag (‘M’ or ‘F’), with characters 1–10 holding the name proper. Slices like N$(P)(TO 10) and N$(P)(11) exploit ZX81-style string slicing to read back name and gender independently.

ArrayMeaningInitial value
M(A)Money ($)1000
Q(A)Population1000
C(A)Corn (sacks)2500
D(A)Corn planted this spring
Z(A)Flood casualties (display)0
X(A)Starvation casualties (display)0
T(A)Thief casualties (display)0
N(A)New arrivals this season
U(A)Player age

Seasonal / Year Loop

S is incremented each iteration of the outer player loop preamble (line 115) and wraps back to 0 at S=4 (line 150). Y is only incremented when S=1 (Spring, line 140), giving a clean year counter. The game ends when Y=5 at line 630.

Disaster Subroutines

Three randomly triggered disasters are evaluated each season per player. Each is called conditionally based on the player’s labour allocation:

  • Floods (1000): Triggered if dyke workers (A1) are fewer than Q(P)/2.2. A random K (5–14) kills K*10 people, destroys K*15 sacks of corn, and fines the player money if K>8. A 1-in-3 chance of no event provides a random reprieve.
  • Thieves (2000): Triggered if defenders (A3) are fewer than Q(P)/2.2. Deducts people, corn, and money. Has a bug: uses T (the loop variable) instead of RND in the reprieve check at line 2010.
  • Starvation (3000): Triggered if corn planted is less than twice the population. Deaths equal the shortfall, capped at the total population.

Corn Economy

At the end of each season, corn is updated as C(P) = (C(P)/1.2) + D(P)*3 (line 535), meaning planted corn triples but existing stocks decay. If the total corn is below Q(P)*2, subroutine 4000 forces the player to buy corn at a random rate ($15–$19 per sack). If surplus exists, subroutine 5000 offers selling at $5–$9 per sack. Money grows automatically at 9% per season (line 580).

Screen Techniques

The program uses PRINT AT extensively for layout and scrolls the screen with a FOR/SCROLL/NEXT loop (22 iterations) rather than CLS, to avoid screen flicker between game phases. The subroutine at line 8000 pre-builds a 22-line background string M$ in FAST mode using inverse characters and ASCII art, then prints it in one statement at line 470 (PRINT AT 0,0;M$).

Centring of numeric output at lines 240–280 is achieved with a formula: TAB 15-(((LEN(STR$ value))+N)/2), where N accounts for the label length. This is an elegant approach to dynamic text centering without knowing the number’s width in advance.

Player Title Logic

Lines 190–200 determine the player’s title for display. The logic uses gender (character 11 of N$) and age (U(P)) to assign King/Queen/Prince/Princess. However, line 200 contains a bug: it tests N$(P)="F" against the full 11-character string rather than N$(P)(11)="F", so the Queen title will never be displayed correctly.

Input Validation

Labour allocations (lines 335, 375, 410) are validated with IF INT A1 <> A1 THEN GOTO to reject fractional inputs. The total labour check at line 412 ensures workers assigned don’t exceed population, looping back to re-display if over-allocated. The corn planting input (line 425) checks it doesn’t exceed available stocks.

Bugs and Anomalies

  • Line 11 / lines 10–12: LET Y=0 is inside a FOR F=10 TO 21 loop with no PRINT or SCROLL, so it serves only to reset Y (the year counter) 12 times on the title screen — the loop body appears to be a remnant of a screen-clear attempt.
  • Line 200: Condition N$(P)="F" tests the entire 11-character name string against a single character, so the Queen title is never triggered.
  • Line 280: The corn display is missing C(P) — the format string prints " SACKS OF CORN." but the corn value itself is not included in the PRINT statement.
  • Line 415: Inside the labour-overflow loop (lines 414–416), IF INT A3<>A3 THEN GOTO 410 is a stray validation check that has no effect since the loop is only entered after valid integer input.
  • Line 2010: Uses T (the loop control variable from line 2030 if previously run, otherwise 0) instead of RND for the 1-in-3 reprieve, making the thieves event deterministic rather than random.
  • Line 2088: PRINT EXP 10,16; is clearly a typo for PRINT AT 10,16;, and would cause a syntax or runtime error.
  • Lines 5040–5070: The sell subroutine prints a prompt but never actually inputs a value — A$ is used at lines 5050 and 5070 but is never assigned by an INPUT statement in this subroutine, so it retains whatever value it last held.
  • Line 7160: INPUT H$ appears twice (lines 7150 and 7160), requiring the player to confirm twice.
  • Line 9005: An inline REM note from the author states “THIS PROGRAM CRASHES REPORT CODE 5/470”, referencing a crash at line 470 (PRINT AT 0,0;M$), likely due to M$ being too long for a single PRINT statement.
  • Line 705: POKE 16418,0 resets the system variable controlling the cursor position — an unusual direct memory write in an otherwise pure-BASIC program.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10122 – 10175.

Related Products

Related Articles

Related Content

Image Gallery

Kingdom

Source Code

   1 PRINT AT 3,7;"*****************"
   2 PRINT AT 4,7;"*               *"
   3 PRINT AT 5,7;"* K I N G D O M *"
   4 PRINT AT 6,7;"*               *"
   5 PRINT AT 7,7;"*****************"
   6 PRINT AT 10,0;"YOU HAVE TO GOVERN A VILLAGE";AT 12,0;"FOR A PERIOD OF FIVE YEARS.YOU";AT 14,0;"MUST TRY TO KEEP ALIVE AS MANY"
   7 PRINT AT 16,0;"PEOPLE AS POSSIBLE.THEY WILL DO";AT 18,0;"ONE OF THREE JOBS.";AT 20,0;"YOU MUST PROTECT THEM AGAINST.."
   8 PRINT AT 21,5;"PRESS ANY KEY TO CONTINUE"
   9 IF INKEY$="" THEN GOTO 9
  10 FOR F=10 TO 21
  11 LET Y=0
  12 NEXT F
  13 PRINT AT 10,0;"...(A)>=FLOODS";AT 11,0;"...(B)>=STARVATION";AT 12,0;"...(C)>=THIEVES";AT 14,0;"YOU HAVE TO BE AS RICH AS POSS.";AT 16,0;"AT THE END OF THE FIVE YEARS";AT 18,0;"AND THE RICHEST WINS."
  14 PRINT AT 21,5;"PRESS ANY KEY TO CONTINUE"
  15 IF INKEY$="" THEN GOTO 15
  16 FOR F=10 TO 21
  17 PRINT AT F,0;"                               "
  18 NEXT F
  19 PRINT AT 10,0;"HOW MANY PLAYERS?  ";  
  20 INPUT A
  21 PRINT A
  22 DIM N$(A,11)
  23 DIM U(A)
  24 GOSUB 7000
  34 PRINT AT 21,5;"PRESS ANY KEY TO START"
  35 IF INKEY$="" THEN GOTO 35
  36 FOR F=1 TO 22
  37 SCROLL 
  38 NEXT F
  39 GOSUB 8000
  40 DIM M(A)
  41 DIM C(A)
  42 DIM Q(A)
  43 FOR F=1 TO A
  44 LET M(F)=1000
  45 LET Q(F)=1000
  46 LET C(F)=2500
  47 NEXT F
  48 DIM D(A)
  49 DIM N(A)
  50 DIM Z(A)
  51 DIM X(A)
  52 DIM T(A)
  53 FOR F=1 TO A
  54 LET Z(F)=0
  55 LET X(F)=0
  56 LET T(F)=0
  57 NEXT F
 100 REM START
 105 LET S=0
 115 LET S=S+1
 120 IF S=1 THEN LET Y$="SPRING"
 125 IF S=2 THEN LET Y$="SUMMER"
 130 IF S=3 THEN LET Y$="AUTUMN"
 135 IF S=4 THEN LET Y$="WINTER"
 140 IF S=1 THEN LET Y=Y+1
 150 IF S=4 THEN LET S=0
 170 FOR P=1 TO A
 175 LET N(P)=INT (RND*10)
 176 LET Q(P)=Q(P)+N(P)
 180 PRINT AT 0,9;Y$;" YEAR ";Y
 190 IF N$(P)(11)="M" AND U(P)>18 THEN PRINT "KING ";N$(P)( TO 10)
 193 IF N$(P)(11)="F" AND U(P)<=18 THEN PRINT "PRINCESS ";N$(P)( TO 10)
 195 IF N$(P)(11)="M" AND U(P)<=18 THEN PRINT "PRINCE ";N$(P)( TO 10)
 200 IF N$(P)="F" AND U(P)>18 THEN PRINT "QUEEN ";N$(P)( TO 10)
 201 PRINT 
 202 PRINT N(P);" PEOPLE CAME TO THE VILLAGE."
 203 PRINT 
 210 PRINT TAB 9;"CASUALTIES:"
 211 PRINT " STARVED . FLOODS . THIEVES"
 212 PRINT TAB 3;X(P);TAB 12;Z(P);TAB 22;T(P)
 214 PRINT "********************************"
 220 PRINT TAB 10;"YOU HAVE:"
 240 PRINT TAB 15-(((LEN (STR$ M(P)))+2)/2);"$";M(P);","
 260 PRINT TAB 15-(((LEN (STR$ Q(P)))+8)/2);Q(P);" PEOPLE,"
 280 PRINT TAB 15-(((LEN (STR$ C(P)))+15)/2);" SACKS OF CORN."
 290 PRINT "********************************"
 300 PRINT "LABOR ARRANGEMENT:"
 320 PRINT "(A) MENDING THE DYKE ";
 330 INPUT A1
 335 IF INT A1<>A1 THEN GOTO 330
 340 PRINT A1
 360 PRINT "(B) PLANTING CORN "
 370 INPUT A2
 375 IF INT A2<>A2 THEN GOTO 370
 380 PRINT A2
 400 PRINT "(C) DEFENDING THE VILLAGE "
 409 INPUT A3
 410 IF INT A3<>A3 THEN GOTO 409
 411 PRINT A3
 412 IF A1+A2+A3<=Q(P) THEN GOTO 420
 413 PRINT AT 21,5;"TOO MANY PEOPLE"
 414 FOR F=1 TO 22
 415 IF INT A3<>A3 THEN GOTO 410
 416 NEXT F
 417 GOTO 180
 420 IF Y$<>"SPRING" THEN GOTO 430
 422 PRINT "HOW MANY SACKS OF CORN ARE TO";"    BE PLANTED?  ";
 423 INPUT D(P)
 424 PRINT D(P)
 425 IF D(P)>C(P) THEN GOTO 422
 426 LET C(P)=C(P)-D(P)
 427 IF D(P)/10>A2 THEN LET D(P)=A2*10
 430 PRINT AT 21,5;"PRESS ANY KEY TO CONTINUE"
 440 IF INKEY$="" THEN GOTO 440
 450 FOR F=1 TO 22
 460 SCROLL 
 465 NEXT F
 466 FAST 
 470 PRINT AT 0,0;M$
 490 PRINT AT 8,14;"******";AT 9,14;"*    *";AT 10,14;"* ++ *";AT 11,14;"*     *";AT 12,14;"******"
 500 PRINT AT 10,27;"T"
 501 LET T(P)=0
 502 LET Z(P)=0
 503 LET X(P)=0
 504 SLOW 
 510 IF A1<Q(P)/2.2 THEN GOSUB 1000
 520 IF A3<Q(P)/2.2 THEN GOSUB 2000
 530 IF D(P)<Q(P)*2 THEN GOSUB 3000
 535 LET C(P)=(C(P)/1.2)+D(P)*3
 540 IF C(P)+D(P)<Q(P)*2 THEN GOSUB 4000
 550 IF C(P)+D(P)>Q(P)*2 THEN GOSUB 5000
 560 LET Q(P)=Q(P)*1.2
 565 LET Q(P)=INT (Q(P))
 575 LET C(P)=INT (C(P))
 580 LET M(P)=M(P)*1.09
 583 LET M(P)=INT (M(P))
 590 FOR F=1 TO 22
 600 SCROLL 
 610 NEXT F
 611 IF M(P)<0 THEN LET M(P)=0
 612 IF C(P)<0 THEN LET C(P)=0
 613 IF Q(P)<0 THEN LET Q(P)=0
 620 NEXT P
 630 IF Y<5 THEN GOTO 115
 640 PRINT AT 0,0;"NOW FOR THE WINNER....."
 644 LET W$=""
 645 LET W=0
 650 FOR F=1 TO A
 660 PRINT N$(F)( TO 10);" WITH $";M(F);","
 680 IF M(F)>W THEN LET W$=N$(F)( TO 10)
 690 IF M(F)>W THEN LET W=M(F)
 700 NEXT F
 705 POKE 16418,0
 710 PRINT AT 20,0,"CONGRATULATIONS",W$;"      YOU ARE THE WINNER OF THE GAME  WITH $";W
 730 GOTO 10000
\n1000 REM DYKE
\n1010 IF INT (RND*3)+1=1 THEN RETURN 
\n1020 LET K=INT (RND*10)+5
\n1030 FOR F=3 TO K+3
\n1040 FOR G=0 TO 21
\n1050 PRINT AT G,F;CHR$ 8
\n1060 NEXT G
\n1070 IF K*10>Q(P) THEN LET K=INT (Q(P)/10)
\n1080 LET Q(P)=Q(P)-K*10
\n1090 IF K>8 THEN LET M(P)=M(P)-((K-8)*100)
\n1095 LET Z(P)=K*10
\n1100 LET C(P)=C(P)-K*15
\n1110 RETURN 
\n2000 REM DEF
\n2010 IF INT (T*3)+1=1 THEN RETURN 
\n2020 LET K=INT (RND*10)+5
\n2025 IF K*6>Q(P) THEN LET K=INT (Q(P)/6)
\n2030 FOR F=27 TO 16 STEP -1
\n2040 PRINT AT 10,F;"T "
\n2050 NEXT F
\n2060 FOR F=1 TO K
\n2070 PRINT AT 10,16;"\. "
\n2080 PRINT EXP 10,16;"\' "
\n2090 PRINT AT 10,16;"\ '"
\n2100 PRINT AT 10,16;"\ ."
\n2110 NEXT F
\n2120 FOR F=16 TO 27
\n2130 PRINT AT 10,F;" T"
\n2140 NEXT F
\n2150 LET Q(P)=Q(P)-K*6
\n2151 LET T(P)=K*6
\n2160 LET C(P)=C(P)-K*25
\n2170 LET M(P)=M(P)-K*15
\n2180 RETURN 
\n3000 REM STAR
\n3010 LET K=ABS (D(P)-(Q(P)*2))
\n3015 IF K>Q(P) THEN LET K=Q(P)
\n3020 LET Q(P)=Q(P)-(INT (K))
\n3035 LET X(P)=K
\n3040 RETURN 
\n4000 REM BUY
\n4010 LET K=INT (RND*5)+15
\n4020 FOR F=1 TO 22
\n4030 SCROLL 
\n4040 NEXT F
\n4050 PRINT AT 0,0;"YOU HAVEN/T GOT ENOUGH CORN TO FEED ";"YOUR VILLAGE-YOU MUST BUY SOME..."
\n4060 PRINT 
\n4070 PRINT "CURRENT BUYING RATE = ";K
\n4080 PRINT 
\n4090 PRINT "YOU HAVE $";M(P)
\n4100 PRINT 
\n4110 PRINT "THE MOST YOU CAN HAVE ARE ";INT (M(P)/K)
\n4120 PRINT "SACKS"
\n4140 PRINT "HOW MANY DO YOU WANT TO BUY?";
\n4150 INPUT I
\n4160 IF I>(M(P)/K) THEN GOTO 4140
\n4170 PRINT I
\n4180 PRINT 
\n4190 PRINT "THAT WILLCOST $ ";I*K
\n4200 LET M(P)=M(P)-(K*I)
\n4210 LET C(P)=C(P)+1
\n4220 RETURN 
\n5000 REM SELL
\n5010 FOR F=1 TO 22
\n5020 SCROLL 
\n5030 NEXT F
\n5040 PRINT AT 0,0;"YOU HAVE A SURPLUS OF CORN.DO    YOU";"WANT TO SELL ANY? IF SO,     SPECIFY THE AMOUNT."
\n5050 IF A$(1)="N" THEN RETURN 
\n5070 LET K=VAL A$
\n5071 IF K<=C(P) THEN GOTO 5080
\n5072 PRINT 
\n5073 PRINT "YOU ONLY HAVE ";INT (C(P));" SACKS."
\n5074 IF INKEY$="" THEN GOTO 5074
\n5075 GOTO 5000
\n5080 LET J=INT (RND*5)+5
\n5090 PRINT K;" SACKS OF CORN AT"
\n5100 PRINT "$";J;" A SACK,WILL MAKE "
\n5110 PRINT "$";K*J
\n5120 LET M(P)=M(P)+K*J
\n5130 LET C(P)=C(P)-K
\n5140 RETURN 
\n7000 FOR F=1 TO A
\n7010 CLS 
\n7020 PRINT "PLAYER ";F
\n7030 PRINT 
\n7040 PRINT "YOUR NAME PLEASE:   "
\n7050 INPUT N$(F)
\n7051 PRINT N$(F)
\n7052 PRINT 
\n7060 PRINT "YOUR AGE? ";
\n7070 INPUT U(F)
\n7080 PRINT U(F)
\n7090 PRINT 
\n7100 PRINT "ARE MALE(M) OR FEMALE(F)? ";
\n7110 INPUT N$(F)(11)
\n7120 PRINT N$(F)(11)
\n7130 PRINT 
\n7140 PRINT "O.K.? ";
\n7150 INPUT H$
\n7160 INPUT H$
\n7170 IF H$="NO" OR H$="NO" THEN GOTO 7010
\n7180 NEXT F
\n7190 RETURN 
\n8000 FAST 
\n8005 LET M$=""
\n8010 FOR F=1 TO 22
\n8020 LET M$=M$+"%A%A%A; % ;                      ;//////"
\n8030 NEXT F
\n8040 SLOW 
\n8050 RETURN 
\n9000 SAVE "1014%9"
\n9005 REM  THIS PROGRAM CRASHES            REPORT CODE 5/470
\n9010 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top