PROGRAM LINES OVERVIEW ====================== lines purpose ----- ------- 0-1 init 2-3 stats, player move 4 cursor display 5-6 player buildings 7 people settling in 8-9 evolve roads and zones
VARIABLES ========= A$ pressed key const C cursor POKE address base (65292) const C$(2-4) characters for different zones const D diff between color map <-> char map (1024) E year (2000-) F funds I loop variable const K high bit (128) const K$(2-4) color codes for different zones M occupied workplaces (0-) O population (0-) P actual POKE address (3072-4071) const R road POKE (160) const S screen start (without stats line) (3112) U actual pos color PEEK (0-255) V how many populations around (0-4) const V(0-3) view directions (-1,1,-40-40) W actual pos PEEK (0-255) X actual X pos (1-37) Y actual Y pos (1-21) Z actual pos to evolve (3112-4031)
EXTENDED CODE (using CBM Prg Studio for special characters) =========================================================== 0 C=65292:S=3112:K=128:FORI=0TO4:READC$(I),K$(I),V(I):NEXT:D=K*8:F=1000:E=2*F:X=19:Y=11 1 R=160:COLOR0,Y:COLOR4,2,6:PRINT"{black}{clear}":CHAR,1,24,"{orange}feels like a city * use crsr,spc,r,c,i" 2 E=E+.001:PRINT"{home}{black}year"INT(E)" people:"O"{left} funds:"F"{left} ":GETA$:IFA$="{left}"THENX=X-1-(X<2) 3 IFA$="{right}"THENX=X+1+(X>36):ELSEIFA$="{up}"THENY=Y-1-(Y<2):ELSEIFA$="{down}"THENY=Y+1+(Y>20) 4 P=X+Y*40+S:POKEC+1,PAND255:POKEC,P/256:IFF<5THEN7:DATA,,-1,,,1,R,"{green}",-40,C,"{blue}",40,I,"{orange}", 5 IFA$=" "ANDPEEK(P)=32THENPOKEP,R:F=F-5:GOTO7:ELSEFORI=2TO4 6 IFA$=C$(I)THENCHAR,X-1,Y,K$(I)+"O{183}P{down}{left*3}{165} {167}{down}{left*3}L{175}{186}{up}{left*2}{black}"+C$(I):F=F-I*100:NEXT:ELSENEXT 7 Z=INT(RND(0)*920)+S:W=PEEK(Z):U=PEEK(Z-D):IFU=53ANDW8 V=0:FORI=0TO3:V=V-(PEEK(Z+V(I))>R):NEXT:IFV=0THEN2:ELSEIFW=RTHENPOKEZ,186:GOTO2 9 IFU>69THENF=F+10*(U-69):IFWMTHENPOKEZ,WORK:M=M+25:GOTO2:ELSE2:ROEPIPI2020
DETAILED CODE DESCRIPTION ========================= "FEELS LIKE A CITY" - use title to prepare player to accept a lesser simulation (also avoid using "SIM" in title to avoid copyright problems)
line 0 - INIT START
C=65292 - use hardware cursor to - give the environment a seamless feel - avoid PEEKing and POKEing around
S=3112 - set screen start just below the stats line
K=128 - high bit to check/set reversing in game
FOR I=0 TO 4:READ C$(I),K$(I),V(I):NEXT - fill up some arrays from DATA in line 4
D=K*8 - set color map <-> char map diff (1024), saving 1 char
F=1000:E=2*F:X=19:Y=11 - set funds, starting year, coordinates; note that starting year is 2x the starting funds, saving another char in line
line 1
R=160 - screen code for roads, also we will consider every zone "occupied" above this
COLOR 0,Y:COLOR 4,2,6 - screen colors; Y is good for this (in retrospect, it wasn't necessary, as line is 2 chars below the limit)
PRINT "{black}{clear}" - clear screen with color black, so POKEing a road char won't need POKEing a color code, too
CHAR,1,24,"{orange}feels like a city * use crsr,spc,r,c,i" - give player a warm welcome and a short guide about what they can do (also to give the game an "out-of-the-box" feeling)
line 2 - LOOP START
E=E+.001 - important to balance out the passage of time; in a year, every char in the playfield gets some chance to evolve
PRINT "{home}{black}year"INT(E)" people:"O"{left} funds:"F"{left} " - display stats; not rushing player displaying months or such; note the auto-erasing leftover digits feature (in retrospect, I would have indented this line just 1 char; also, deleting digits from 'people' count is unnecessary as it won't decrease)
GET A$:IF A$="{left}" THEN X=X-1-(X<2) - starting the long key-checking and keeping the player inside the edges, to avoid errors placing 3x3 zones
line 3
IF A$="{right}" THEN X=X+1+(X>36):ELSE IF A$="{up}" THEN Y=Y-1-(Y<2):ELSE IF A$="{down}"THEN Y=Y+1+(Y>20) - yep, it's long... note the comparison expressions inside the brackets, eg. if (X>36) is true, it returns -1; if false, returns 0.
line 4
P=X+Y*40+S:POKE C+1,P AND 255:POKE C,P/256 - set actual screen address and place hardware cursor
IF F<5 THEN 7 - low funds, skip buildings
DATA,,-1,,,1,R,"{green}",-40,C,"{blue}",40,I,"{orange}", - compressed DATA for check directions and zones
line 5
IF A$=" " AND PEEK(P)=32 THEN POKE P,R:F=F-5:GOTO 7 - build roads only on empty places; skip buildings
ELSE FOR I=2 TO 4 - check for different zone buildings; also I is for 1/100th of their prices
line 6
IF A$=C$(I) THEN CHAR,X-1,Y,K$(I)+"O{183}P{down}{left*3}{165} {167}{down}{left*3}L{175}{186}{up}{left*2}{black}"+C$(I):F=F-I*100 - zone coloring and gfx; pressed key is also for zone letter
NEXT:ELSE NEXT - simple trick after conditional branches to save a line for loop end
line 7
Z=INT(RND(0)*920)+S:W=PEEK(Z):U=PEEK(Z-D) - pick a random position along the 23 lines of playfield; set char and color PEEKs
IF U=53 AND Wadd some funds and people; one 3x3 green zone can hold 200 people (their centers are unused); go back to loop start
line 8
V=0:FOR I=0 TO 3:V=V-(PEEK(Z+V(I))>R):NEXT:IF V=0 THEN 2 - everything else beside unoccupied greens: see if it has "occupied" chars around; if not, go back to loop start
ELSE IF W=R THEN POKE Z,186:GOTO 2 - if it's a road char, make it occupied by cars (and go back to loop start)
line 9
IF U>69 THEN F=F+10*(U-69) - if it's "above" green (as orange and purple happens to be), give funds to player, orange ranking the highest :)
IF WM THEN POKE Z,W OR K:M=M+25:GOTO 2 - also if it's unoccupied and there are more people than working ones: occupy and mark as workers (go back to loop start)
ELSE 2 - anything else: back to loop start
ROEPIPI2020 - "signed"; the interpreter won't run it because it's after an (implicit) GOTO |