Tak na tento program som sa chystal dlho, veľmi dlho, úvodnú hlavičku som vyrobil v roku 2020, rozvrhol som nejaké schémy ako na to, časti programu som aj napísal - ale stále to bolo akosi priveľmi komplikované a tak som to radšej založil do šuplíku a spalo to tam doteraz - a to ešte pred pár dňami. Teraz som vzal zo starého, rozrobeného a nedokončeného programu iba jeho pôvodnú hlavičku, kompletne všetko ostatné som urobil a napísal odznova - a to po novom, celkom inak, program je napísaný pre SBC6502 s 32kB RAM (dané pevnou lokáciou adries tieňovej obrazovky v RAM). Nemyslím že by tie pevne nastavené lokácie v RAM nejako vadili, tých 32kB RAM na takýchto SBC je dnes dá sa povedať už nepísaným štandartom. Chcel som vyskúšať ako na to viem ísť "po vlastnej osi", takže nemal som (ani som nehľadal) žiadnu inšpiráciu z podobnej hry - a teda použité riešenie je naozaj jedinečné a nie je okopírované. Možno by stálo za to tu vyskúšať použiť v programe príkaz DIM, tu som to ale nepoužil, rozhodol som sa vytvoriť si potrebné dvojrozmerné hráčske pole priamo vo voľnej RAM, pripadalo mi to zábavnejšie pri písaní programu (a vďaka tomu je program aj o poznanie kratší).
Čo ma viedlo k napísaniu tejto hry? Nuž mimo iného je to dané aj tým že hier čo sa hrajú v terminálovom okne v dnešnej dobe akosi niet - nakoniec výpis pri štarte samotného SBC6502 uvádza rok 1977 ... (letí to ...) a zatiaľ som len preberal a konvertoval nejaké hry, už bolo načase nadlapať svoju vlastnú jednoduchú hru. Program spolupracuje s programom Hyperterminál pod Win, iný terminálový program som na spoluprácu netestoval. Pre mazanie obrazovky je použitý typický terminálový príkaz ? CHR$(12) namiesto príkazu CLS ktorý MS BASIC pre SBC6502 nemá.
Je tu jedna vlastnosť ktorá sa nedá obísť - tu totiž nie je možné prepisovať veci po celej obrazovke a návrat pozície kurzoru je možný len o pár znakov - a to tiež len obmedzene a teda pri potrebnej zmene je potom potrebné prepisovať celú obrazovku. Vo výsledku to znamenalo urobiť si v RAM pamäti tieňovú obrazovku a zmeny prevádzať v nej a až keď je tam prevedená zmena tak následne zmazať displej a potom to celé naraz nanovo vypísať na obrazovku terminálu. Je to síce také škrabanie sa za uchom opačnou rukou - ale na lepší systém ako na to som doteraz neprišiel (kto vie lepšie riešene - sem s ním !). Urobil som jednoduchú hru Battleships, kde sa snažíte na ploche 40 x 14 štvorčekov nájsť umiestnenie jednotlivých lodí a teda snažíte sa túto bojovú flotilu postupne likvidovať.
Čisté hracie pole.
Program vytvorí spomenuté hracie pole a potom do neho náhodne vygeneruje rozmiestnenie 20 bojových lodí nášho protivníka, našou úlohou je nájsť ich lokáciu. Pre základné zničenie nepriateľskej flotily postačuje zlikvidovať minimálne 14 lodí, potom je ich bojaschopnosť úplne ochromená. Vzhľadom k tomu že je tu k dispozícii celkove 560 možných lokácií tak o dlhú zábavu je postarané - a to nemusíme pritom ani nájsť všetky lode protivníka. Na displeji zadávame údaje o lokácii v poradí - najprv treba zadať os X (1÷40) a potom os Y (1÷14), povolený rozsah týchto hodnôt program kontroluje. Ak použijete v zadaní X alebo Y hodnotu 0 = koniec programu.
Na tomto obrázku som nechal nájsť všetkých 14 potrebných lodí (ako priamo na to - tak túto fintu neuvádzam), pekne však vidieť že sa skutočne jedná vždy o náhodné rozmiestnenie lodí protivníka a teda situáciu pri ich hľadaní nám počítač rozhodne neuľahčuje. Pozícia zničenej lode je značená krížikom - †, nepoužité pole pri našom poľovaní je vyznačené bodkou . , program počíta celkové skóre, tak isto počíta počet potrebných striel na dosiahnutie uvedeného skóre.
Takto to vyzerá priamo v hre - vidíme zásahy - † a tak isto ak trafíme vedľa - x
Obmedzujúcim prvkom je tu maximálne použiteľné vertikálne rozlíšenie (dané terminálovým oknom), je k dispozícii iba 22 riadkov a teda musím si vystačiť s tým čo je k dispozícii. Komunikačné riadky pod poľom majú k dispozícii 3 riadky z 22 a sú tu maximálne využité, to potom stanovilo aj maximálny počet riadkov v osi Y na 14.
Program mám v 2 verziách,
jedna je pre x-tal 1.8432MHz:
S_battle_1_8432MHz.txt (6,47 kb)
druhá je pre x-tal 4.9152MHz:
S_battle_4_9152MHz.txt (6,47 kb)
Záver:
Medzi nami - vedel by som to hracie pole roztiahnuť a zväčšiť trebárs aj na 78 x 18 štvorčekov (to by už bolo 1404 pozícií na hľadanie), otázka je iná - nemám pocit že by to potom ešte niekoho bavilo, aj tak je to teraz už hodne zložité, to je jediný dôvod prečo som nešiel do extrému. Hra má pokiaľ možno baviť, nie otráviť.
No a keď som toto dokončil /hru som napísal v priebehu 2 dní/ som si povedal: "Skús previesť konverziu tohoto programu pre SBC6809 a tiež pre Micro UK101 ..., nemal by to byť problém." - ale o tom ako to dopadlo zase už niekedy inokedy.
____________________________________________________________
Ukážka - listing programu pre SBC6502 a x-tal 1.8432MHz:
1000 CLEAR:POKE 15,80:? CHR$(12):?:A=31000:B=124:REM 05.11.2023
1030 ? SPC(12)" _ _ _ _ _ _ "
1032 ? SPC(12)" | | | | | | | | | | (_)"
1034 ? SPC(12)" | |__ __ _| |_| |_| | ___ ___| |__ _ _ __ ___"
1036 ? SPC(12)" | '_ \ / _` | __| __| |/ _ \/ __| '_ \| | '_ \/ __|"
1038 ? SPC(12)" | |_) | (_| | |_| |_| | __/\__ \ | | | | |_) \__ \"
1040 ? SPC(12)" |_.__/ \__,_|\__|\__|_|\___||___/_| |_|_| .__/|___/"
1042 ? SPC(12)" | | SBC6502"
1044 ? SPC(12)" |_|"
1046 ? SPC(12)" )_("
1048 ? SPC(12)" ________|_ "
1050 ? SPC(12)" ______ /==========| ___/"
1052 ? SPC(12)"____ _____ [\\\]___/___________|__[///] __/"
1054 ? SPC(12)"\ o \____[\\]__/__________________________\___[//]___"
1056 ? SPC(12)" \ 2311 |__O__O__||__O__O__||__O__O__||__O__O__|"
1058 ? SPC(12)" \ /"
1060 ? SPC(12)"";:FOR F=1 TO 55:?CHR$(126);:NEXT:GOSUB 9998
1065 FOR H=1 TO 5:? CHR$(8);:NEXT:? CHR$(94);:GOSUB 9998
1070 FOR H=1 TO 4:GOSUB 9970:NEXT:? CHR$(8)CHR$(126)
1170 ? TAB(22);"by Igi(c)2023 - http://blog.3b2.sk/igi";
1172 GOSUB 9999
1200 ? CHR$(12):GOSUB 2500:GOSUB 2700
1400 ?:? CHR$(12);
1410 ? SPC(5)"+- 20 battleships in this game,you have to destroy";
1415 ? " at least 14 ships -+"
1417 ? SPC(5)"+----------+ ";
1420 ? "|X 1111111111222222222233333333334 ";
1422 ? " +----------+"
1425 ? SPC(16)"+-+ Y|1234567890123456789012345678901234567890 -+"
1430 GOSUB 5100
1700 A=31000:GOSUB 2900:A=31050:GOSUB 2900:A=31100:GOSUB 2900
1706 A=31150:GOSUB 2900:A=31200:GOSUB 2900:A=31250:GOSUB 2900
1714 A=31300:GOSUB 2900:A=31350:GOSUB 2900:A=31400:GOSUB 2900
1720 A=31450:GOSUB 2900:A=31500:GOSUB 2900:A=31550:GOSUB 2900
1726 A=31600:GOSUB 2900:A=31650:GOSUB 2900
1800 GOSUB 5100
1805 ? SPC(18)"|Score:";:IF SC<10 THEN ?" "SC;
1820 IF SC=>10 THEN ? SC;
1825 ? SPC(17)"Gun shots: "GS;
1830 IF GS<10 THEN ? " |"
1835 IF GS=>10 AND GS <100 THEN ? " |"
1840 IF GS=>100 THEN ? "|"
1845 ? SPC(18)"+------------- X or Y=0 -> End -------------+"
1850 IF SC=14 THEN 2940
1880 ? SPC(28)"Your choice X (1-40)";:INPUT X
1885 IF X=0 THEN 2950
1890 IF X>40 THEN GOSUB 9988:GOTO 1400
1900 ? SPC(28)"Your choice Y (1-14)";:INPUT Y
1905 IF Y=0 THEN 2950
1910 IF Y>14 THEN GOSUB 9988:GOTO 1400
2000 T=31700:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2002 T=31702:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2004 T=31704:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2006 T=31706:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2008 T=31708:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2010 T=31710:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2012 T=31712:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2014 T=31714:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2016 T=31716:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2018 T=31718:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2020 T=31720:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2022 T=31722:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2024 T=31724:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2026 T=31726:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2028 T=31728:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2030 T=31730:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2032 T=31732:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2034 T=31734:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2036 T=31736:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2038 T=31738:GOSUB 2800:IF X=X1 AND Y=Y1 THEN 3000
2050 GS=GS+1
2055 IF X<>X1 OR Y<>Y1 THEN 4000
2250 C=C+1:?C;:FOR F=A+4 TO A+43:POKE F,46:NEXT F:RETURN
2500 GS=0:SC=0:C=0:?"I am generating a line no.:"
2552 A=31000:GOSUB 2250
2555 POKE A,B:POKE A+1,32:POKE A+2,49:POKE A+3,B:POKE A+44,B
2560 A=31050:GOSUB 2250
2562 POKE A,B:POKE A+1,32:POKE A+2,50:POKE A+3,B:POKE A+44,B
2570 A=31100:GOSUB 2250
2572 POKE A,B:POKE A+1,32:POKE A+2,51:POKE A+3,B:POKE A+44,B
2580 A=31150:GOSUB 2250
2582 POKE A,B:POKE A+1,32:POKE A+2,52:POKE A+3,B:POKE A+44,B
2590 A=31200:GOSUB 2250
2592 POKE A,B:POKE A+1,32:POKE A+2,53:POKE A+3,B:POKE A+44,B
2600 A=31250:GOSUB 2250
2602 POKE A,B:POKE A+1,32:POKE A+2,54:POKE A+3,B:POKE A+44,B
2610 A=31300:GOSUB 2250
2612 POKE A,B:POKE A+1,32:POKE A+2,55:POKE A+3,B:POKE A+44,B
2620 A=31350:GOSUB 2250
2622 POKE A,B:POKE A+1,32:POKE A+2,56:POKE A+3,B:POKE A+44,B
2630 A=31400:GOSUB 2250
2632 POKE A,B:POKE A+1,32:POKE A+2,57:POKE A+3,B:POKE A+44,B
2640 A=31450:GOSUB 2250
2642 POKE A,B:POKE A+1,49:POKE A+2,48:POKE A+3,B:POKE A+44,B
2650 A=31500:GOSUB 2250
2652 POKE A,B:POKE A+1,49:POKE A+2,49:POKE A+3,B:POKE A+44,B
2660 A=31550:GOSUB 2250
2662 POKE A,B:POKE A+1,49:POKE A+2,50:POKE A+3,B:POKE A+44,B
2670 A=31600:GOSUB 2250
2672 POKE A,B:POKE A+1,49:POKE A+2,51:POKE A+3,B:POKE A+44,B
2680 A=31650:GOSUB 2250
2682 POKE A,B:POKE A+1,49:POKE A+2,52:POKE A+3,B:POKE A+44,B
2684 ?:RETURN
2700 Q=31700:?:?"I am generating 20 battleships ..."
2705 FOR I=1 TO 20
2710 D=INT(RND(1)*14):D=D+1:POKE Q,D
2720 E=INT(RND(1)*40):E=E+1:POKE Q+1,E
2725 Q=Q+2:? I;:FOR R=0 TO 300:NEXT:NEXT:RETURN
2800 Y1=PEEK(T):X1=PEEK(T+1):RETURN
2900 ? SPC(18);:FOR F=A TO A+44:? CHR$(PEEK(F));:NEXT F:?
2905 RETURN
2940 ?SPC(16)"Congratulations! You destroyed the enemy's fleet."
2945 GOTO 2955
2950 ? CHR$(12)
2955 ?:?SPC(28)"(N)ew game or (Q)uit:";:INPUT A$
2960 IF A$="N" THEN 1200
2965 IF A$="Q" THEN END
2970 GOTO 2950
3000 ?SPC(35)"Bingo !!!";:GOSUB 9998:SC=SC+1:OP=134:GOSUB 5000
3080 GS=GS+1:GOTO 1400
4000 ?SPC(36)"Miss !!!";:GOSUB 9998:OP=120:GOSUB 5000:GOTO 1400
5000 IF Y=1 THEN POKE (31004+X-1),OP
5010 IF Y=2 THEN POKE (31054+X-1),OP
5015 IF Y=3 THEN POKE (31104+X-1),OP
5025 IF Y=4 THEN POKE (31154+X-1),OP
5030 IF Y=5 THEN POKE (31204+X-1),OP
5035 IF Y=6 THEN POKE (31254+X-1),OP
5040 IF Y=7 THEN POKE (31304+X-1),OP
5045 IF Y=8 THEN POKE (31354+X-1),OP
5050 IF Y=9 THEN POKE (31404+X-1),OP
5055 IF Y=10 THEN POKE (31454+X-1),OP
5060 IF Y=11 THEN POKE (31504+X-1),OP
5065 IF Y=12 THEN POKE (31554+X-1),OP
5070 IF Y=13 THEN POKE (31604+X-1),OP
5075 IF Y=14 THEN POKE (31654+X-1),OP
5080 RETURN
5100 ? SPC(18)"|-------------------------------------------|"
5102 RETURN
9970 ? CHR$(8)CHR$(126)CHR$(94);:GOSUB 9998:RETURN
9988 ?SPC(37)"Error ...";:GOSUB 9998:RETURN
9998 FOR F=0 TO 2255:NEXT:RETURN
9999 FOR F=0 TO 7518:NEXT:RETURN
_____________________________________________________________
Upozornenie:
Zobrazenie krížiku platí pre nastavenie fontu v Hypertermináli, kedy je jeho okno zmenšené - písmo Lucida Console, veľkosť písma 8, osobne používam najradšej túto veľkosť Hyperterminálového okna:
Ak ponecháme základné nastavenie fontu čo je písmo Terminal, veľkosť písma 14:
tak musíme v programovom riadku číslo 3000 urobiť zmenu:
pôvodný text
3000 ?SPC(35)"Bingo !!!";:GOSUB 9998:SC=SC+1:OP=134:GOSUB 5000
nahradíme:
3000 ?SPC(35)"Bingo !!!";:GOSUB 9998:SC=SC+1:OP=127:GOSUB 5000
Čiže je tu zmena obsahu v premennej OP - po tejto zmene sa zobrazí namiesto krížiku pri zásahu lodička , ak sa zmena neprevedie bude sa zobrazovať iný, vzhľadom nie príliš vhodný znak. Toto samozrejme platí aj v opačnom garde. Je to dané tým, že uvedené dva fonty používajú mierne odlišnú znakovú sadu.
______________________________________________________
Vaše hodnotenie, Rate post: