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

last post from oobdoo at the

Heute so gecodet...

  • Hier gibt es übrigens einen Sudoku Löser in good ol' BASIC 2.0: https://csdb.dk/release/?id=184499&show=notes#notes

    Scheint aber nur eingeschränkt lösen zu können ...

    Der Solver-Code kommt für auch recht kurz vor ... (ohne ihn jetzt genauer angesehen zu haben).

  • Hier gibt es übrigens einen Sudoku Löser in good ol' BASIC 2.0: https://csdb.dk/release/?id=184499&show=notes#notes

    Scheint aber nur eingeschränkt lösen zu können ...

    Der Solver-Code kommt für auch recht kurz vor ...

    Der Name sagt ja quasi Easy Sudoku Solver ;)

    Aber der Code bietet einen ersten Ansatz für jemanden, der das auch am 64er umsetzen möchte.

  • Wenn man jedoch nur die erste Zeile ausfüllt, dann hat der Algo schon ganz schön daran zu knabbern.

    Wird die Lösungszeit schlechter wenn du nur die letzte Zeile ausfüllst?

    Das selbe Ergebnis.


    Es hängt wohl hauptsächlich ab von der Anzahl leerer Plätze.

    Und natürlich auch vom Zufall.

    Je nach Sudoku hat man mehr oder weniger viele Fehlversuche.

  • Wird die Lösungszeit schlechter wenn du nur die letzte Zeile ausfüllst?

    Ich würde schon sagen, dass es deutlich länger ist, solange die Bestimmtheit genau nur eine Lösung erlaubt. Wenn es mehrere Möglichkeiten gibt, dann wird - so vermute ich - irgendeine Lösung relativ leicht gefunden. Man denke nur an den Extremfall, rechts oben setze ich die Ziffer 1 (nur ein Feld belegt). Dann ergibt das erste regelkonforme Auffüllen aller anderen Feldern zwangsläufig eine Lösung auf den 1. Versuch, oder? Natürlich ist das dann "schnell" (sogar noch schneller, als sonst).

  • Nicht heute, sondern bereits gestern:

    Ich habe auf Github ein wenig im GUI64-Code von WebFritzi herumgestöbert und einige kleinere alternative Code-Snippets per PN mit ihm besprochen.

    War ein sehr nettes und interessantes Gespräch. :)


    Außerdem habe ich am Space Invaders Disassembly weitergemacht.

    Berichte mal davon.

    Der Code ist – für ein 4KB Spiel – ziemlich chaotisch.

    Viele Atari 2600 Disassemblies, die ich so gesehen habe, sind – vom Code-Flow her – wesentlich strukturierter und fangen in der Regel bei $f000 (seltener $1000) mit dem bekannten Schema SEI CLD ... an — hier liegt der Init-Kram bei $fe98. Gut, der ROM-Start steht ja am Ende in den Vektoren ab $fffa, kann man also relativ schnell finden, aber im restlichen Code wird wie wild im ROM herumgesprungen – das könnte glatt als abschreckender Kopierschutz durchgehen. :S


    Einige weitere Stellen (halbwegs) logisch durch Leerzeilen getrennt und kommentiert. Labels wurden noch nicht umbenannt – es gibt kein Suchen/Ersetzen in der App und händisch ist das zu doof jede Instanz des Labelnamens zu suchen.

    Später könnte man noch den Code mit der NTSC Version abgleichen und das Disassembly so erweitern, dass man beide Versionen damit assemblieren kann.

  • Eben über eine tolle Stelle im Disassembly gestolpert:

    Code
    1. LDA $DC
    2. AND #$04
    3. LSR A
    4. LSR A
    5. LSR A
    6. LDA #$01

    Ich vermute mal mangels STA, das ist einfach nur zum Cycles verbrennen.

    Da gibt es noch so ein paar Stellen, die ich als potenzielle "Kann man ggfs. wegoptimieren"-Kandidaten markiert habe: darunter auch diverse NOPs. Das wäre durchaus auch für ROM-Hacks interessant, wenn man da noch mehr freie Bytes herauskitzeln könnte. Aktuell habe ich nur 2 Bytes bei $fff8 als Unused/Free markiert.

    Leider habe ich momentan keinen Zugriff auf den Debugger in Stella. Das ließe sich sonst alles deutlich leichter überprüfen.

  • Eben über eine tolle Stelle im Disassembly gestolpert:

    Code
    1. LDA $DC
    2. AND #$04
    3. LSR A
    4. LSR A
    5. LSR A
    6. LDA #$01

    Ich vermute mal mangels STA,

    "mangels STA" verstehe ich nicht.

    Die Zeilen 1-5 verbrauchen 11 cycles, wobei absolut egal ist, was in $DC drin steht, in Zeile 5 ist Akku ja 0 - nur um dann ein LDA #$01 zu machen... Wäre zum reinen cycle-waste von 11 Taktzyklen nicht folgendes einfacher (lesbar):

    Code
    1. BIT $EA
    2. NOP
    3. NOP
    4. NOP
    5. NOP
    6. LDA #$01

    Oder ist LDA $DC beim Atari nen magisches register? Edith sagt (laut Atariage.org) dass die zeropage Adressen $DA-$DF wohl floating point extra register sind. Aber da $DC nur geladen und nicht befummelt wird, ist es egal, wird ja nix mit gemacht.

    Code
    1. FP extra register (?)
  • Das schiebt doch Bit 2 ins Carry, oder? Das AND ist dabei aber natürlich eigentlich überflüssig. Aber vielleicht passiert mit dem Carry nachher noch etwas?

  • Das schiebt doch Bit 2 ins Carry, oder? Das AND ist dabei aber natürlich eigentlich überflüssig. Aber vielleicht passiert mit dem Carry nachher noch etwas?

    :honk:

    Vergesst meinen Schwachsinn von heute Morgen. Mein Hirn war anscheinend noch im Halbschlaf. Das war der Meinung LDA beeinflusst Carry :anonym


    Nochmal genauer hingeschaut: der Code macht doch Sinn. Kurz nach den LDA #$01 kommt ein BCC um ein ASL A zu überspringen.

  • Das schiebt doch Bit 2 ins Carry, oder? Das AND ist dabei aber natürlich eigentlich überflüssig. Aber vielleicht passiert mit dem Carry nachher noch etwas?

    :honk:

    Vergesst meinen Schwachsinn von heute Morgen. Mein Hirn war anscheinend noch im Halbschlaf. Das war der Meinung LDA beeinflusst Carry :anonym


    Nochmal genauer hingeschaut: der Code macht doch Sinn. Kurz nach den LDA #$01 kommt ein BCC um ein ASL A zu überspringen.

    Aber dann braucht es das "AND #$04" nicht. Die LSR erledigen ja den Job mit dem Carry setzen

  • Beschwerden bitte an Richard Maurer – ist schließlich sein Code. :D

  • Inspiriert durch eine Aufgabe, die der Sohn eines Freundes in der Schule zu lösen hatte: SUDOKU Löser

    Hatte ich irgendwann mal Weihnachten auch gemacht, weil meine Frau zu lange für ein Sudoku gebraucht hatte. Das Programm war schneller geschrieben, als sie es lösen konnte.


    Lösung mittels rekursivem Backtracking.


    Mein Sudoku kann allerdings das Spielfeld nicht eingeben, es muss in das Programm einkompiliert werden.


    Erstellt mit VisualC++ 6. Nicht auf hübsch getrimmt, aber authentisch.

  • Hab dank Mike's Vorlage Minipaint Support für den 8x16-Char-Modus in C64-Studio eingebaut. Von reinem Charset-Editor zum Charscreen zum Grafik-Editor mit Export-nach-Charset-Möglichkeit.

    Die meiste Zeit hat mich gekostet, hinter den RAM-Aufbau für den verwendeten 160x192-Modus zu kommen. Charset- und Screen-RAM werden überlappend konfiguriert, und man hat dann Zeichen 16 bis 255 zur Verfügung.

    Eine in einen Zeichensatz konvertierte Grafik sieht dann so aus:



  • Nicht wirklich gecodet, sondern nur Formeln in Excel geschrieben. Ich wollte wissen wie es grafisch aussieht, wenn man Bits eine Richtung gibt, also 1 nach oben und 0 nach unten.

    Sowas kann man bestimmt mit vorgefertigen Diagrammen in Excel darstellen. Ich wollte aber was eigenes.



    Mit Zufallswerten gefüttert und dem Finger auf F9 kann man schön die Entwicklung sehen. Die blauen Linien errechnen sich über die Position des letzten Bits ganz rechts.

  • Ich habe heute noch etwas am MicroKey2 rumprogrammiert und mich dabei wieder mal geärgert, daß Variablen im Segger-Debugger Ozone fast die ganze Zeit als 0 angezeigt werden und nur manchmal kurz ihren tatsächlichen Wert zeigen. Ist mir schon früher aufgefallen, was ich habe das bisher auf Bugs in Ozone oder äußere Umstände geschoben. Im MicroKey2 war es jetzt so schlimm, daß ich eigentlich gar keine Variablen mehr zur Laufzeit beobachten konnte. Also habe ich Ursachenforschung betrieben. Das Update von Ozone und der Segger J-Link-Software hat leider ebenso wenig geholfen wie der Austausch des USB-Kabels. Dann habe ich bei der Recherche im Internet einen Hinweis darauf gefunden, daß das Auslesen von Adressen per Debug-Schnittstelle bei Arm-Cores im Sleep-Mode zum fehlerhaften Lesen von 0 führen kann.

    Tatsächlich benutze ich in meiner Hauptschleife normalerweise solch ein Konstrukt, damit der Prozessor schläft, bis ein Interrupt einschlägt und mache alle relevanten Sachen in (timerbasierten) Interrupts :

    Code
    1. while(1) {
    2. /* Sleep until next IRQ happens */
    3. __WFI();
    4. }

    "__WFI" ist eine Intrinsic-Funktion/Anweisung, um den Controller bis zum nächsten Interrupt in den Sleep-Mode versetzen.

    Weil der einzige Interrupt ein 1ms-Interrupt ist, in dem ich im Idle-Zustand nur schaue, ob Restore gedrückt wurde, verbringt der Mikrocontroller in er Tat 99.9% der Zeit im Sleep-Mode.

    Also habe ich das jetzt mal so abgeändert, daß man das WFI fürs Debuggen ausknipsen kann:

    Code
    1. while(1) {
    2. #if DEBUG_NO_WFI==0
    3. /* Sleep until next IRQ happens */
    4. __WFI();
    5. #endif
    6. }

    Und siehe da: wenn ich den Schalter auf 1 setze, kann ich wieder alle Variablen zur Laufzeit auslesen, ohne daß sie dauernd auf 0 wechseln...

  • Vorgestern, eine kleine C2N-Lib für die Arduino IDE mit dem Raspberry Pi Pico W nach ausgiebigen Recherchen. Endlich sauberes Timing bei gesperrtem IRQ und Auswerten der Hardware-Timer.



    0x02 , da war allerdings der Marker noch nicht passend drin.



    Eine statische Header und PRG aus dem Pico im Pet 2001N mit Basic 4 geladen. Jetzt muss das noch mit meinem Wifi-Adapter zusammengeführt werden.