Hello, Guest the thread was viewed415k times and contains 2252 replies

last post from oobdoo at the

Heute so gecodet...

  • Heute nochmal an zwei verschiedenen Fronten aktiv gewesen:


    SQL

    Jemanden, der damit nun beruflich zu tun hat, einen Crash-Kurs gegeben. Zumindest beschränkt auf SELECT Abfragen, mehr wird eigentlich nicht benötigt. Also nix großartig mit wie normalisiert man Datenbanken, bisschen ja, aber nicht auf Developer-Niveau.

    Als Hausaufgaben paar Queries bearbeiten, erweitern gegeben. Ruhig auch mit WHERE + Zweittabelle versuchen. JOIN kommt danach dran.


    Space Invaders (2600 Disassembly)

    Ein paar weitere RAM-Stellen identifiziert, und Labels entsprechend notiert. Außerdem sind noch neuere Kommentare hinzugekommen.

    Nimmt langsam Form an :)

  • Also nix großartig mit wie normalisiert man Datenbanken

    Also ich mache beruflich auch viel mit Datenbanken. Das Thema Normalisierung muss man ab einer gewissen Größe einfach klein schreiben, sonst braucht der Optimizer mehr Zeit als die Abfrage selber ;-)


    Warum hat man früher denn überhaupt normalisiert? Ganz einfach, weil der Speicherplatz knapp war. Die Zeiten sind vorbei und ich habe durchwegs gute Erfahrungen mit "so-gut-wie-keine-Normalisierung" gemacht.

  • Nachdem ich nun noch "etwas" an meinem ByteCode-Interpreter gearbeitet habe, möchte ich dazu ein paar Details erzählen.


    Vorab: Ich bin kein guter Coder, aber dass ich sowas überhaupt hinbekommen habe, ist schon ein echter Erfolg für mich. Die Möglichkeiten sind inzwischen so umfangreich, dass meine Dokumentation dafür derzeit 12 A4 Seiten in Anspruch nimmt. Ohne diese Dokumentation steige ich schon selbst nicht mehr durch :D

    Abgesehen davon würde ich ihn mit dem dadurch erworbenen Wissen nun ganz anders Programmieren. So wie er derzeit ist, ist er in bester Spaghetti-Code Struktur erstellt und leider nicht auf Speicherplatzverbrauch (was den eigentlichen ByteCode angeht) optimiert. Das lässt sich nun im Nachgang (für das bestehende Projekt) nicht mehr so ohne weiteres ändern, da der ByteCode selbst inzwischen so umfangreich ist (bestimmt insgesamt so 5-10kb händisch erstellt), dass wohl etliche Stunden draufgehen würden, den wieder anzupassen. Aber vielleicht dann für das nächste Projekt...


    Aber zurück zum ByteCode:

    Wofür ist der ByteCode Interpreter:

    Damit werden Eingaben, die ein Spieler in einem Spiel getätigt hat ausgewertet und entsprechende Aktionen eingeleitet.

    Vorher wurden die Eingaben aber bereits in Token umgewandelt.

    Die Aktionen können entweder bestimmte Textausgaben sein oder es werden Trigger gesetzt, die irgendwelche Veränderungen im Spielablauf bewirken.


    Es gibt "normalen" ByteCode, BlockByteCode, MultiByteCode und KontextByteCode. Wobei die verschiedenen ByteCodearten beliebig miteinander kombiniert werden können. Die Begrifflichkeiten habe ich so für mich gewählt, ob die so allgemeingültig wären, weiss ich nicht, aber ist vom Grundsatz auch egal.


    1. Normaler ByteCode:


    !byte 10,$02,$00,$73,$00,$F0,42,1,$F0,%00000000


    Erläuterung:

    10 Länge des ByteCodes

    $02-$F0 Eingaben des Spielers in Token sowie Endkennung.

    42,1,$F0 Textausgaben (Text 42 aus aktuellem Raum) und Endkennung.

    %00000000 BinärFlag, damit werden weitere Aktionen gesteuert, z.B. ob Voraussetzungen oder Inventargegenstände notwendig sind, ob man in der Nähe von etwas sein muss, ob Textausgaben unterdrückt werden sollen und Trigger gesetzt werden sollen.
    Wenn das entsprechende Bit gesetzt ist, werden weitere Bytes angehängt und ausgewertet.



    2. BlockByteCode:


    !byte $BC
    !byte 9,$02,$00,$A7,$00,$99,$99,$F0
    !byte 8,$02,$00,$00,$00,$A7,$00,$F0

    !byte 10,$02,$00,$00,$00,$A7,$00,$99,$99,$F0

    !byte $BC
    !byte 10
    !byte 62,1,$F0,%00001000,$FF,$FF,<Nähe_zu_irgendwas,>Nähe_zu_irgendwas


    $BC Kennzeichnet den Beginn und das Ende eines Blocks und enthält die verschiedenen Eingaben des Spielers.

    Dann kommt eine neue Längenkennung und der Rest ist wie bei normalem ByteCode.


    3. MultiByteCode


    !byte 27,$90,$00,$A7,$00,$99,$99,$F0,$E9,%01100111,7,129,0,176,0,$F0,%00000000
    !byte $E9,%01010101,14,0,129,0,130,0,$F0,%00000000


    Der Anfang ist wie normaler ByteCode, dann kommt ein Steuerzeichen ($E9) mit dem noch Bedingungen abgefragt werden können. Das darauf folgende BinärFlag gibt diese Bedingungen vor (hier: keine Negierung, Inventar, Flag für Sprung bei Nichterfüllung, 5 Bits für Nummer des Gegenstandes (hier Gegenstand 7)). Das nächste Byte gibt vor, um wieviel Bytes weiter gesprungen werden soll bei Nichterfüllung. Bei Erfüllung werden 2 Texte (hier Texte 129 und 176 aus den globalen Texten) ausgegeben und der Code bis zum BinärFlag ausgeführt. Ansonsten gehts beim nächsten $E9 weiter.


    4. KontextByteCode


    !byte %10000000+15,%01000000,$FF,$FF,<Nähe_zu_irgendwas,>Nähe_zu_irgendwas
    !byte $02,$00,$09,$00,$F0,4,1,$F0,%00000000


    Wenn im ersten Byte des ByteCodes Bit 7 gesetzt ist, dann wird der ByteCode nur ausgeführt, wenn ein bestimmter Kontext gesetzt ist.
    Der Kontext ist hier %01000000:

    01 für Spieler muss in der Nähe zu etwas bestimmten sein.

    Die weiteren Bits würden ausgewertet, wenn entweder ein Gegenstand oder eine andere Voraussetzung vorliegen müssen.


    5. ByteCodearten Kombiniert


    !byte $BC
    !byte %10000000+8,%00000000,$11,$00,$9E,$00,$F0
    !byte 6,$11,$00,$6D,$00,$F0
    !byte 8,$11,$00,$6D,$00,$9E,$00,$F0
    !byte 8,$93,$00,$30,$00,$22,$00,$F0
    !byte 12,$93,$00,$30,$00,$09,$00,$11,$00,$9E,$00,$F0
    !byte 6,$93,$00,$9E,$00,$F0
    !byte 10,$93,$00,$30,$00,$09,$00,$9E,$00,$F0
    !byte $BC
    !byte 63

    !byte $E9,%11010010,52,0

    !byte $E9,%10001010,23,1, $EA,$FF,$FF,<Nähe_zu_irgendwas,>Nähe_zu_irgendwas,0,1

    !byte $E9,%10100100,6,15,1,$F0,%10000000,12
    !byte $E9,%10100101,6,15,1,$F0,%10000000,12

    !byte $E9,%10100110,6,16,1,$F0,%10000000,9

    !byte $E9,%10001010,23,1

    !byte $E9,%10100111,7,20,1,8,1,$F0,%00000000

    !byte $E9,%00000111,18,1,18,1,$F0,%10000000,5


    Hier werden ByteCode, BlockByteCode, MultiByteCode und KontextByteCode kombiniert verwendet.

    Das ist schon ein ByteCode mit umfangreichen Abfragen und Verzweigungen.


    Wofür sind die ByteCodeArten:


    1. normaler ByteCode ist dafür, wenn aus einer bestimmten Eingabe nur eine bestimmte Ausgabe resultiert.


    2. BlockByteCode ist dafür, dass mehrere Eingaben des Spielers eine bestimmte Ausgabe/Aktion erzeugen. Das spart Speicher, da nicht für jede einzelne Eingabe eine eigene ByteCodeZeile mit den zugehörigen Ausgaben erzeugt werden muss.


    3. MultiByteCode heißt, dass "wenn-dann-sonst" Szenarien abgebildet werden können.


    4. KontextByteCode bedeutet, dass zuerst auf einen Kontext geprüft wird, bevor Auswertung von Eingaben und die daraus resultierenden Ausgaben bearbeitet werden. Z.B. Spieler steht auf einer Leiter, oder hat einen bestimmten Gegenstand oder eine andere Voraussetzung liegt vor.


    Weiteres dazu beim nächsten Mal ;)

  • Ich habe schon viel mit Excel und VB.net gemacht, d.h. was ich in Excel berechnet bekomme kann ich dann auch einfach in VB wiederholen.

    Diesmal haben mich aber Rundungsprobleme viel Zeit gekostet. :gahh:


    Zwischendurch ne KI gefragt. Anwort "Standardverhalten: Excel rundet standardmäßig kaufmännisch, während VB.NET standardmäßig die Bankiers-Rundung verwendet"

    Bankiers-Rundung war für mich was neues. :gruebel


    :puhh:

  • Spaß halber würde ich hier mal ein Programmcode als Bits durchlaufen lassen.

    Nennt sich dann z.b. C64 Code grafisch dargestellt! :thumbsup:


    Vielleicht kommen ja satanische Botschaften in Form von schlimmen Bildern zu tage.

  • Spaß halber würde ich hier mal ein Programmcode als Bits durchlaufen lassen.

    Nennt sich dann z.b. C64 Code grafisch dargestellt! :thumbsup:


    Vielleicht kommen ja satanische Botschaften in Form von schlimmen Bildern zu tage.

    Das geht aber nur bis Programme mit max. 2048 Byte. Das sind dann 16384 horizontale Zellen die Excel maximal schafft. :D

  • >28000 Zeilen hatten

    Das sind dann 16384 horizontale Zellen

    Zeilen != horizontale Zellen ;)


    Ok, schlecht von mir vorher ausgedrückt. :D


    Gesamtzahl der Zeilen und Spalten in einem Arbeitsblatt 1.048.576 Zeilen und 16.384 Spalten.

  • Streng genommen habe ich noch nicht wirklich was programmiert, aber die letzten Tage habe ich rumgebastelt, um auf dem Raspberry Pi Zero 2 W von meinem PC aus zu entwickeln.

    Dank der Extension "Remote SSH" von Visual Studio Code kann man tatsächlich am PC entwickeln, kompilieren und debuggen, obwohl alles auf dem RaspPi läuft.
    Sprich: der Quelltext liegt nur auf dem RasPi, der Compiler und der Debugger laufen auf dem RasPi. Trotzdem sieht es (fast) so aus, als wäre das ein lokales Projekt auf dem PC mit lokalen Tools:



    Leider ist Visual Studio Code halt speziell beim Einrichten eines Projekts etwas "sperrig" und das ganze ist leider eine ziemliche Übung in Geduld.

    Geschätzt braucht es eine Minute, bis man nach dem Start von Visual Studio Code so richtig loslegen kann. Und wenn man eine Debug-Session startet, dauert es 15-30s bis man auf dem ersten Breakpoint steht.

    Bin mir nicht sicher, ob das am langsamen WLAN liegt oder am Zero 2, aber es ist trotzdem toll, daß so etwas überhaupt funktioniert...

  • Ich habe meinen Azubis gerade erklärt, dass ich gestern Abend aus Versehen eine kleine Anwendung entwickelt habe...

    ... da fragen die mich doch tatsächlich, wie so etwas "aus Versehen" passieren kann. Pfff...





    Jetzt muss ich den C64 nicht immer permanent nebenbei laufen lassen, wenn ich am PC sitze, sondern kann fix reinkommen in den Chat, sobald sich jemand anmeldet. ;-)

    Oder ich kann einfach das SID Radio laufen lassen und rüber wechseln in den Chat, sobald sich da wer anmeldet... dieser Use Case wird sich allerdings überholen, sobald Chat und Radio integriert werden...

  • Heute habe ich das Start-Script von RetroPie bearbeitet.

    Da ich neben der Emulationstation noch Vice und Amiberry drauf habe, fand ich es immer unschön das Enulationstation startet und ich es dann beende um an der Kommandozeile Vice oder Amiberry zu starten.

    Ich habe jetzt im Startscript ein paar Abfragen von USB-Geräten eingebaut.


    Wenn beim Start eine Maus und eine Tastatur angesteckt sind, startet Amiberry mit dem A500.

    Ist keine Maus dran, aber eine Tastatur, dann startet Vice.

    Ist nichts angesteckt, dann startet Emulationstation und wartet auf einen Bluetooth-Controller.


    :thumbsup: