SBC6502 - 68 - basic programs - "Battleships".

By Administrator at novembra 07, 2023 13:25
Filed Under: SBC6502

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:

Info o autorovi

Volám sa Igor Gramblička, bydlisko: Bratislava, Slovakia. Môj nick: Igi. Blog je o mojich záujmoch, predtým som pracoval ako IT špecialista na počítačové siete a redakčné systémy pre viaceré denníky - až som pred rokmi nakoniec v jednom z nich zakotvil a kde som to potiahol až do konca mojej profesnej kariéry.

Rok, mesiac, počet článkov: