4. AVANCERAD BASIC

4.1 INLEDNING

De närmast följande kapitlen har skrivits för dig som är relativt van vid programspråket BASIC och dess begrepp, vilket är nödvändigt för att första dessa mer avancerade program.

För de av er som just börjat lära programmering, kommer viss information att vara något för teknisk att förstås fullständigt. Bli nu inte orolig... det finns nämligen två roliga kapitel: SPRITE-grafik och SKAPA LJUD där vi gjort enkla exempel som är skrivna för nybörjare. Exemplen kommer att ge dig en god uppfattning om hur man använder Commodore 64's rika möjligheter att skapa sofistikerade ljud och bildprogram.

Om du beslutar att lära dig mer om hur man skriver program i BASIC, finns det lämplig litteratur i ämnet.

4.2 ENKEL ANIMERING

Låt oss öva på några av Commodore 64's grafiska egenskaper genom att utnyttja det vi visat tidigare tillsammans med några nya begrepp. Om du är intresserad kan du skriva in följande program och se vad som händer. Du kommer att upptäcka att inom PRINT-instruktioner kan vi också använda markörstyrnings- och skärmkommandon. När du ser något liknande (CRSR vänster) i en programlista, tryck ned SHIFT-tangenten och tryck på CRSR-tangenten. Bildskärmen visar då det grafiska tecknet för markörförflyttning ett steg vänster (två reverserade vertikala balkar). På samma sätt visas, om man trycker SHIFT och CLR/HOME, ett reverserat hjärta.

  NEW

  10 REM STUDSANDE BOLL
  20 PRINT"{clear}":REM SHIFT+CLR HOME
  25 FOR X = 1 TO 10 : PRINT"{down}" :NEXT
  26 REM "{down}"=CRSR-NED
  30 FOR BL=1 TO 40
  40 PRINT" Q{left}"; :REM "Q"=shift+q
  41 REM "{left}"=CRSR-VÄNSTER
  50 FOR TM = 1 TO 5
  60 NEXT TM
  70 NEXT BL
  75 REM FLYTTA BOLLEN HÖGER - VÄNSTER
  80 FOR bl = 40 TO 1 STEP -1
  90 PRINT " {left*2}Q{left}";:REM CRSR VÄNSTER,CRSR VÄNSTER,BOLL,CRSR VÄNSTER
  100 FOR TM = 1 TO 5
  110 NEXT TM
  120 NEXT BL
  130 GOTO 20
(Hämta)

ANM: ':' på rad 25 indikerar ny instruktion. Mellanrummen på rad 40 och 90 är avsiktliga.

TIPS:

Alla ord i denna text skrivs ut i en följd. Så länge som du inte trycker på RETURN kommer Commodore 64 automatiskt att vid radslut byta till nästa rad även mitt i ett ord.

Detta program visar en studsande boll som rör sig fram och tillbaka Över skärmen.

Om vi studerar programmet noga, (se nedan) kan du se hur detta utfördes..

       10 REM STUDSANDE BOLL
+----→ 20 PRINT"{clear}":REM SHIFT+CLR HOME
|      25 FOR X = 1 TO 10 : PRINT"{down}" :NEXT
|      26 REM "{down}"=CRSR-NED
| +--→ 30 FOR BL=1 TO 40
| |    40 PRINT" Q{left}"; :REM "Q"=shift+q
| |    41 REM "{left}"=CRSR-VÄNSTER
| | +> 50 FOR TM = 1 TO 5
| | +- 60 NEXT TM
| +--- 70 NEXT BL
|      75 REM FLYTTA BOLLEN HÖGER - VÄNSTER
| +--→ 80 FOR bl = 40 TO 1 STEP -1
| |    90 PRINT " {left*2}Q{left}";:REM CRSR VÄNSTER,CRSR VÄNSTER,BOLL,
| |    CRSR VÄNSTER
| | +> 100 FOR TM = 1 TO 5
| | +- 110 NEXT TM
| +--  120 NEXT BL
+----  130 GOTO 20

Rad 10 är en REMark (kommentar) som enbart berättar vad programmet gör. Den har ingen inverkan på det egentliga programmet. Rad 20 raderar skärmen på all information.

Rad 25 skriver 10 st markör-nedåt kommando. Detta styr bollen till mitten av skärmen. Om rad 25 utelämnas skulle bollen röra sig över översta raden på skärmen.

Rad 30 startar en loop (slinga) för att flytta bollen 40 kolumner från vänster till höger.

Rad 40 utför en hel del. Först skrivs ett mellanslag för att radera den tidigare bollpositionen, därefter skrivs bollen ut och slutligen utförs markör vänster-förflyttning för att förbereda nästa radering av bollpositionen.

Slingan, som startas i rad 50 och 60, minskar bollens hastighet genom att fördröja programmet. Utan fördröjning skulle bollen röra sig för fort för att synas.

Rad 70 avslutar slingan, som ritar bollen på skärmen, vilken startade på rad 30.

Varje gång som slingan genomlöps flyttas bollen ytterligare ett steg till höger. Som du ser av illustrationen har vi åstadkommit en slinga inom en annan. Detta kallas en kapslad slinga (nested loop).

Detta accepteras av datorn. Den enda gång du får problem är när slingorna korsar varann. Vi rekommenderar att du kontrollerar program med flertal slingor på detta sätt.

För att se vad som händer om du korsar två slingor, byt instruktionerna på rad 60 och 70. Du kommer att få felindikering (error) då datorn blir förvirrad och inte kan för stå vad som händer.

Rad 80 till 120 gör samma sak som i första delen av programmet men med omvänd funktion. Bollen flyttas nu från höger till vänster. Rad 90 är lätt förändrad jämfört med rad 40 eftersom bollen ska röras i motsatt riktning (vi måste radera bollen till höger och flytta åt vänster).

När allt detta är utfart ger programmet tillbaka till rad 20 och startar om på nytt. Ganska händigt!

En variant på programmet kan erhållas om du ändrar rad 40 enligt följande:

40 PRINT "O" ← För att åstadkomma O håll ned SHIFT och tryck på bokstaven
               Q.
kör programmet och se vad som händer. Eftersom vi utelämnade markörkontrollerna kommer alla bollarna att bli kvar på skärmen tills dess de raderas av bollen när den rör sig från höger till vänster i andra delen av programmet.

4.3 INPUT

Allt inom ett program har hittills varit bestämt innan det körts. När programmet väl var startat kunde inget ändras. INPUT tillåter dig att förmedla information under tiden programmet körs. Programmet kan alltså bearbeta eller reagera på den nya informationen under körning.

För att du ska få en idé om hur INPUT arbetar, skriv NEW och skriv in detta korta program:

  10 INPUT A$
  20 PRINT "DU SKREV: ";A$
  30 PRINT
  40 GOTO10

  RUN
  ? COMMODORE 64  ←------------- Du skrev
  DU SKREV: COMMODORE 64    ←--- Datorn svarade

Vad som händer när du kör detta korta program är enkelt. Ett frågetecken visar sig. Detta indikerar att datorn väntar att du ska skriva in något. Skriv vilket som helst tecken eller grupp av tecken och tryck RETURN. Datorn kommer att svara med "DU SKREV:" följt av det du skrev in. Detta kan verka mycket elementärt men föreställ dig vad du kan få datorn att göra med information du skriver in.

Du kan använda INPUT för numeriska värden eller textsträngar och även få INPUT-kommandot att skriva ut ett meddelande till användaren. INPUT skrivs i följande form:

  INPUT "MEDDELANDE"; VARIABEL
         ↑
         +---- Meddelande måste vara mindre än 40 tecken!
Eller enbart:
  INPUT VARIABEL
OBS. För att avbryta detta program tryck på RUN/STOP och RESTOR samtidigt.

Följande är inte endast användbart, utan demonstrerar dessutom en hel del av vad som presenterats tidigare, inklusive det nya INPUT-kommandot.

  NEW

  1 REM TEMPERATUR-OMVANDLINGS-PROGRAM
  5 PRINT "{clear}" : REM SHIFT+CLR HOME
  10 PRINT "OMVANDLA FRÅN FARENHEIT ELLER CELSIUS":INPUT "(F/C)";a$
  20 IF A$ = "" THEN 5
  30 IF A$ = "F" THEN 100
  40 IF A$ <> "C" THEN 10
  50 INPUT "ANTAL GRADER CELSIUS: "; C
  60 F = (C*9)/5+32
  70 PRINT C ; "GRAD. CELSIUS ="; f;"GRAD. FARENHEIT"
  80 PRINT
  90 GOTO 10
  100 INPUT "ANTAL GRADER FAHRENHEIT: "; F
  110 C = (F-32)*5/9
  120 PRINT F ; "GRAD. FARENHEIT ="; c; "GRAD. CELSIUS"
  130 PRINT
  140 GOTO 10
(Hämta)

ANM: Inget mellanslag mellan citationstecknen på rad 20. Glöm inte trycka RETURN efter raderna.

Om du skriver in och kör detta program får du se INPUT-kommandot i aktion.

Rad 10 använder INPUT-kommandot inte enbart för att hämta information utan också för att skriva ut ett uppmanande meddelande. Lägg också märke till att vi kan fråga efter antingen ett siffervärde eller en textsträng (genom att använda numerisk eller sträng-variabel).

Raderna 20, 30 och 40 gör vissa kontroller av vad som skrivits in. På rad 20, om inget skrivits in men RETURN tryckts, återgår programmet till rad 10 och begär ny inskrift. På rad 30, om F är inskrivet, vet vi att användaren önskar få en temperatur i Fahrenheit omvandlad till Celsius, varför programmet grenas av till den del som utför denna omvandling.

Rad 40 gör ytterligare en kontroll. Vi vet att det finns enbart två giltiga val som användaren kan skriva in. For att komma till rad 40 måste användaren skrivit ett tecken annat än F. Nu görs en koll om tecknet är C, om inte begär programmet en ny INPUT.

Detta verkar vara en massa detaljer, men är god programmeringspraxis. En användare som inte är van vid programmet kan bli mycket irriterad om programmet gör något oväntat beroende på inmatningsfel.

Så fort vi bestämt vilken typ av omvandling vi önskar, utförs beräkningen av programmet och datorn skriver ut den inskriva temperaturen tillsammans med den omvandlade temperaturen.

Beräkningen är enbart vanlig matematik, med användning av den kända formeln för temperaturomvandling. Efter att beräkningen och utskriften är klar hoppar programmet tillbaka och startar på nytt.

Efter att programmet körts kan skärmen se ut så här:

  OMVANDLA FRÅN FAHRENHEIT ELLER CELSIUS
  (F/C) ?F
  ANTAL GRADER FAHRENHEIT: 32
  32 GRAD. FAHRENHEIT= 0 GRAD. CELSIUS

  OMVANDLA FRÅN FAHRENHEIT ELLER CELSIUS
  (F/C) ?

Efter att du kört programmet kan du spara det på flexskiva eller band. Detta program såväl som andra som visas i denna bruksanvisning kan bilda grunden för ditt eget programbibliotek

4.4 GET

GET möjliggör hämtning av ett tecken i taget från tangentbordet utan att man behöver trycka på RETURN. Detta ökar i många fall hastigheten vid inmatning av data. Den tangent du trycker ned, tilldelas den variabel du angett efter GET.

Följande rutin visar hur GET fungerar:

  NEW

  1 PRINT "{clear}"
  10 GET A$: IF A$= "" THEN 10
  20 PRINT A$;
  30 GOTO 10
(Hämta)

ANM: Inget mellanslag mellan citationstecknen på rad 10

Om du kör programmet, rensas skärmen och varje gång du trycker på en tangent, skriver rad 20 ut tecknet på skärmen. Därefter väntar programmet på rad 10 till dess du trycker ned nästa tangent. Det är viktigt att lägga märke till att de inmatade tecknen inte visas på skärmen såvida du inte uttryckligen begär det genom PRINT-kommandot, så som vi gjort har.

Den andra instruktionen på rad 10 är också betydelsefull. GET-instruktionen utförs kontinuerligt, även om ingen tangent trycks ned, (till skillnad från INPUT som väntar på ett svar). Den andra instruktionen kontrollerar alltså tangentbordet till dess en tangent trycks ned.

Undersök vad som händer om den andra instruktionen på rad 10 tas bort. Detta program kan stoppas med RUN/STOP och RESTORE nedtryckta samtidigt. Den första delen av temperaturomvandlingsprogrammet kan lätt skrivas om till GET-kommando. Hämta (LOAD) temperaturprogrammet och ändra raderna 10, 20 och 40 enligt nedan:

  10 PRINT "OMVANDLA FRÅN FAHRENHEIT ELLER CELSIUS (F/C)"
  20 GET A$:IF A$ = "" THEN 20
  40 IF A$ <> "C" THEN20

Denna förändring ger att programmet fungerar smidigare, eftersom inget händer såvida användaren inte skriver in önskat svar, F eller C.

När denna förändring gjorts är det lämpligt att spara den nya versionen av programmet.

4.5 SLUMPTAL OCH ANDRA FUNKTIONER

Commodore 64 innehåller ett antal funktioner som används för att utföra speciella uppgifter. Funktioner kan liknas vid ett speciellt program inbyggt i BASIC. Istället för att skriva in ett antal instruktioner varje gång du vill utföra en speciell beräkning, räcker det med att du skriver kommandoordet för den önskade funktionen varefter datorn sköter resten.

Många gånger när du ger ett spel eller utbildningsprogram, behöver du skapa ett slumptal, exempelvis för att simulera ett tärningskast. Du kan givetvis skriva ett program som skapar dessa slumptal, men ett enklare sätt är att anropa RaNDom number (slumptal) funktionen.

För att utröna vad RND verkligen gör. Prova följande korta program:

  NEW

  10 FOR X = 1 TO 10
  20 PRINT RND(1), ← Om du utelämnar komma skrivs siffrorna ut i en rad
  30 NEXT

Efter du kört programmet kommer skärmen att se ut ungefär så här:

  .789280697          .664673958
  .256373663          .0123442287
  .682952381          3.90587279E-04
  .402343724          .879300926
  .158209063          .245596701

Dina siffror passar inte? Om dom passat vore det väl underligt då de är helt slumpmässigt utvalda!

Prova med att köra programmet några gånger för att övertyga dig om att resultatet är annorlunda varje gång. Även om talen inte följer ett bestämt mönster, kommer du att märka att vissa saker blir samma varje gång programmet körs.

För det första blir resultatet alltid mellan 0 och 1 men aldrig 0 eller 1. Detta passar oss inte om vi vill simulera ett slumpmässigt tärningskast. Vi letar efter siffror mellan 1 och 6.

Den andra viktiga egenskapen vi ser är att vi handskas med decimaltal (med decimalkomma). Även detta kan vara ett problem då det ofta behövs enbart heltal.

Det finns ett antal enkla sätt att erhålla siffror i det område vi önskar från RND-funktionen.

Ersätt rad 20 med följande och kör programmet på nytt.

  20 PRINT 6*RND(1),

  RUN

  3.60563664          4.53660853
  5.47238963          8.40850227
  3.19265054          4.39547668
  3.16331095          5.50620749
  9.32527884          4.17090293

Detta löste problemet med att få resultat större än 1, men vi har fortfarande decimalerna att handskas med. Nu måste vi använda oss av en annan funktion.

INTeger (heltal)-funktionen omvandlar decimaltal till heltal.

Byt på nytt ut rad 20 med följande och kör programmet så ser du vad som förändrats.

  20 PRINT INT(6*RND(1)),

  RUN

  2         3         1         0
  2         4         5         5
  0         1

Detta löste en hel del. Vi kom närmare vårt mål att skapa slumptal mellan 1 och 6. Om du tittar efter noga så ser du att resultatet är inom området 0 till 5.

Som ett sista steg, addera 1 till instruktionen enligt följande:

  20 PRINT INT(6*RND(1))+1,

Nu har vi erhållit det önskade resultatet..

Rent allmänt kan du placera ett tal, en variabel, eller något BASIC-uttryck inom parenteserna till INT-funktionen. Beroende på önskat område multiplicerar du den övre gränsen med RND-funktionen. Om du exempelvis vill generera ett slumptal mellan 1 och 25, kan du skriva:

  20 PRINT INT(25*RND(1))+1

Den allmänna formeln för att generera ett slumptal inom ett bestämt område är:

SLUMPTALET = INT (Undre gräns + (övre-undre + 1) * RND(x))

4.6 GISSNINGSSPEL

Då vi nu kommit en bit på vägen att förstå slumptal, utnyttjar vi detta. Följande spel visar på ett användningsområde för slumptal och bjuder oss dessutom på ytterligare programmeringsteori.

  1 REM NUMMERGISSNINGS-SPEL
  2 PRINT"{clear}":REM CLR+SHIFT
  5 INPUT"ÖVRE GRÄNS FÖR TALET";LI
  10 NM=INT(LI*RND(1))+1
  15 CN=0
  20 PRINT"JAG HAR ETT TAL."
  30 INPUT"VAD GISSAR DU";GU
  35 CN=CN+1
  40 IF GU > NM THENPRINT"MITT TAL ÄR LÄGRE":PRINT:GOTO30
  50 IF GU < NM THENPRINT"MITT TAL ÄR STÖRRE":PRINT:GOTO30
  60 IF GU = NM THENPRINT"BRA!DU FICK MITT NUMMER"
  65 PRINT"EFTER ";cn;"GISSNINGAR.":PRINT
  70 PRINT"VILL DU GISSA MER ? (J/N)";
  80 GET AN$:IF AN$=""THEN 80
  90 IF AN$="J"THEN 2
  100 IF AN$<> "N" THEN 80
  110 END
(Hämta)

När du kör detta program skapas ett slumptal, NM.

Du kan bestämma hur stort talet får bli i början av programmet. Sedan är det din uppgift att gissa vilket talet är.

En provkörning följer tillsammans med en förklaring:

  ÖVRE GRÄNS FÖR TALET? 15
  JAG HAR ETT TAL.
  VAD GISSAR DU? 10
  MITT TAL ÄR LÄGRE

  VAD GISSAR DU? 5
  MITT TAL ÄR LÄGRE

  VAD GISSAR DU? 3
  BRA!DU FICK MITT NUMMER
  EFTER  3 GISSNINGAR.

IF/THEN-instruktionen jämför det tal du gissat med det framtagna slumptalet. Beroende på vad du gissat skriver datorn om det är större eller mindre än slumptalet.

Prova om du med hjälp av formeln för slumptal kan lägga till några rader i programmet så att du också kan bestämma den undre gränsen på slumptalen.

Varje gång du gissar ökar DN med 1 för att hålla reda på hur många gånger du gissat. När du använder programmet försök genom att fråga logiskt komma fram till rätt svar på minsta möjliga antal försök.

När du gett rätt svar skriver datorn ut "BRA! DU FICK MITT NUMMER", tillsammans med uppgift om det antal gissningar som behövdes. Du kan därefter starta på nytt. Programmet tar fram ett nytt slumpmässigt utvalt tal varje gång.

PROGRAMTIPS:

På raderna 40 och 50 används ett kolon för att Åtskilja flera instruktioner på samma rad. Detta sparar inte enbart skrivarbete, utan i långa program sparar det även minnesutrymme.

Lägg också märke till IF/THEN instruktionen på samma rader. Där vi instruerar datorn att skriva (PRINTa) något istället för att direkt grena ut till någon annan punkt i programmet.

Den sista punkten visar på orsaken till att skriva radnummer i steg om 10:

Efter programmet var skrivet beslöts att lägga till räknedelen. Genom att helt enkelt lägga till dessa nya rader i slutet av programmet, med radnummer som passar in mellan befintliga rader, var det enkelt att modifiera programmet.

4.7 DITT KAST

Följande program simulerar kast med 2 tärningar. Du kan använda det som det är eller som del i ett större program.

   5 PRINT "VILL DU PRÖVA LYCKAN?"
  10 PRINT "RÖD TÄRNING =";INT(6*RND(1))+1
  20 PRINT "VIT TÄRNING =";INT(6*RND(1))+1
  30 PRINT "TRYCK MELLANSLAGSTANGENTEN FÖR NYTT KAST" : PRINT
  40 GET A$ : IF A$ = "" THEN 40
  50 IF A$ = CHR$(32) THEN 10

Är du beredd att pröva lyckan?

Med hjälp av vad du lärt om slumptal och BASIC, se om du kan förstå vad som händer.

4.8 SLUMPMÄSSIG GRAFIK

Som en avslutning på slumptal, och som en introduktion till hur man konstruerar grafik, ta och skriv in och kör följande korta program.

  10 PRINT"{clear}"
  20 PRINT CHR$(205.5 + RND(1));
  30 GOTO 20
(Hämta)

Som du kanske väntat dig är rad 20 nyckelraden. Ytterligare en ny funktion, CHR$ (teckensträng), getr dig ett tecken, baserat på ett standardiserat kodnummer från 0 till 255. Alla tecken Commodore 64 kan skriva är kodade på detta sätt. Se bilaga F.

För att få reda på koden för något tecken, skriv:

  PRINT ASC("X")
där X är det tecken du frågar på. Detta kan vara alla skrivbara tecken, inklusive grafik. Svaret är koden för det tecken du skrev. Som du antagligen redan räknat ut är "ASC" ännu en funktion, vilken ger tillbaka den standardiserade "ASCII"-koden för det tecken du skrev. Du kan nu skriva ut tecknet genom att skriva:
  PRINT CHR$(X)

Om du skriver:

  PRINT CHR$(205); CHR$(206)
kommer du se de två grafiska tecknen som finns till höger på M- och N-tangenterna. Detta är de två tecken som programmet använder till labyrinten.

Genom att använda formeln 205.5+RND(1) använder datorn slumptal mellan 205.5 till 206.5. Detta ger 50% chans att talet är över eller under 206. CHR$ ignorerar decimaldelen av talen så att halva tiden skrivs tecknet med koden 205 ut och den återstående tiden skrivs tecknet med koden 206.

Om du vill experimentera med detta program, kan du prova med att ändra 20.5 genom att addera eller subtrahera några tiondelar. Detta kommer att ge endera tecknet en större chans att bli utvalt.

[ ← Föregående | Innehållsförteckning | Nästa → ]
[HTML 4.01]
Peter Krefting / $Date: 2009-10-08 13:34:08 $ / peter@softwolves.pp.se