Hallo Besucher, der Thread wurde 19k mal aufgerufen und enthält 122 Antworten

letzter Beitrag von atomcode am

BASIC-Wettbewerb: Blaues Kreuz (kleinstes PRG)

  • Ich glaube, Geschwindigkeiten könnte man bei einem Wettbewerb problemlos angeben, wenn es darum geht.

    Aber sollte man bei solchen Wettbewerben, bei denen es um die Größe geht, diese wirklich angeben? Hat Vor- und Nachteile.


    Ich hab noch eine Funktionsbeschreibung zu meiner Lösung erstellt.


    Was bedeutet Nur-PRINT? Nur, dass man das Zeichen mit PRINT ausgibt, statt mit POKE in den Bildschirmspeicher zu schreiben? Wäre also das Positionieren über Adresse 211/214 erlaubt?

  • Was bedeutet Nur-PRINT? Nur, dass man das Zeichen mit PRINT ausgibt, statt mit POKE in den Bildschirmspeicher zu schreiben? Wäre also das Positionieren über Adresse 211/214 erlaubt?

    Ich habs zu schwammig formuliert als ich die "Print Only" Version ins Spiel gebracht habe.

    Es sollte eine Lösung sein ohne die Formel zu benutzen, weil ich die als ich meine erste "Print Only" Version fertig hatte noch nicht kannte ( und mich doch dann so "aufgeregt" habe das es da eine Formel für das X gibt, weil ich zu spät auf den Assembler Link geklickt hatte ).

    3 Pokes wird man brauchen habe ich in einem weiteren Posting geschrieben... 2x Farbe, 1x Bildschirm "festhalten"

    Der 211/214 Ansatz baut ja "nur" den Screen-Adress Poke nach!

    logiker hat schon geschrieben das er in seiner "Print only" Version die Formel nicht benutzt, mein Ansatz zwar fast 3mal so lang wie logiker Lösung nutzt die Formel auch nicht!

    Stand bis jetzt bei "Print Only"
    logiker 112 Bytes
    ddb_ 312 Bytes

    ciao Dirk

  • 2019?"♥":fOX=2TO81:pO54238+X,.:pO982+aB(26-INT(5/8*X))*40+X,160:nE:wA.,.


    • Dem Algorithmus liegt die Überlegung zugrunde, beide Diagonalen zusammen als nur eine zu plottende Funktion zu behandeln, die 80 Zeichen breit ist, 26 Zeichen hoch und einer Dreieckkurve entspricht, und zwar von 0/24 nach 39/0 aufsteigend und dann von 40/-1 nach 79/23 wieder absteigend, wobei das Wrapping der theoretischen 80-Zeichen-Zeile auf 40 Zeichen dafür sorgt, dass der absteigende Teil um 1 weiter unten (-1 bis 23 => 0 bis 24) und 40 weiter links (40 bis 79 => 0 bis 39) geplottet wird. Es wird dabei keine Speicherzelle außerhalb des Bildschirmspeichers überschrieben.


    Anders gesagt: Eine Gerade, deren oberer rechter Teil nach unten gespiegelt und nach links verschoben wird. Siehe Bild.


    FOR X=2 TO 81:POKE 982+ABS(26-INT(5/8*X))*40+X,160:NEXT


    • Die Rechen-Basis (982) ist etwas kleiner als der Ursprung (1024) gewählt und wird durch leicht erhöhte Koordinaten ausgeglichen.


    • Die Nulllinie ist unten. Das aktuelle Y (die Zeile) wird berechnet, indem X mit der Steigung 5/8 multipliziert wird, fängt also bei 1 an (2*5/8). Das wird von 26 Zeilen abgezogen (25 echte Bildschirmzeilen plus einer gedachten wegen der kleineren Basisadresse), dann mal Zeilenbreite 40 genommen und zur Basisadresse 982 addiert, sodass die erste Zeilenadresse-2 die unterste ist. Das X selbst kommt für den Plot natürlich noch dazu, fängt mit 2 also genau auf der Zeilenadresse an. Das INT() ist notwendig, weil wir für Y Vielfache von 40 brauchen und nichts dazwischen.


    • Wenn wir oben angekommen sind und das als Term errechnete Y >= 26 wird, wird das X >= 42, sodass dann das Wrapping greift (982+0*40+42=1024). Die ABS-Funktion entfernt das Vorzeichen der Zeilenberechnung und sorgt so dafür, dass die errechnete Zeile nicht Richtung Zeropage geht, sondern wieder größer wird. Bei X=81 und Y=|26-5/8*81|=24 ist Schluss: 982+24*40 ergibt Zeilenadresse-2 von Zeile 23. Plus die 81 aus X ergibt Spalte 39 in Zeile 24.


    • Die Rahmen- und Hintergrundfarbe wird auf schwarz gesetzt, indem ab der letzten Spiegelung der entsprechenden VIC-Adressen Nullen geschrieben werden. Die letzte Spiegelung wurde gewählt, damit keine wichtigen Steuerregister des VICs verändert werden. Es wird lediglich der SID gelöscht.


    WAIT.,. wartet, bis der Inhalt der Adresse 0 mit 0 AND-verknüpft ungleich 0 wird und damit für immer. Lässt sich mit Stop+Restore abbrechen. Die 2 Byte kürzere CPU-Jam-Alternative ist SYS7, ruft aber beim VICE-Emulator den Debugger auf.


    cross68.prg


    Die entsprechende PRINT-Variante mit Adresse 214 zur Zeilenansteuerung und PRINT SPC(x) für die Spaltenangabe benötigt 91 Bytes.



    Danke, logiker. War wieder interessant. Ich hätte von den Erkenntnissen vllt. was in meinem BOH (PUR80-10-Liner 2019) berücksichtigen können, hätte ich die da schon gehabt.

  • Nach dem Wettbewerb, ist vor dem Wettbewerb.

    Für die PRINT-only Variante würde ich mir folgende Regeln vorstellen:


    Selbs Ziel und selbe Regeln wie beim ursprünglichen Wettbewerb, zusätzlich aber:

    1. Kein PEEK/POKE (Außer 53280,53281 und 198)
    2. Kein SYS u.ä.
    3. Keine File-Manipulation
    4. Kein Selbstmodifizierender Code

    Man könnte fast sagen: reines (Dartmouth-)BASIC mit PETSCII-Steuercodes.

  • Danke atomcode für alles! Für das Mitmachen, den Code und die Erklärung dazu! Und nochmals Gratulation!

    Der Code ist echt interessant und meinem sehr ähnlich. Ich muss deinen Code allerdings noch verdauen, da ich sehe, dass du "ziemlich viel" herumPOKEst.


    Du POKEst auch Adressen an, die nicht verwendet werden, oder? Hast dir schon überlegt, was wäre, wenn du diese Adressen nicht anPOKEn würdest?


    Hier nun meine Variante:

    Code
    1. 0pO53280,0:pO53281,0:?"{clear}":fOi=-39.5to40:pO4^5+i+abs(int(5/8*i)*40),160:nE:wait1,0


    Sie ist ähnlich jener von atomcode, nur etwas länger. Aber sie sollte auch viel leichter verständlich sein.

    • Durch die ABS-Funktion erreicht, dass man die Zeilen immer positiv von 0 bis 24 durchläuft. i läuft ca. von -40 bis 40 wodurch die Spiegelung erreicht wird. Einmal wird sozusagen hinzugezählt (von links), einmal abgezogen (von rechts).
    • .5 wurde wegen dem Runden hinzugezählt, deshalb die komische Zahl "-39.5".
    • wait.,. kannte ich zu diesem Zeitpunkt noch nicht ;-)
    • 4^5 entspricht 1024
  • SYS7-Variante war 66Bytes. Minus Terminator-Nullen = 64Bytes (ja, welch schöne Zahl). Ohne Ladeadresse (wie CBM-Studio angibt) sind es 62 Bytes, bzw. mit WAIT wieder 64.


    Hab dein Programm eben ins C64-Studio kopiert, gespeichert und komme auf 76 Bytes. Du hattest 77, eins zu viel angegeben. :gruebel

    Mit POKE54280+I,0 (analog zu meiner Variante) wären es auch nur 69Bytes.

  • 64Bytes (ja, welch schöne Zahl)

    Ich dachte mal, dass man nicht nur 2 sondern sogar 3 Bytes entfernen kann. Aber dem ist nicht so. Gerade eben ausprobiert.

    Hab dein Programm eben ins C64-Studio kopiert, gespeichert und komme auf 76 Bytes. Du hattest 77, eins zu viel angegeben. :gruebel

    Ich hatte zum Schluss noch ein Byte rausgeholt. Allerdings auf eben relativ unschöne Art. Ich kann die 77er Version auch noch veröffentlichen.

    Mit POKE54280+I,0 (analog zu meiner Variante) wären es auch nur 69Bytes.

    Dann wären es nur noch 1 Byte Unterschied zu dir. Wo ich das wohl verloren hab? ;-)

  • Ich hab es mit print versucht und es ist immerhin ein Zweizeiler geworden mit 128 Byte.


    0 poke53281,.:poke53280,.:print"[clr,runter,blau,rev-an]";:poke242,.:a$(.)="[links] [links]":a$(1)="[links,links] [links,links]

    1 fori=.to24:printa$(noti+i/5and1)"[runter]";:next:print"[home]";:a$(.)=" ":a$(1)=" ":goto1


    Also bei a$(1) müssen jeweils 2 Leerzeichen stehen, da scheint eins vom Editor gelöscht zu werden.


    Schönen Gruß.

  • Werten wir das als Beitrag für die gewöhnliche Compo?

    Für die PRINT - only Compo müsste das POKE 242 weg.


    Bezüglich der Leerzeichen hilft vielleicht das Formatieren als Code.

  • Hier meine Ansätze, die Aufgabe zu lösen:


    Dies ist die 80 Byte Variante:

    Code
    1. 0 print"{clear}"
    2. 1 fori=0to41:poke53280+i,0:poke982+o+int(i*.625)*40+i*(1oro>0),160:next:o=43:goto1


    Und hier eine etwas längere Version (86 Bytes). Dafür wird der Aufbau komplett innerhalb der For/Next-Schleife erledigt, was erlaubt, dass alles in einer Zeile untergebracht werden könnte (vorausgesetzt, die Zeilenlänge ist durch die Spielregeln nicht auf PUR-80 beschränkt):

    Code
    1. 0 print"{clear}":fori=-40to39:poke53280+i/9,0:poke1024+-40*(i<0)+int(abs(i+.5)*.625)*40+i,160:next:wait198,1

    Auf den "Trick", die Rahmen- und Hintergrundfarbe 53280/81 innerhalb der Schleife zu setzen, bin ich auch gekommen. Das sind so die Momente, wo das Herz ein bisschen schneller schlägt, weil man dem Ziel plötzlich einen grossen Sprung näher kommt (wobei ich in der Endphase 1 Byte Reduktion als kleinen und >1 Byte als grossen Sprung betrachte) :D


    Das Rumtüfteln hat mir jedenfalls sehr viel Spass gemacht. Und ich habe auch wieder einiges dabei gelernt.

  • Nicht übel. Aber da kann ich, glaube ich, aus meinen Versuchen dann immerhin noch 2 Byte Reduktion beitragen, indem man auf das WAIT verzichtet und stattdessen den Prompt unsichtbar macht:


    Code
    1. 2019print"{clear}{down}{down}{black}":forX=2TO81:poke54238+X,.:poke982+abs(26-INT(5/8*X))*40+X,160:next
  • Erstmal vielen Dank an logiker für die Ausrichtung der Compo - und herzlichen Glückwunsch atomcode, dem verdienten Sieger!


    Hier nun mein Einzeiler (mit abgekürzten Basicbefehlen eingeben):


    1 ?"{clear}":fOx=.5to40:pO53280+x,0:a=4^5+int(x*5/8)*40:pOa+x,160:pOa+40-x,160:nE:wA1,0

    Hat mir viel Spaß gemacht!