FAST.BAS : "Rasen mit 310 Km/h" in BASIC - sollte eigentlich ein 10-Zeiler werden, aber da es dann auch spielbar und mit Anreiz sein sollte, sind es 13 Zeilen geworden

  • Mit "Rasen" meine ich "Schnell fahren", nicht das grüne Zeugs ;-)


    Wollte mich eigentlich am Wettbewerb beteiligen, aber dann habe ich die Einschränkung auf 8-Bitter gesehen.
    Also sind es 13 Zeilen mit max. 80 Zeichen Länge geworden. Ziel war die Spielbarkeit, und die Portabilität auf mindestens jeden PC (keine CPU-Speed Abhängigkeit).


    Gespielt wird es (nach Start mit "RUN" im Interpreter) mit den Tasten "n" und "m" (ja, und nur mit den Kleinbuchstaben!). Abbruch mit "q" möglich.


    Hier der Source-Code, frei kopierbar und abänderbar wie ihr wollt, solange ihr die ursprüngliche Quelle (mich) angibt:


    10 DEFINT A-Z:RANDOMIZE TIMER:D!=TIMER:S=RND*40!+20:C=S+4:O=C:CLS
    20 LOCATE 11,1:FOR I=1 TO 12:PRINT SPC(S);"|";SPC(10);"|":NEXT I:Z=0:V!=.3
    30 R=RND*7:IF R<3 THEN M=-1 ELSE IF R=3 THEN M=0 ELSE M=1
    40 LOCATE 2,1:PRINT "KM:";Z;" Vmax:";310-CINT(V!*1000!):S=S+M
    50 LOCATE 23,1:IF S>58 THEN S=58 ELSE IF S<1 THEN S=1
    60 PRINT SPC(S%);"|";SPC(10);"|";" ":PRINT:Z=Z+10:T=SCREEN(10,C):LOCATE 10,C
    70 PRINT "*";:LOCATE 9,O:PRINT " ";:IF T<>32 THEN LOCATE 3,1:PRINT "CRASH!"
    80 IF T<>32 THEN SOUND 37,5:LOCATE 23,1:END ELSE O=C:IF TIMER<D!+1 THEN 110
    90 IF V!>.1 THEN V!=V!-.01 ELSE IF V!>.05 THEN V!=V!-.005 ELSE V!=V!-.001
    100 D!=TIMER:SOUND Z/10+100,2:IF V!<0 THEN V!=0
    110 K$=INKEY$:T!=TIMER+V!:WHILE TIMER<T!:WEND
    120 IF K$="" THEN 30 ELSE IF K$="n" THEN C=C-1 ELSE IF K$="m" THEN C=C+1
    130 IF K$="q" THEN LOCATE 23,1:END ELSE 30:REM (C) P.DASSOW


    Hier auch mal ein Screenshot mit einem real erspielten Highscore (Uff!), DOSBOX als Emulator, BASICA 3.30 als Basic-Variante (GWBASIC geht natürlich auch):


    P.S.: Jetzt auch als kompilierte EXE (im ZIP) anbei.

  • Sehr schön! Gratuliere!


    Wenn du magst, kann ich den Code auf unserer Zusatz-Webseite für den demnächst erscheinenden Katalog zum OCM posten. Den sollen die Museumsbesucher eingeben, um ein wenig über die Systeme dort zu lernen.

  • Klar, gerne.


    Auf Rechnern ab 286 läuft es ganz manierlich, bei einem PC/XT oder auch bei einem Schneider PC 1512 ist es in der "Endstufe" etwas langsamer als gewollt.


    Werde ich also noch so abändern, dass es auch auf den ganz langsamen PCs am Schluss schwierig wird ;-)


    Gruss Peter


    P.S.: Da ich ein fauler Mensch bin, habe ich erstmal jede Menge BASIC-Compiler ausprobiert, um auch auf dem XT oder Schneider PC es schnell genug laufen lassen zu können.
    Anbei also das Kompilat, was auch auf den langsamen PCs schnell genug läuft, dass es am Schluss eine echte Herausforderung wird...

    Dateien

    • FAST-TB.zip

      (24,84 kB, 32 Mal heruntergeladen, zuletzt: )

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

    Dieser Beitrag wurde bereits 1 Mal editiert, zuletzt von Peter z80.eu ()

  • Das kann dann im Museum auf einem 386 programmiert werden.

  • P.S.: Da ich ein fauler Mensch bin, habe ich erstmal jede Menge BASIC-Compiler ausprobiert, um auch auf dem XT oder Schneider PC es schnell genug laufen lassen zu können.
    Anbei also das Kompilat, was auch auf den langsamen PCs schnell genug läuft, dass es am Schluss eine echte Herausforderung wird...


    Das Zusammensetzen der Printzeile (60) dürfte wesentlich flotter sein, wenn man das einmal als fixen String printed und nicht in jedem Durchlauf neu zusammenbastelt.


    Die Abfrage aud T<>32 in (70) und (80) kosten ohne Ende Zeit und können prima durch einen einzigen Sprung ans echte Ende auf ein IF verkürzt werden. Der ELSE Teil in (80) ist prinzipiell unnötig, weil es beim Crash auch egal ist, ob da nochmal eine Variable gerettet wird, sonst aber kostet das bei jeder Runde viel Zeit.



    Die KeyAbfrage wird auch flotter, wenn die Keys einzeln behandelt werden und dann direkt gejumped wird. Also nicht so ein SchachtelELSE, sondern eher
    120 IF K$="" THEN 30
    125 IF K$="n" THEN C=C-1 : GOTO 30
    126 IF K$="m" THEN C=C+1 : GOTO 30


    Zumindest, wenn das IF dann noch bis zum Zeilenende gilt.
    Außerdem dürfte Abfragen der CHR$ Codes schneller sein als "Tastenkappenbezeichnungen" auszuwerten. Vermutlich mit INKEY ?


    Noch schneller sollte dort so eine Konstruktion sein, wie
    C=C+1 : IF K$="n" C=C-2 : GOTO 30
    unter Verzicht auf den Abbruch mit q, was auch OK ist, da man ja definiert abbrechen kann, indem man in die Bande rast.


    Ansonsten funktioniert das wirklich schon ganz nett (DOSBOX) und lange bleibt man da nicht unterwegs ... öhem, nun ja ... muß wohl mal die Hand-Keyboard-Koordination wieder ein wenig üben.


  • Hallo,


    es ging um die Größe des gesamten Listings bzw. die Anzahl der Zeilen, und nicht um Eleganz - Du hast da was VÖLLIG MISSVERSTANDEN.


    Sicherlich kannst Du Dir vorstellen, dass ich vor dem "Verkleinern" mehr Programmzeilen hatte, und das Ganze auch effizienter gestaltet war (ich kenne natürlich BASIC, und sicherlich kann man z.B. zwei gleiche "IF" Abfragen auch zusammenfassen - nur dadurch wäre die Zeile zu lang geworden, also mehr als 80 Zeichen). Ich hätte für den Wettbewerb sowie eine andere Art der Beschränkung ausgewählt, keine Zeilenanzahl, sondern die Größe von 1KB wäre meine Grenze gewesen. Dann hätte ich auch viele Dinge einfacher gestalten können, auch wenn die Zeile dadurch länger als 80 Zeichen wird. Und zur Zeile 60 - nein, da kannst Du nichts zu einem fixen String zusammenfassen, weil ja jedesmal die Position der "Strasse" neu bestimmt wird.


    Ich kann auch gerne eine geschwindigkeitsoptimierte Version noch posten, aber die wird dann definitiv mehr Zeilen haben - das war aber vorrangig nicht mein Ziel gewesen.


    Gruss Peter


    P.S.: Diese Version ist geschwindigkeitsoptimiert, aber das macht derart wenig aus, dass es die Mühe nicht lohnt:


    10 DEFINT A-Z:RANDOMIZE TIMER:D!=TIMER:S=RND*40!+20:C=S+4:O=C:CLS
    20 LOCATE 11,1:FOR I=1 TO 12:PRINT SPC(S);"|";SPC(10);"|":NEXT I:Z=0:V!=.3
    30 R=RND*7:IF R<3 THEN M=-1 ELSE IF R=3 THEN M=0 ELSE M=1
    40 LOCATE 2,1:PRINT "KM:";Z;" Vmax:";310-CINT(V!*1000!):S=S+M
    50 LOCATE 23,1:IF S>58 THEN S=58 ELSE IF S<1 THEN S=1
    60 PRINT SPC(S%);"| |";" ":PRINT:Z=Z+10:T=SCREEN(10,C):LOCATE 10,C
    70 PRINT "*";:LOCATE 9,O:PRINT " ";:IF T=32 THEN O=C:IF TIMER<D!+1 THEN 110 ELSE 90
    80 LOCATE 3,1:PRINT "CRASH!":SOUND 37,5:LOCATE 23,1:END
    90 IF V!>.1 THEN V!=V!-.01 ELSE IF V!>.05 THEN V!=V!-.005 ELSE V!=V!-.001
    100 D!=TIMER:SOUND Z/10+100,2:IF V!<0 THEN V!=0
    110 K$=INKEY$:T!=TIMER+V!:WHILE TIMER<T!:WEND
    120 IF K$="" THEN 30
    130 IF K$="n" THEN C=C-1:GOTO 30
    140 IF K$="m" THEN C=C+1:GOTO 30
    150 IF K$="q" THEN LOCATE 23,1:END

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

    Dieser Beitrag wurde bereits 3 Mal editiert, zuletzt von Peter z80.eu ()

  • es ging um die Größe des gesamten Listings bzw. die Anzahl der Zeilen ... Sicherlich kannst Du Dir vorstellen, dass ich vor dem "Verkleinern" mehr Programmzeilen hatte, und das Ganze auch effizienter gestaltet war (ich kenne natürlich BASIC ...


    Tja, und ich hatte angenommen, daß es jetzt - nachdem das Ganze in der Form gar nicht eingereicht worden ist - noch darum ginge, da ein wenig mehr Speed herauzukitzeln. Zumal das ja oben auch mal so angedeutet worden ist:


    Auf Rechnern ab 286 läuft es ganz manierlich, bei einem PC/XT oder auch bei einem Schneider PC 1512 ist es in der "Endstufe" etwas langsamer als gewollt.


    ... hätte für den Wettbewerb sowie eine andere Art der Beschränkung ausgewählt, keine Zeilenanzahl, sondern die Größe von 1KB wäre meine Grenze gewesen. Dann hätte ich auch viele Dinge einfacher gestalten können, auch wenn die Zeile dadurch länger als 80 Zeichen wird.


    Die Größengrenzen sind halt einfach üblicher. 80 Zeichen finde ich ja schon deshalb interessant, weil es mal was Neues für solche Wettbewerbe ist (kannte ich zumindest noch nicht als Vorgabe) und man kann dann die Listing schön lesen und gut ausrucken - auch wenn das auf Retina und 4K Displays relativiert wird


    Und zur Zeile 60 - nein, da kannst Du nichts zu einem fixen String zusammenfassen, weil ja jedesmal die Position der "Strasse" neu bestimmt wird.


    Na, wenn Du meinst.


    Ich kann auch gerne eine geschwindigkeitsoptimierte Version noch posten, aber die wird dann definitiv mehr Zeilen haben - das war aber vorrangig nicht mein Ziel gewesen.


    Würde ich gut finden. Gucke ich mir gerne an und vielleicht ja der ein oder andere auch. Sowas ist meist ganz spannend, insbesondere im Vergleich vorher / nachher und in Relation zum dadurch erreichten Effekt.


  • [...]


    Würde ich gut finden. Gucke ich mir gerne an und vielleicht ja der ein oder andere auch. Sowas ist meist ganz spannend, insbesondere im Vergleich vorher / nachher und in Relation zum dadurch erreichten Effekt.


    Na dann schau mal in mein vorheriges Posting. Ansonsten, wenn das hier in Stress ausartet, mache ich so was lieber in meinem Blog publik.
    Dann schreibe doch einfach mal selbst ein Spiel mit derart wenig Zeilen und zeig' mir dann damit, wie es besser geht...

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Nachtrag: Beim Kopieren der letzten Zeile der "geschwindigkeitsoptimierten" Version ist etwas verloren gegangen. Die letzte Zeile soll heissen: 150 IF K$="q" THEN LOCATE 23,1:END ELSE 30

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Ich hätte Lust, das ganze mal in das puristischere Commodore Basic zu übersetzen, um es mal auf meinem Lieblingsrechner auszuprobieren.
    Daher ein paar Fragen zum hier verwendeten Basic:
    Was hat es mit DEFINT A-Z auf sich?
    Was beduten die Variblennamen mit Ausrufezeichen?
    Wie funktioniert TIMER?


    Gruß
    Christian

  • Was hat es mit DEFINT A-Z auf sich?
    Was beduten die Variblennamen mit Ausrufezeichen?


    Mit DEFINT werden alle danach aufgeführten Variablen als Integer definiert.
    Das Ausrufezeichen macht im Prinzip dasselbe für diejenige Variable, hinter der es steht.

  • Die Erklärung von Microprofessor sind absolut korrekt, wenn Du hinter den Variablennamen ein % anhängst, sind diese vom Typ INTEGER, wenn Du ein ! anhängst, sind diese vom Typ FLOAT/DOUBLE.
    Das macht man, um genau an den Stellen die Variablentypen zu nutzen, die tatsächlich nur benötigt werden. INTEGER Variablen sind normalerweise wesentlich schneller vom BASIC Interpreter abgearbeitet.
    Das $ hinter String-Variablen kennst Du ja sicherlich bereits.


    Du kannst prinzipiell alle TYP-Definitionen in BASIC weglassen, dann wird die Abarbeitung der Operationen mit den Variablen langsamer, und vielleicht das eine oder andere Mal auch nicht so, wie man es will (z.B. bei INTEGER = keine Nachkommastellen).


    TIMER beinhaltet prinzipiell die Uhrzeit in einer bestimmten Einheit (wesentlich kleiner als 1 Sek). Das kannst Du ausprobieren, indem Du einfach in einem BASIC-Interpreter auf dem PC schnell hintereinander PRINT TIMER und dann erneut PRINT TIMER eingibst.
    Genau gesagt ist TIMER die Anzahl der Sekunden seit Mitternacht/System-Reset, aber nicht als 16-Bit INTEGER, sondern als FLOAT. Daher kommen dann auch Kommazahlenwerte bei der Ausgabe heraus.


    TIMER wird in BASIC Programmen genutzt, um CPU-Speed unabhängig Zeiten abmessen zu können.
    Wenn Du also z.B. ZEIT!=TIMER eingibst, dann eine Sekunde wartest, und dann PRINT TIMER-ZEIT! eingibst, kriegst Du die Differenz von 1 Sek. als FLOAT Zahl ausgegeben.

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

    Dieser Beitrag wurde bereits 1 Mal editiert, zuletzt von Peter z80.eu ()

  • Danke für die Erklärungen.
    Das bedeutet für die Umsetzung, daß ich mit den ganz normalen Gleitkomma-Variablen arbeiten werde, da bei Commodore Basic meines wissens Integer langsamer verarbeitet werden.
    Die Kennzeichnung für Integer ist dabei übrigens auch %.
    Bei Commodore Basic gibt es zwei Variablen für den Timer.
    TI startet beim Rechnerstart mit 0 und wird 60 mal in der Sekunde um 1 erhöht, bei CBM-II Maschinen 10 mal in der Sekunde.
    TI$ enthält die aktuelle Uhrzeit im Format HHMMSS. Da keine Echtzeituhr vorhanden ist, steht sie beim Rechnerstart auf 000000.
    Gestellt wird die Uhr einfach durch eine entsprechende Wertzuweisung der Variable.


    Ich denke, da werde ich mich heute abend mal dransetzen. :)

  • Die fertige Commodore Routine wird dann hier vorgestellt ? Wäre sicher nett, so als Vergleich.


    Ich hatte auch ein paar Sachen nachgucken müssen bezüglich dem M$ Basic (u.a. auch dieses DEFINT) und dabei haben sich diese Seiten als besonders brauchbar erwiesen
    http://www.antonis.de/qbebooks/gwbasman/
    http://www.petesqbsite.com/sec…tutorials/tutorials.shtml


    Das erste ist schön clean und sehr brauchbar (fast wie ein echtes Handbuch) zum schnellen Nachsehen, das zweite eine absonderliche Anhäufung von irgendwie allem rund um das Thema QBasic etc., gut für einge Stunden "einlesen".

  • Ich habe erstmal eine 40-Zeichen Veriante für PET/CBM gemacht.
    Mit der Geschwindigkeit bin ich noch nicht so recht zufrieden, da ist aber noch einiges rauszuholen.
    Die Umsetzung ist bisher noch sehr stark an das Original angelehnt.
    Ich möchte das noch an die CBM-Eigenheiten anpasen.
    Die Fahrbahn ist nur 5 Zeichen breit, damit ist das ganze trotz der eher niedrigen Geschwindigkeit noch etwas fordernd ist.
    Die ganzen {irgendwas} Ausdrücke sind die Commodore-üblichen Cursor-Steuerzeichen.


  • Wow. Wusste gar nicht das der Commodore auch so was wie TIMER hat...
    Die Ausgabe der vielen Zeichen zur Bildschirmsteuerung bremsen das wirklich aus. Kann man beim CBM nicht auch direkt auf die jeweilige Bildschirmposition per POKE schreiben ? Das passende PEEK hast Du ja auch schon genutzt....

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Hier mal eine Geschwindigkeitsoptimierte Version für PET/CBM,
    geeignet für Rechner mit 40 und 80 Zeichen pro Zeile.
    Nebenbei past das ganze jetzt in 10 Zeilen mit jeweils maximal 80 Zeichen.
    Das Programm ist 531 Bytes klein und würde somit auch auf einer Maschine mit 1 kB Ram laufen. :)


    Was ich verändert habe:


    Die Initialisierung ist ans Programmende verschoben.
    Das hat den Vorteil, daß die erste Zeile der Hauptschleife direkt die zweite Programmzeile ist.
    Damit wird diese beim GOTO, das vom Ende der Hauptschleife wieder dorthin zurückspringt, schneller gefunden.
    Beim Commodore Basic wird bei jedem GOTO oder GOSUB die angeforderte Programmzeile vom Anfang des Programms an gesucht.


    Die aufwendigen Cursorpositionierungen sind aus der Hauptschleife fast vollständig rausgeflogen.
    In der Hauptschleife wird über PRINT nur noch die Statuszeile ausgegeben (und vor dem Scrollen wieder gelöscht), und der Cursor einmal eine Zeile nach oben gesetzt.
    Die Statuszeile ist in die unterste Bildschirmzeile gewandert, das Spielfeld endet eine Zeile darüber.
    Dadurch bleibt der Cursor immer in den untersten Zeilen, und muß nicht über den ganzen Bildschirm wandern.
    Nur noch beim initialen Bildaufbau und beim Programmende nach einer Kollision gibt es umfangreichere Cursorpositionierungen.


    Die meisten IF-THEN Verzweigungen bezogen sich auf Berechnungen.
    Das bietet Einsparungspotential: Die Vergleichsoperationen kann man direkt in die Berechnungen einbauen.
    Eine unwahre Bedingung (1>1) hat den Wert 0, eine wahre (1=1) den Wert -1.
    Da muß dann garnicht nicht mehr verzweigt werden.


    Im Originalprogramm wurde die Beschleunigung geschwindigkeitsabhängig mit mehreren IF-THEN Verzweigungen verändert.
    Ich habe stattdessen eine einzelne Formel verwendet, die ebenfalls Geschwindigkeitsabhängig beschleunigt.


    Und schließlich habe ich noch die Abfrage auf die Taste 'Q' zum Beenden entfernt.
    Wenn man vorzeitig beenden will, kann man stattdessen, wie weiter oben schonmal vorgeschlagen, in die Bande fahren.


    Möglicherweise gibt es noch ein minimales Einsparungspotential:
    Ich nehme an, daß der Zugriff auf (numerische) Variablen schneller ist, als auf entsprechende Konstanten im Programmtext, da die Konstanten aus dem Programmtext, bevor sie verwendet werden können, erst in Gleitkommazahlen umgewandelt werden müssen. Somit gäbe es also noch ein paar Prozessortakte rauszukitzeln. :)


    Für weiter Optimierungsideen bin ich durchaus offen. :)

    Code
    1. 0 b=32768:goto7:rem beginn bildschirmspeicher
    2. 1 pokeg+c,160:t=peek(j+c):print"km:"z" v:"int(310-v/.1)"{up}":z=z+10
    3. 2 r=int(rnd(ti)*7):s=s+(r<3)-(r>3):s=s+(s>a)-(s<1):pokek+s,102:pokek+s+f,102
    4. 3 getk$:o=c:ift<>32thenprint"{rvon}{home}{down}{down}{down}{down}{down}{down} * crash * {rvof}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}{down}":end
    5. 4 ifnoththenv=v-(v/25):l=(ti+v):v=-v*(v>.05):h=(v=0)
    6. 5 ifti<lgoto5
    7. 6 c=int(c+(k$="n")-(k$="m")):pokeg+o,32:print" ":goto1
    8. 7 print"{clr}{down}.":e=80+40*(peek(b+40)=46):print"{clr}{down}{down}{down}{down}{down}{down}{down}{down}{down}":g=b+e*10:j=g+e
    9. 8 v=31:f=e/8+1:k=b+e*23:d=ti:s=int(rnd(ti)*e/4+e/8):c=s+f/2+1:a=e-f-3
    10. 9 fori=1to13:printtab(s)"{CBM-+}"spc(f-1)"{CBM-+}":next:print:o=c:goto1
  • Wow. Wusste gar nicht das der Commodore auch so was wie TIMER hat.....


    Doch, doch :-)


    Aber ich glaube mich zu erinnern, dass der schicke Timer von E/A-Operationen (mindetstens) auf externe Geräte gebremst wird.
    Damit würde er (TI und TI$) sich nicht für Zeitmessungen eignen.

  • Zumindest bei den PET/CBM Rechnern laufen TI und TI$ auch bei Disk-Operationen unbeeindruckt weiter.
    Die laufen genauso, wie die z.B. Tastaturabfrage auch, im Interrupt.
    Daher kann man auch während man ein Programm lädt, schonmal blind 'run' in den Tastaturpuffer eingeben.
    Bei den Homecomputern mag das anders sein, das weiß ich nicht.

  • Hut ab.... mach' mal ein Screenshot vom laufenden Spiel auf dem Commodore....


    Davon abgesehen habe ich auch mal was dran geschraubt, aber jetzt war nur der Ausbau der Funktionalität entscheidend, nicht die "Kleinheit" des Programms.
    Bitte ausprobieren....


    Ich habe endlich die Zufälligkeit der Kurven korrekt in den Griff bekommen, und kann dadurch eine echten Schwierigkeitsgrad-Änderung herbeiführen (kurviger oder weniger kurviger).
    Habe auch noch etwas Farbe und Wiese mit Gras hinzugefügt, einen Programmtitel, eine Auswahl am Schluß, und ausserdem die Punktezählung (Score) dem Schwierigkeitsgrad angepasst, den man auswählt ;-)


  • Das mit den TRUE/FALSE Werten ist eine witzige Variante. Habe ich auch schonmal wo gesehen, aber insbesondere die Seitenbegrenzungen damit festzulegen ist schon sehr nett (ich war da auch ein bißchen am Rumbasteln mit s=ABS(s+r) und dann irgendwelchem AND Zeugs zur Begrenzung auf z.B. 63 max. - das da ist aber schon eleganter).


    Allerdings, bei der Zufallsbestimmung der Kurvenrichtung würde wohl auch reichen

    Code
    1. 2 r=int(rnd(ti)*3)-1:s=s+r


    und das Berechnen der aktuellen Geschwindigkeit muß nicht direkt im PRINT Befehl erfolgen (2) (

    Code
    1. int(310-v/.1)

    ) sondern kann auch einmal beim Neufestlegen von v (4) geschehen und in einer Variablen landen.


    Na ja, spart zusammen also 3 Zeichen und 0.2 µsec - ob man das dann Optimierungsidee nennen darf ... ?



    Ach, und: Die grüne Wiese im QBasicEXE macht was her.
    Prinzipiell hat aber noch der Abfragemechanismus (Testen auf Randsymbol bzw. NichtSPACE) das kleine Problem, daß man an bestimmten Stellen die Bahn verlassen kann. Dürfte auch für die CBM Version gelten. Das klappt immer dann, wenn man quasi diagonal durch zwei versetzt übereinanderstehende Striche "rutscht". Einfachste Abhilfe wäre eine doppelte Fahrbahnbegrenzung ( || ), da kann der Rest großenteils unverändert bleiben.

  • Das mit den Kurven kann man dann so lösen, wenn einem das mit der Häufigkeit der Kurven völlig egal ist (also mit RND(TI)*3 oder so, trinäres Ergebnis).
    Im Ungünstigsten Fall hat man dann ein ständiges Hin- und Hergezuckel der Strasse, ohne das wirklich eine grössere Kurve entsteht.


    Da bin ich ganz stolz auf meine neue Lösung, die in meiner erweiterten Version jetzt zum Tragen kommt - da kann ich nämlich die Wahrscheinlichkeit einer Kurve bestimmen, indem ich die Anzahl der Decrements/Increments mitzähle, d.h. im Klartext man muss mehr als einmal nach rechts oder nach links (-1 oder +1) hintereinander wirken lassen, dann wird's auch was mit den Kurven.


    Das mit den Ausbüchsen aus der Begrenzung kannst in meiner neuen Version mal ausprobieren, wird Dich nicht weit bringen, weil Du auf die Grasbüschel ('w') stossen wirst - die wirken nämlich wie die Begrenzung und erzeugen auch einen Unfall ;-)

    "Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind."


    ... und schaut auch mal bei meinem Blog vorbei ...

  • Zitat

    Das bedeutet für die Umsetzung, daß ich mit den ganz normalen Gleitkomma-Variablen arbeiten werde, da bei Commodore Basic meines wissens Integer langsamer verarbeitet werden.


    Wieso das? Versuchshalber habe ich folgendes im VirtualC64 laufen lassen:

    Code
    1. 10 T=TI
    2. 20 FOR ABC=1 to 10000
    3. 30 NEXT
    4. 40 PRINT TI-T


    Als Ergebnis wird 702 ausgegeben.

    Zitat

    Die Kennzeichnung für Integer ist dabei übrigens auch %.


    Selber Versuch mit Integer-Zahlen indem ich Zeile 20 ändere in

    Code
    1. 20 FOR ABC%=1 to 10000


    bekomme ich ein ?SYNTAX ERROR IN 20.

    Code
    1. ABC%=123
    2. PRINT ABC%


    funkioniert aber.


    Um Erleuchtung bittend,
    Mr. AMS (der britische BASIC-Dialekte gewohnt ist)

  • Gute Frage. Im Handbuch hier steht, daß Integer für arithmetische und Vergleichsoperationen in Gleitkomma umgewandelt wird. Deshalb macht es wohl Sinn Integer nur zu verwenden, wenn logische Operationen damit gemacht werden oder Speicherstellen abgebildet werden.


    Zur FOR-NEXT Problematik sagt das Handbuch nur
    "NOTE: You cannot use an integer variable (1%) as the counter variable."


  • Hm... Liegt es evtl. am Variablennamen? Beim C64 kann sowas passieren, wenn man reservierte "Worte" benutzt.
    Oder geht es vielleicht mit Integern% allgemein nicht als Schleifenvariable?