Posts by berni

    Ist echt schwer, zu der Zeit als Holländer einen Fuß auf die Erde zu bekommen. Habe erstmal 2 Städte erobert und höllandisch gemacht, kann aber nirgends zum Gouverneur, um befördert zu werden. Vielleicht hilft mir König Willem-Alexander da weiter? :whistling:

    Oh je. Jetzt hab' ich ein schlechtes Gewissen, weil ich das ja im Wesentlichen vorgeschlagen habe (und zudem läuft es bei mir ziemlich gut). Mich reizt das vor allem, weil fast alles spanisch ist und zudem noch nicht mal irgendwer im Krieg ist. Das macht es schwieriger. Ich hatte gedacht, dass ihr das auch spannend findet, aber da hab' ich mich wohl getäuscht... Sorry. :huh:


    Im folgenden Spoiler habe ich ein paar Ideen aufgeschrieben, wie man bei diesem Setting aus dem Quark kommt:

    Ich hatte jetzt grad Lust, mal eine Runde zu spielen. Hab' die Parameter, die ich oben genannt habe, genutzt, also 1600, Dutch Trader, Swashbuckler, Skill at Gunnery. Der Anfang lief total beschissen. Am Ende konnte ich aber dann doch noch ein bissl was rausholen - 8 pirat points immerhin:



    Jetzt bin ich gespannt, ob das jemand mit diesen Vorgaben übertrifft. :)


    Und wenn Bodhi1969 gerne andere Parameter haben möchte, dann mache ich da gerne auch mit. Muss nur schauen, wie ich die Zeit finde... (jetzt hatte ich nämlich grad Zeit).

    Ich fände so eine Challenge auch sehr interessant, allerdings würde es mich deutlich mehr reizen, wenn ein festes Setting vorgegeben ist, also beispielsweise: 1600, Dutch Trader, Swashbuckler, Skill at Gunnery. Damit hätten alle die gleichen Startbedingungen und die Herausforderung ist etwas höher...

    Wenn ich mir meine Sammlung an d64-Files so anschaue und dann schaue was ich davon wirklich spiele, muss ich feststellen das es eben genau die Spiele meiner Kindheit sind. Mit anderen Titeln werde ich auch nicht richtig warm...

    Das geht mir auch oft so. Gerade hier in dem Thread werden ja einige Titel immer wieder genannt, die ich früher nicht kannte. Ich hab' einige davon ausprobiert, aber bei vielen komme ich nicht richtig rein (Defender of the Crown zum Beispiel). Ich frage mich, was damals anders war? Waren wir probierfreudiger oder hatten wir einfach eine viel kleinere Auswahl? Oder mehr Zeit? Oder ist unser Gehirn jetzt schon so eingerostet, dass wir nicht mehr in der Lage sind, uns an neue Spiele anzupassen?


    Allerdings gibt es auch Ausnahmen: Irgendwer hatte hier im Thread "Heart of Africa" mit "Pirates!" in einem Satz erwähnt. Da für mich "Pirates!" eines der besten Spiele war, habe ich mir vor ein paar Wochen "Heart of Africa" runtergeladen und mal durchgespielt. Bis auf ein Detail, das ich zuerst nicht verstanden hatte, hat es mir auf Anhieb super gefallen, und ich bin mir sicher, dass ich es nochmal spielen werde, zumal ich ja noch gar nicht ganz Africa durchsucht habe. :) (Und Gold Quest IV spiele ich auch immer wieder gerne.)

    Wenn ich <sta putchar+2> aufrufe wie kann dies mit Labels funktionieren oder ist putchar kein Label sondern eine Variable, das würde mir einleuchten, aber für mich ist das nur ein Label.

    Vielleicht ist auch da das Verständnisproblem zu suchen: Labels sind sowas ähnliches wie Variablen, aber wohl eher Konstanten (wenn sie einmal festgelegt sind, kann man sie nicht mehr verändern). Sie markieren eine Position in einem Programm. Mit diesen Positionen kann man rechnen: putchar+2 ist dann die Position, die sich um zwei Byte hinter der Position von putchar befindet.

    Ich versuche mich auch nochmal. Anders, als Detlev, bin ich ja großer Fan von selbstmodifizierendem Code. :D


    Im Speicher des Computers werden diese Assemblerbefehle (wie alles andere auch) als eine Folge von Bytes gespeichert. In diesem Fall sieht das so aus (wenn der Code bei $C050 beginnt):

    Code
    1. ... 8D 5D C0 20 99 C0 8D 5C C0 A9 A0 8D 00 04 ...

    Das entspricht

    Code
    1. ...
    2. $C050 8D 5D C0 STA $C05D
    3. $C053 20 99 C0 JSR $C099
    4. $C056 8D 5C C0 STA $C05C
    5. $C059 A9 A0 LDA #$A0
    6. $C05B 8D 00 04 STA $0400
    7. ...

    Der Wert von "putChar" entspricht in diesem Fall $C05B. "putChar+2" ist dann $C05D. Das ist die Speicherzelle, in der die 04 gespeichert ist. (Und "putChar+1" ist dann $C05C, die Speicherstelle in der 00 gespeichert ist.)


    Nehmen wir mal an, am Anfang der Sequenz habe der Akku den Wert 06 und nach dem JSR-Befehl den Wert FF, dann sorgen die beiden ersten STAs dafür, dass der Code nach dem zweiten STA so aussieht:

    Code
    1. ...
    2. $C050 8D 5D C0 STA $C05D
    3. $C053 20 99 C0 JSR $C099
    4. $C056 8D 5C C0 STA $C05C
    5. $C059 A9 A0 LDA #$A0
    6. $C05B 8D FF 06 STA $06FF
    7. ...

    Der letzte STA-Befehl wurde also durch die ersten beiden STA-Befehle verändert und der Code speichert jetzt das Zeichen #$A0 an die Stelle $06FF statt an $0400.

    Ein wesentlicher Grund, warum ich mir Denise bislang noch nie angeschaut habe ist vermutlich, dass es keine Wiki-Seite dazu gibt. Ich wüsste jetzt auf Anhieb noch nicht einmal, wo ich mir den runterladen könnte...

    Für Verbesserungen bin ich immer zu haben. Ich lerne mich gerade wieder ein und hab mit Erschrecken festgestellt, wie viel ich vergessen habe. Die erste Version war noch deutlich länger und umständlicher 😀 Alles, was den Code schlanker und schöner macht, ist herzlich willkommen.

    Für Beschleunigungen gibt es ja grundsätzlich zwei ganz unterschiedliche Arten: Das eine sind algorithmische Beschleunigungen und das andere Detail-Gefrickel. Wenn wir erst mal bei dem Rahmen bleiben: Die Lösung von ChatGPT ist deswegen so schlecht, weil die Anzahl der Operationen dort ungefähr Breite x Höhe beträgt, während sie bei den anderen Lösungen ungefähr 2 x (Breite + Höhe) ist. Bei Breite=40 und Höhe=25 wären das 1000 Operationen vs. 150 Operationen. Das Gefrickel ist dann, ob ich POKE oder PRINT verwende und ob ich mit Variablen arbeite und in welcher Reihenfolge ich die definiere, und so Zeugs.


    Die algorithmischen Optimierungen sind in der Regel immer wichtig, während das Gefrickel allenfalls beim heißesten Code (also dem, der am häufigsten benutzt wird) sinnvoll sein kann (oder wenn man halt Spaß dran hat, so wie hier im Thread).


    Eine algorithmische Optimierung ist mir in den Zeilen 280-410 aufgefallen: Die Felder, in denen sich Squirmy befindet, speicherst du in den Variablen A1, A2, ... , B8. Dadurch musst du bei jedem Schritt alle 17 Variablen kopieren. Mit einem sogenannten Ring-Puffer geht das schneller, aber dafür musst du auf ein Array umsteigen. Also beispielsweise mit DIMA(16) und A(0), A(1), ..., A(16). Zudem brauchst du eine weitere Variable, die auf den Kopf zeigt, im folgenden Bild als Pfeil dargestellt:



    Damit brauchst du, statt der beiden Zeilen 320 und 330 nur noch den Kopf anpassen und den Zeiger eins weitersetzen. (Bei den POKEs in 390 machst du das ja im Grunde genommen schon so.)


    Weiß nicht, ob das so jetzt verständlich war...



    Eine andere Optimierung, mehr vom Gefrickel-Typ, wäre es, wenn du die Zeilen 340 bis 360 zusammenfassen würdest. Das ginge, wenn Wurm, Rand und Gift die Zeichen 0, 1 und 2 wären. Dann kannst du mit IF PEEK(A1)<3 GOTO570 alle drei auf einmal erschlagen.

    Als kleines Dankeschön für die coolen Ideen zur Rahmengestaltung mal vorab die Beta, sprich den aktuellen Stand meines Basic Spiels. Wenn man den Verlauf des Threads so beobachtet, ist der Rahmen mit Sicherheit nicht mein kleinstes Optimierungsproblem... Sprich, da werd ich noch mal ordentlich Zeit ins Lernen investieren :D .

    Magst du Rückmeldungen zum Code haben? Da die Joystick-Abfrage bei mir etwas ruckelig ist, hatte ich mal geschaut, wie du das machst und ich denke, in der Schleife ab Zeile 280 gäbe es noch Verbesserungspotential. :)

    Sicher bekannt: man kann ja den "Letzte Ecke Poke" bei Bedarf mit LEFT INS im PRINT unterbringen (Zeile 11).
    Schneller als POKE? :)

    Jetzt wo du es sagst: Als Kind kannte ich das mal, aber ich hatte es wieder vergessen. Und ja, es ist deutlich schneller: Jetzt sind wir bei 1108 Rasterzeilen (oder 575 Rahmen in der der Zeit, die ChatGPT dafür braucht).

    Und es geht noch schneller (1361 Rasterzeilen, das ist weniger als eine Zehntelsekunde)...



    PS: Im Prinzip braucht man das letzte "HOME" nicht, wenn das Programm danach weitergeht. Wenn man das weglässt, sind es nochmal 9 Rasterzeilen weniger, also 1352...

    Ich dachte oben in [WebFritzi3] übrigens noch, dass die Reihenfolge eine Rolle spielt.

    Du meinst die Reihenfolge, in der die Zeichen auf den Bildschirm kommen, oder? Ja, das hatte ich vermutet. Eine andere Reihenfolge spielt bei der Geschwindigkeit übrigens eine wichtige Rolle, nämlich in welcher Reihenfolge die Variablen definiert werden. Die, die häufiger benutzt werden, müssen zuerst definiert werden, damit es schneller wird. (Deswegen bei mir B$ vor A$.)

    Die schnellste Version hat berni (s.o.) geliefert.

    Für das Spiel würde ich vermutlich deine Webfritzi3-Version wählen. Einfach von der Ästhetik her gibt das viel mehr her. Speed ist halt nicht alles! ^^


    Übrigens, mir ist noch eine deutlich schnellere Variante eingefallen. Eigentlich total naheliegend. Hier in zwei Versionen:



    Die obere Version dauert 1905 Rasterzeilen, die untere sogar nur 1877 Rasterzeilen. Allerdings kann man die untere nicht mehr mit dem BASIC-Editor eintippen, sondern muss sie von einem Programm generieren lassen.

    Wenn ich dein Tool verwende gibt es ja drei Einstellmöglichkeiten. 1 und 3 glaube ich geben eine Uhrzeit aus und Version 2 Raster und Position?

    Ne, es gibt nur zwei Varianten. SYS49152,1 verwendet die Echtzeituhr, SYS49152,2 zählt Rasterzeilen (Und nur für die 1-Minuten-Challenge im anderen Thread gibt sie, wenn man in der richtigen Rasterzeile endet noch weitere Hinweise, um das Ergebnis taktgenau zu bekommen. Hier kann man das nicht nutzen.)

    Wie berechne ich daraus die Rasterzeilen? Das habe ich irgendwie auch schon nicht im Originalthread verstanden...


    EDIT:

    Für ein 10 forx=1to1000:next spuckt mir ein sys49152,2 ein 50/22 aus. Wie viele Rasterzeilen sind das?

    OK. Am Beispiel kann man das vermutlich am Besten erklären: Die erste Zahl gibt die Anzahl der kompletten Bildschirmdurchläufe an. Das sind jeweils 312 Rasterzeilen. (Eigentlich ein klein wenig weniger, da die IRQ-Routine, die die Rasterzeilen zählt auch etwas Zeit benötigt; das hab' ich gestern beim Messen aber nicht berücksichtigt; korrekter wäre es demnach vermutlich, wenn man mit 311 multipliziert.)


    Die zweite Zahl gibt dann noch an, in welcher Rasterzeile das Programm endete. Da es in Rasterzeile 253 beginnt, muss man entweder 253 von der Zahl abziehen oder 59 dazuzählen, je nachdem ob die Zahl >=253 ist oder <253.


    In deinem Fall lautet das Ergebnis also 50*312+22+59=15681 Rasterzeilen.