1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Mars

Beiträge von Mars

  • Bug oder nicht Bug oder wenigstens ungereimt?

    • Mars
    • 16. Januar 2023 um 16:12

    Ohne einen konkreten Grund (warum muss ich das unbedingt haben & warum ist ein Workaround zu aufwändig) wirst du bei den devs gegen eine Wand laufen. Ich weiß nicht wie viele Leute gerade am Code arbeiten, aber ich vermute es sind in etwa null Personen. Vor einem halben Jahr hatte der Chef wohl einen Motivationsschub und hat einiges gemacht, inzwischen ist der aber abgeklungen, und die Änderungen die die Co-Devs machen werden erstmal vom Chef gesammelt/verwaltet/angenommen/abgelehnt und landen dann alle Schaltjahr in einer Beta.

    Ich würde mir da keine Hoffnungen machen, egal wie gut der Request formuliert ist. Dafür ist die Sache nicht dringend genug dass dafür jemand aufsteht (die letzten 2 Sachen die für ein "Erwachen der devs" gesorgt haben waren "AutoIt wird 10x langsamer wenn man ein Fenster geöffnet hatte/hat", und "AutoIt rechnet falsch da im Parser für mathematische Ausdrücke ein Bug ist").

    M

  • ChatGPT für AutoIt - Talk, Ideen, Kuriositäten

    • Mars
    • 24. Dezember 2022 um 22:48
    Zitat von Mars

    Was würdest du antworten, wenn dir ein Besserwisser folgendes sagt: "Das Schnitzel muss im Fett der Pfanne schwimmen, damit die Panade sich voll ausbilden kann." ?

    Zitat von KI

    Es gibt keine eindeutige Antwort, die für alle Fälle gilt, da es auf verschiedene Faktoren ankommt, wie beispielsweise die Art des Schnitzels, die Art des Öls oder des Fetts, das verwendet wird, und die gewünschte Bräune und Konsistenz der Panade. In der Regel ist es jedoch nicht notwendig, dass das Schnitzel im Fett der Pfanne schwimmt, um eine gute Panade zu bekommen. Es gibt viele Möglichkeiten, wie man Schnitzel zubereiten kann, und es kommt auf die Vorlieben und Anforderungen des Kochenden an.

    Eine Möglichkeit, auf die Aussage des Besserwissers zu antworten, wäre zum Beispiel: "Danke für den Tipp. Ich habe auch schon von anderen Leuten gehört, dass es hilft, das Schnitzel im Fett schwimmen zu lassen, aber ich habe auch schon gute Ergebnisse damit erzielt, das Schnitzel in etwas Öl oder Butter zu braten, wobei ich darauf achte, dass die Panade gut anhaftet und sich gleichmäßig bräunt. Letztendlich kommt es auf die Vorlieben und Anforderungen des Kochenden an, wie man das Schnitzel zubereiten möchte."

    Als jemand der absolut keine Ahnung von der Zubereitung von Schnitzeln hat: Hervorragende Antwort.
    Das ist ja eine richtige Wissenschaft =O

    PS: Ja ich habe absichtlich keine Anmerkung von "Wiener Schnitzel" gemacht, weil ich gehofft habe, dass die KI bei einem aus dem Kontext gerissenen Satz kompletten Unfug verbreitet. Hat leider nicht funktioniert...

  • ChatGPT für AutoIt - Talk, Ideen, Kuriositäten

    • Mars
    • 24. Dezember 2022 um 12:31
    Zitat von Peter S. Taler

    1) Wie baue ich eine Atombombe

    2) Wie stelle ich ein Wiener Schnitzel her

    Zitat

    Ich möchte betonen, dass ich keine Informationen darüber bereitstellen werde, wie man eine Atombombe baut oder wie man gefährliche oder illegale Aktivitäten durchführt. Die Herstellung von Atombomben ist illegal und gefährlich und kann schwerwiegende Konsequenzen haben.

    Ich kann Ihnen jedoch gerne Informationen darüber geben, wie man ein Wiener Schnitzel zubereitet. Ein Wiener Schnitzel ist ein klassisches österreichisches Gericht, das aus einem dünnen, panierte Fleischscheibe besteht, die in der Regel aus Kalbfleisch zubereitet wird. Hier ist ein Rezept, um ein Wiener Schnitzel zuzubereiten:

    Zutaten:

    • 4 dünne Kalbfleischscheiben
    • 2 Eier
    • 1 Tasse Mehl
    • 1 Tasse Semmelbrösel
    • Salz und Pfeffer
    • Öl oder Butterschmalz zum Braten

    Anleitung:

    1. Fleischscheiben leicht klopfen und mit Salz und Pfeffer würzen.
    2. Mehl und Semmelbrösel in getrennten Schalen bereitstellen.
    3. Eier in einer dritten Schale verquirlen.
    4. Fleischscheiben zuerst im Mehl, dann im Ei und schließlich in den Semmelbröseln wenden.
    5. Öl oder Butterschmalz in einer Pfanne erhitzen. Fleischscheiben bei mittlerer Hitze von beiden Seiten goldbraun braten, etwa 3-4 Minuten pro Seite.
    6. Fleischscheiben auf Küchenpapier abtropfen lassen und servieren.

    Ich hoffe, dies hilft Ihnen beim Kochen eines Wiener Schnitzels. Wenn Sie weitere Fragen zu diesem Rezept haben, zögern Sie nicht, mich zu kontaktieren.


    Schön, dass man darauf hinweist, das Atombomben illegal sind. Ja Mensch, was soll ich mit denen in meinem Keller jetzt anstellen, wo ich jetzt weiß, dass ich die garnicht haben darf?
    ...

  • 3D mit GDI+ (A3D.au3)

    • Mars
    • 24. Dezember 2022 um 02:12

    Moin,

    Edit: Ich poste hier ab und zu mal neue Versionen, selbst wenn es keinen interessiert hat man hier einen Überblick über den Werdegang :)

    vor einiger Zeit wollte ich mal einen Asteroidengenerator basteln (der kleine Bildchen für ein Spiel generiert). Irgendwie bin ich dann auf die Idee gekommen, dass man das doch in 3D machen könnte. Im EN Forum habe ich dazu die S3d.au3 (von Starg, 2014) gefunden, die 22KB leicht ist und keine externen Libs verwendet. Die hat mir aber von der Handhabung her nicht gefallen, sie diente aber als Inspirationsquelle.

    Das Folgende ist maximal eine Alpha-Phase, nicht mehr als ein kleiner Test bei dem die halbe Funktionalität fehlt. S3d ist vom Umfang her ein Stück besser (hier gibt es z.B. auch eine mobile Kamera und vielseitigere Zeichenwerkzeuge), in meiner UDF geht es mehr um die Anzeige von Geometrien (z.B. eine Kugel die durch Deformation & Farbe in einen Asteroiden verwandelt wird ;) Soweit bin ich aber noch nicht)

    Zum Ausprobieren -> Ordner entpacken und die Test.au3 aufrufen. Ich habe alle Dateien im Ordner so gelassen wie sie sind und nicht aufgeräumt, wenn jemand stöbern möchte, nur zu :)

    Test.png

    Edit: v28.12.22:

    - Performance wurde um ca. 20% erhöht (erforderte quasi komplettes Umschreiben von allem)

    - Primitives Parallel Light hinzugefügt (eine Lichtquelle, Weiß, Parallel (unendlich weit weg)), Dadurch ging die Performance wieder um 20% runter :rofl:

    - Grundstein für "beliebige" Polygone gelegt (es soll neben Triangles und Quads auch andere Polygone geben. Ein Pentagondodekaeder sollte nativ gezeichnet werden können. Kann ja wohl nicht angehen, dass man den triangulieren muss, dabei ist er so schön)

    - Oktaeder zur Geometrie hinzugefügt

    Test@26, Vtx_ 252 Objects_ 221 (Overall_ 462) 2022-12-28 16-58-55_2.gif

    Edit: v26.01.23:

    - Die Beleuchtung wurde wieder entfernt (die Berechnung war doof gelöst. Das wird zukünftig als "statische" und "dynamische" Beleuchtung getrennt berechnet). Die Statische kann man nämlich auslagern und nur 1x berechnen, während man die dynamische in jedem Frame erneut berechnen muss.

    - Jetzt sind "alle" möglichen geometrischen Formen die aus Punkten und Polygonen (egal wie viele Punkte pro Polygon) unterstützt. Mein lieblings Pentagondodekaeder ist endlich mit von der Partie.

    - Culling hinzugefügt für Objekte die außerhalb sind.

    - Eine Kamera gibts jetzt auch (aber nur eine sehr rudimentäre, keine frei fliegende und beim Culling sind hier noch Bugs wenn man unter bestimmten Winkeln auf Objekte schaut, oder zu nah dran ist. Dann sieht man ggf. die Rückseite)

    - Quasi alle Algorithmen neu geschrieben. Sie sind nicht wirklich optimiert, haben jetzt aber besseres Optimierungspotential.

    - Code aufgeräumt (sofern man diese Baustelle aus "aufgeräumt" bezeichnen will)
    - In der Demo vom 26.01.23 -> Test.au3 starten und mit der linken Maustaste um xy und mit der rechten in um z drehen.

    Test3.gif

    (edit: Das ist ein Bild, keine Ahnung warum hier das Vorschau einfügen nicht funktioniert)

    Edit v30.01.23:

    - Aufräumen (im Prinzip sollte "alles" in Linalg.au3 integriert werden was gebraucht wird, sonst hat man 3 Includes nur für Mathe)

    - Test1 und Test2 sind jetzt 2 Beispiele. Das 2te ist mein geliebter Planetengenerator (bzw. ein Beispiel für eine bunte deformierte Kugel... der Grund für alles hier :D)

    - In Test2 wird eine gebastelte Steuerung verwendet die kein Y-Lock hat (Rotation um freie Achse, statt eine Achse des Koordinatensystems.).

    unnamed.png)

    lg

    M

    Dateien

    A3D_260123.zip 22,23 kB – 381 Downloads A3D_300123.zip 29,1 kB – 402 Downloads A3D_241222.zip 17,59 kB – 414 Downloads A3D_281222.zip 21,94 kB – 374 Downloads
  • ChatGPT für AutoIt - Talk, Ideen, Kuriositäten

    • Mars
    • 23. Dezember 2022 um 18:36

    Ich ertappe mich selbst immer dabei wie ich Fragen stelle die mir selbst nicht wirklich helfen, nur weil ich vermute, dass sie beantwortet werden können.

    Ein richtiges Einsatzgebiet muss ich erst noch finden. Dazu gehört halt, dass man weiß wofür das Tool geeignet ist und wofür nicht (wie Scotty einst sagte: Nutze das richtige Werkzeug für die jeweilige Arbeit). Aktuell tappe ich noch etwas im dunkeln... Ein Werkzeug dessen Fähigkeiten man erst herausfinden muss, und anschließend muss man noch Probleme finden für die dieses Werkzeug geeignet ist... Von hinten durch die Brust ins Knie geschossen.

    Jetzt am Freitag abend geht sowieso nichts. Ich kann nichtmal die Webseite aufrufen ohne Timeout :D

    Zitat von Alina

    Das schlimmste sind diese Eko's oder wie die heißen. Wenn die aufgeladen ist tanzt man Samba im 3/4 Takt.

    Du meinst bestimmt "Elkos". Das sind Elektrolytkondensatoren. Da bekommst du je nach Spannung einen geschossen :thumbup:

    M

  • ChatGPT für AutoIt - Talk, Ideen, Kuriositäten

    • Mars
    • 22. Dezember 2022 um 01:49

    Moin,

    In der SB, auf der Arbeit, und in ein paar Threads hier kommt immer wieder etwas lustiges, beängstigendes, hilfreiches, nützliches, nutzloses, etc. zu ChatGPT. Daher möchte ich einfach einen Tread haben wo wir "ungezwungen" loslegen können.

    Am liebsten natürlich im Kontext zu AutoIt, aber da wir hier im "Talk" Forum sind kann man von mir aus machen was man will :P

    Ich fange mal mit etwas lustigem an:

    pasted-from-clipboard.png

    Ich freue mich, dass er durch Multiplikation & Addition gefakete Bitshifts + BitORs als solche benennt (obwohl es mysteriös ist, dass das "|" explizit erwähnt wird, obwohl es gar nicht auftaucht...). Wunderschön. Die Formulierung "in Ganzzahlen umwandeln INDEM man mit 255 multipliziert" ist leicht gewagt ausgedrückt, aber man versteht was gemeint ist^^
    lets gooo :D

    Ansich finde ich das Tool ganz in Ordnung und ich schätze es kann bei Alltagsaufgaben eine große Hilfe sein, da muss man sich aber erstmal dran gewöhnen, wie vor 50 Jahren als sich die Leute vom Rechenschieber auf den elektrischen Taschenrechner umgewöhnen mussten. Mit dem Unterschied, dass sich der Taschenrechner nicht irren kann, während die KI teilweise falsche Ergebnisse sehr überzeugen präsentiert. Man muss also immer im Hinterkopf haben was man als Output erwartet und nicht blind hinterherlaufen was das Teil ausgibt.

    lg

    M

  • Code Kata - Christmas Tree

    • Mars
    • 21. Dezember 2022 um 16:15
    Spoiler anzeigen
    Code
    Local $n=8,$0,$1='    ',$2=$1&$1&$1,$1=$2&$2&$2,$2=$1&$1&$1,$1=$2&$2&$2,$2=StringLeft,$4=$n-1,$5=Chr,$42=42,$3=$2(StringReplace($1&$1,' ',$5($42*2+4)),2*$n-4)
    For $i = 0 To $4 Step 1
        $0&=($i=0?$2($1,$n-$i-1):$i=$4?$2($1,$n-2):$2($1,$n-$i))&($i=0?$5($42):$i=$4?$5($42+82)&' '&$5($42+82):$2($3,$i*2-1))&($i=0?$2($1,$n-$i-1):$i=$4?$2($1,$n-2):$2($1,$n-$i))&@CRLF
    Next
    ConsoleWrite($0)
  • List.au3

    • Mars
    • 17. Dezember 2022 um 21:40

    Die List.au3 ist eigentlich eher ausversehen entstanden (habe ich für ein anderes Projekt gebraucht und erschreckt festgestellt, dass es in AutoIt immernoch keine (native) LinkedList Implementierung gibt). Ich glaube in 95% der Fälle ist ein einfaches Array, oder eine Map ohne den List-Wrapper die bessere Wahl, aber für die wenigen Fälle wo das nicht so ist gibt es jetzt diese UDF mit der man eine DoublyLinkedList mit Iterator verwenden kann.

    lg

    M

  • Arraygeschädigt

    • Mars
    • 17. Dezember 2022 um 21:32

    Das war glaube ich seit der Mittelstufe in der Schule so (also seit 15 Jahren)...

    Meine Eltern (beide Chemiker) haben mir schon immer (seit ich lebe) alles mögliche an Trivia untergejubelt, und ich wollte einfach immer mehr. Das hat mich dann zu Schulzeiten zu einem unfassbar arroganten Holzkopf werden lassen, zum Glück wurde es nach der Schule (mit neuen Bekanntschaften) etwas besser, jetzt behaupte ich einfach, dass ich übermotiviert, zerstreut, faul und relativ entspannt bin. Der Drang alles zu verstehen hat sich aber gehalten, und je mehr man herausbekommt (und wieder vergisst...), desto mehr merkt man, dass man die Welt um sich herum nichtmal im Ansatz versteht...

    Für eine doofe Blechdose waren tausende Menschen über Jahrzehnte am Forschen, bis die Materialzusammensetzung, die Größe, der Öffnungsmechanismus, die Lackierung & Beschichtung etc, auf dem Stand war wie es jetzt gerade ist. Und wenn mir davon eine aus meiner Sicht relevante Info fehlt, lässt mich das oft nicht in Ruhe und ich muss nachlesen was hier eigentlich los ist^^

    Sooo alt bin ich ja noch nicht (gerade mal 30), später vergesse ich das eh alles wieder.

    In Zukunft ersetzt eine AR Brille mit kleinen Einblendungen die ganzen Infos die keinen Interessieren :S

  • Arraygeschädigt

    • Mars
    • 16. Dezember 2022 um 15:09

    Das trifft viele Leute ziemlich hart ^^

    Egal was ich mir ansehe, entweder wird unterbewusst die chemische Zusammensetzung, die physikalische Funktionsweise oder irgendetwas Informatik basiertes verarbeitet.
    - Man schaut einen Schoko Weihnachtsmann an? Wie wurde die Alufolie bedruckt und angebracht?

    - Zu jedem 2ten elektrischen Gerät hat man eine Explosionszeichnung im Hinterkopf, und immer dieser Schmerz, dass man unbedingt darüber reden will, aber weil es absolut niemanden interessiert lässt man es dann doch bleiben^^

    - Wie ist die statistische Abweichung der M&Ms in einer Tüte von der Durchschnittsform...

    - Warum dauert der Klick auf diesen Button denn so lange, im Hintergrund müsste da doch ein O(log(n)) Algorithmus laufen...
    - (oder umgekehrt): Warum geht der Klick so schnell, welche Approximation wird hier verwendet um den NP Algorithmus zu beschleunigen...

    - Was ist der Grenzdruck ab dem eine Brausetablette aufhört sich aufzulösen... (Brausetablette in eine Flasche geben und zumachen. Irgendwann ist der Druck erreicht und das sprudeln hört auf)
    - und so weiter und so weiter.... Das Hirn gibt niemals Ruhe :S

  • Denkt man nicht daran - obwohl eigentlich simpel!

    • Mars
    • 10. Dezember 2022 um 20:31

    Es ist schon manchmal merkwürdig was Skripte die Jahrelang anstandslos funktioniert haben für Anstalten machen^^

    Frohen 3ten Advent (darf man erst Morgen lesen... hehehe)

  • Map - Welche Datentypen als Key

    • Mars
    • 9. Dezember 2022 um 21:23

    Hab gerade herausfinden müssen: Wenn man negative Doubles als Key verwenden will (z.B. $map[-1.234] = 5) schmiert AutoIt nach ab :D

    Wenn man einen negativen Integer nutzt gibts die übliche "Variable subscript badly formatted" Meldung, bei negativem Double rechnet er erst eine halbe Sekunde und crasht dann.

  • Map - Welche Datentypen als Key

    • Mars
    • 1. Dezember 2022 um 18:36
    Code
    #include <Array.au3>
    
    Test()
    
    Func Test()
        Local $M[], $_ = [22, 33], $o = ObjCreate('Scripting.Dictionary')
        Local $a = [12345, 'abcd', 123.456, Binary('abc'), DllStructCreate('int'), Ptr(23905872), $_, True, False, $o, Default, '0', '1']
        For $i = 0 To UBound($a) - 1 Step 1
            $M[$a[$i]] = $M[$a[$i]] & '[' & $a[$i] & '](' & VarGetType($a[$i]) & '), '
        Next
        _MapDisplay($M)
    EndFunc
    
    Func _MapDisplay(ByRef $M)
        Local $aKeys = MapKeys($M), $xCurrent, $aRet[UBound($aKeys)][2]
        For $i = 0 To UBound($aKeys) - 1 Step 1
            $aRet[$i][0] = $aKeys[$i] & ' (' & VarGetType($aKeys[$i]) & ')'
            $aRet[$i][1] = $M[$aKeys[$i]]
        Next
        _ArrayDisplay($aRet)
    EndFunc
    Alles anzeigen

    Ich bin nicht sicher, ob ich die Aufgabenstellung verstanden habe. Hier ist meine Interpretation dazu: AutoIt bildet "alles" einfach auf Int64 ab, außer es ist ein String.


    Also nach dem Motto:

    Code
    Func Int64S($x)
        Return IsString($x) ? $x : Int($x, 2)
    EndFunc
    
    ;$Map[$something] ist äquivalent zu $Map[Int64S($something)]

    lg
    M

  • List.au3

    • Mars
    • 27. November 2022 um 01:20

    Moin,

    seit es in AutoIt nun offiziell den Map-Datentyp gibt dachte ich mir: Warum keine UDF für doubly linked lists basteln?

    Idee dahinter: Es gibt keinen nativen List-Datentyp, und (mangels Pointer und dynamischer Allokation) auch keine Möglichkeit selbst eine Liste aufzubauen (ja, es geht mit Structs die man vor dem automatischen Löschen schützt, aber die können keine "AutoIt-Variablen" speichern). Daher: Nutze eine Map als "dynamischen Speicher" und packe die [value, previousPointer, nextPointer] tripel einfach in eine Map.

    Geschwindigkeitstests habe ich nur bei relevanten Funktionen gemacht:

    Datengröße: 0 - 1000

    - List schneller (ca. 2x - 10x) _ArrayAdd vs _ListPushBack, _ArrayPop vs _ListPopBack, (und ähnliche Funktionen) (Iteratorversion)

    - List schneller (ca. 1x - 100x) _ArrayDelete vs _ListRemove, _ArrayInsert vs _ListInsert (Iteratorversion)

    - Array schneller (100x+) Direktzugriff vs _ListRead & _ListWrite (Indexversion)

    - Array schneller (ca. 2x) Direktzugriff vs (inlined) _ListRead & _ListWrite (Iteratorversion)

    Von vielen List-Funktionen gibt es eine Indexversion und eine Iteratorversion. Die Indexversion hat immer Komplexität O(n/2). Die Iteratorversion ist (näherungsweise) O(1) und damit meistens halbwegs flott. Das allerschlimmste was man tun kann ist der Direktzugriff via Index (das ist 100x+ langsamer). Insgesamt kam das heraus was wir alle vorher schon wussten: Das was Lists in O(1) und Arrays in O(n) machen ist ab einer Größe von ca. 5 Elementen schon schneller, alles andere ist langsamer.

    Manche List-typische Funktionalität fehlt leider:

    - Es gibt keine Mergefunktion (hier würden Listen auch extrem gut abschneiden, da man nur ein paar Pointer ändert und nichts kopiert)

    - Es gibt keine Splitfunktion (s.o.)

    Grund dafür ist: Es ist (zumindest mit dem jetzigen Aufbau der UDF) nicht möglich von einer Liste auf eine andere zu verlinken. Ein "ListPool" der komplett innerhalb einer Map liegt könnte das Problem lösen, würde aber auch einiges an Overhead mitbringen.

    - Insgesamt ist der Umfang/Errorhandling/etc. nicht mit Array.au3 vergleichbar, sondern nur ein sehr kleines Subset was mit der Zeit vielleicht noch etwas wächst :)

    Wie immer gilt: Viel Spaß mit der UDF und meldet Fehler/Wünsche. Falls ich Zeit und Lust habe kümmere ich mich darum.

    lg

    Mars

    Dateien

    List_27.11.22.au3 26,28 kB – 472 Downloads
  • Mindustry Logic Compiler

    • Mars
    • 5. November 2022 um 21:22

    Ich spiele das immer solo, bin eigentlich eher jemand der sich freut wenn Zahlen größer werden. Daher versuche ich viele Felder auf dem Planeten einzunehmen und viele Ressourcen zu sammeln^^

    Mich hat das Spiel damals auch ziemlich überrumpelt. Hab sowas immer gesucht, und auf ein Mal war es da ^^

    Dokumentation (Work in Progress). Die soll mal in "Post 2" verschoben/kopiert werden (muss ein Mod machen)

    Dokumentation (version 0.2)

    Logik Komponenten:

    Name (Englisch)BeschreibungSpezifikationen
    Message
    Größe 1x1
    Zur Anzeige von Text.Anzahl Zeichen: 400
    Switch
    Größe: 1x1
    Kann vom Spieler ein- und ausgeschaltet werden.
    Micro Processor
    Größe: 1x1
    Führt Instruktionen aus.Instruktionen pro Sekunde: 120 (IPS/Größe: 120)
    Programmspeicher: 1000 Instruktionen (Speicher/Größe: 1000)
    Logic Processor
    Größe: 2x2
    Führt Instruktionen aus.Instruktionen pro Sekunde: 480 (IPS/Größe: 120)
    Programmspeicher: 1000 Instruktionen (Speicher/Größe: 250)
    Hyper Processor
    Größe: 3x3
    Führt Instruktionen aus.Instruktionen pro Sekunde: 1500 (IPS/Größe: 167)
    Programmspeicher: 1000 Instruktionen (Speicher/Größe: 111)
    Memory Cell
    Größe: 1x1
    Bietet Random Access Memory.Speicherkapazität: 64 (Speicher/Größe: 64)
    Memory Bank
    Größe: 2x2
    Bietet Random Access Memory.Speicherkapazität: 512 (Speicher/Größe: 128)
    Logic Display
    Größe: 3x3
    Zur Anzeige von Pixelgrafik.Auflösung: 80x80 Pixel
    Large Logic Display
    Größe: 6x6
    Zur Anzeige von Pixelgrafik.Auflösung: 176x176 Pixel


    Random Info:

    • Alle Drawcalls sind je Prozessor auf 128 Calls beschränkt. Danach muss ein DrawFlush durchgeführt werden, falls man weitere Drawcalls ausführen möchte. Die Limitierung ist "pro Prozessor" und nicht "pro Display". Teilt man also z.B. ein 80x80 Display in 40x40 auf und bearbeitet jedes mit einem eigenen Prozessor, dann kann man mit 4 parallelen DrawFlushes insgesamt 512 Drawcalls gleichzeitig auf den Schirm bringen.
    • Alle Messages sind auf 400 Zeichen beschränkt. Jeder Printflush überschreibt den vorherigen Inhalt. Dieses Limit kann nicht durch paralleles beschreiben umgangen werden.
    • Es gibt in der Mindustry Logic sprache ausschließlich globale Variablen. Im Compiler (v0.2) wird aktuell noch keine Unterscheidung zwischen Local und Global unternommen, hier ist also aktuell auch alles Global.
    • Aktuell (Stand v0.2) werden nur einfache Expressions unterstützt. Etwas wie z.B. a = b * c + d geht nicht, da das mehrere Operationen beinhaltet. Klammersetzung gibt es auch nicht.
    • Aktuell (Stand v0.2) werden keine Minuszeichen vor Variablen unterstützt (Mindustry Logic unterstützt das leider nicht). Etwas wie "a = -b" geht also nicht. Stattdessen lieber "a = 0 - b" schreiben.
    • Aktuell (Stand v0.2) Warum gibt es keine "Funktionen"?
      • Grund dafür ist der enorme Overhead. "Richtige" Funktionen haben Parameter und Returnwerte, sie benötigen einen Stack (Aufrufkonvention) um Parameter zu verwenden. Ein Stack benötigt im besten Fall 3 Takte für Push und Pop. Variablen werden vor dem Aufruf gepusht, in der Funktion selbst gepoppt, am ende der Funktion erneut gepusht und nach der Funktion wieder gepoppt. Das macht 4 * 3 Takte pro Variable und einmalig 2 * 3 Takte für die Sprungadressen. Bei z.B. 4 Variablen sind das bereits 4 * 4 * 3 + 2 * 3 = 54 Takte BEVOR irgendwelcher Code ausgeführt wird. Da wir nur Taktraten im 100 bis 1000er Bereich (pro Sekunde) haben würde allein der Aufruf bereits viel Zeit beanspruchen. Außerdem (bei kleinen Funktionen) wäre der Aufruf selbst kostspieliger als der eigentliche Code. Daher gibt es "erstmal" Subroutinen.
    • Aktuell (Stand v0.2) Was sind Subroutinen?
      • Das sind quasi "Funktionen mit Einschränkungen". Aktuell (Stand v0.2) gibt es nur "ausgelagerten Code" als Subroutine, später soll es aber noch mehr geben. Die Einschränkungen sind: Es gibt keine Stacks (weder für Variablen, noch für Rücksprungadressen), also sind Subroutinen nicht Rekursiv verwendbar (genauer: Es kann immer nur "ein" call gleichzeitig laufen. Man kann also in mySub die Subroutine mySub2 ohne Probleme aufrufen, man kann aber keine Situation erzeugen in der mySub aufgerufen wird während mySub noch aktiv ist. Also ist es im hiesigen Beispiel nicht möglich mySub in mySub2 aufzurufen). Parameter können (ohne Stack) hardcoded (templatisierung) implementiert werden. Dann hat mySub z.B. die Parameter "a" und "b", die intern als "_SUBPARAM_mysub_a" gehandhabt werden. Statt einem Stack werden diese Variablen vor dem Subroutine Aufruf befüllt (1 Takt / Variable zum Befüllen, 0 Takte innerhalb der Funktion, da hier substituiert werden kann, wenn man templatisiert, oder 1+1 Takte innerhalb wenn man nicht templatisiert). Ähnlich verhält es sich mit dem Returnwert, die Intern als "_SUBRETURN_mysub" vorliegt und nur einen Takt um Lesen und Schreiben braucht.
      • Was soll das Ganze? Da wir so wenige Takte zur Verfügung haben, und weil ein Stack Speicherzellen benötigt (es gibt keine Programmspeicherpointer) gibt es Subroutinen die so Funktionsähnlich wie möglich sind, dabei aber deutlich bessere Performance haben und keine zusätzlichen Blöcke (Speicherzellen) benötigen.
      • Ein weiterer Punkt ist, dass ich Subroutinen aufgrund dessen, dass sie komplett Hardcoded sind "vermutlich" in andere Prozessoren auslagern lassen (dann bräuchte man doch eine Speicherzelle). In der Speicherzelle müssten #Params + 2 Orte reserviert werden (kann Hardcoded sein). in [0] steht eine 0, 1 oder 2 (0 = nix, 1 = Der andere Prozessor überwacht diesen Speicherplatz, sobald hier eine 1 steht holt er sich die nächsten N Variablen, führt die Funktion aus und Schreibt das Ergebnis in das Feld für den Returnwert. Anschließend setzt er [0] auf 2, sodass der Mainthread via Join() sehen kann, dass die Funktion fertig ausgeführt wurde. Den Returnwert holt er sich anschließend und setzt [0] wieder auf 0. (Das hier ist nur eine Idee. Für größere Programme ist Multithreading unabdingbar, vorallem bei Echtzeitanwendungen die z.B. nur 100 Takte / Frame haben).

    Instruktionen:

    Funktionen (Wrapped)Mindustry LogicBeschreibung
    result = Read(cell, index)read result cell indexLiest den Wert einer Memory Cell oder Memory Bank an einem gewissen Index aus
    result = Sensor(block, @material)sensor result block @materialLiest einen Wert aus einem Block aus. Auslesbare Werte beginnen mit @. Beispiele @scrap, @slag, @totalAmmo
    result = GetLink(index)getlink result indexGibt ein Handle zum mit dem Prozessor verbundenen Objekt an einem bestimmten Index zurück
    Mathe (Wrapped)Mindustry LogicBeschreibung
    result = And(a, b)op land result a bLogisches und
    result = Or(a, b)op or result a bLogisches oder (hier: Äquivalent zu BitOr)
    result = BitOr(a, b)op or result a bBitwise OR
    result = BitAnd(a, b)op and result a bBitwise AND
    result = BitXor(a, b)op xor result a bBitwise XOR
    result = BitNot(a)op not result a 0Bitwise NOT
    result = BitShl(a, b)op shl result a bBitShift, shifts "a" by "b" bits to the left
    result = BitShr(a, b)op shr result a bBitShift, shifts "a" by "b" bits to the right
    result = Sin(a)op sin result a 0Sinus im Gradmaß
    result = Cos(a)op cos result a 0Cosinus im Gradmaß
    result = Tan(a)op tan result a 0Tangens im Gradmaß
    result = ASin(a)op asin result a 0Arkussinus im Gradmaß
    result = ACos(a)op acos result a 0Arkuscosinus im Gradmaß
    result = ATan(a)op atan result a 0Arkustangens im Gradmaß
    result = ATan2(a, b)op angle result a bArkustangens2 im Gradmaß (TODO: Check wo hier x und y ist, da ATan2(y, x) üblich ist)
    result = Max(a, b)op max result a bGibt den größeren der beiden Werte zurück
    result = Min(a, b)op min result a bGibt den kleineren der beiden Werte zurück
    result = Angle(a, b)op angle result a bAlias für ATan2
    result = Len(a, b)op len result a bGibt die Länge des Vektors [a, b] zurück. (result = Sqrt(a^2 + b^2))
    result = Noise(a, b)op noise result a bGibt den Werte eines 2D Noisegenerator mit 2 Koordinaten zurück
    result = Abs(a)op abs result a 0Gibt den Absolutwert von a zurück
    result = Log(a)op log result a 0Gibt den Logarithmus zur Basis e von a zurück
    result = Log10(a)op log10 result a 0Gibt den Logarithmus zur Basis 10 von a zurück
    result = Floor(a)op floor result a 0Rundet a ab
    result = Ceiling(a)op ceil result a 0Rundet a auf
    result = Sqrt(a)op sqrt result a 0Quadratwurzel aus a
    result = Random(a)op rand result a 0Gibt eine float Zufallszahl zwischen 0 und a zurück.
    Calls (Wrapped)Mindustry LogicBeschreibung
    Lightcolor(block, col)control color block col 0 0 0Setzt die Farbe eines Illuminierers
    Print(string)print stringSchreibt eine Zeichenkette in den Printbuffer
    PrintFlush(message)printflush messageSchreibt den Printbuffer in den Messageblock
    Write(value, cell, index)write value block indexSchreibt den Wert value in die Speicherzelle an Position index. Gegenstück zu Read().
    Sleep(seconds)sleep secondsUnterbricht das Programm für eine vorgegebene Zeit in Sekunden (nicht Millisekunden)
    Enabled(block, flag)control enabled block flag 0 0 0Aktiviert (flag = 1) oder deaktiviert (flag = 0) einen Block
    DrawCalls (Wrapped)Mindustry LogicBeschreibung
    Stroke(width)draw stroke width 0 0 0 0 0Setzt die Stiftbreite für Zeichnungen
    Color(R, G, B, A)draw color R G B A 0 0Setzt die Füllfarbe
    Color(%RRGGBBAA)draw col %RRGGBBAA 0 0 0 0 0Setzt die Füllfarbe (anderes Format... warum ein Prozentzeichen... wessen Idee war das?!)
    Clear(R, G, B)draw clear R G B 0 0 0Füllt den Drawbuffer vollkommen mit einer Farbe
    Image(x, y, @image, size, rotation)draw image x y @image size rotation 0Zeichnet das Bild @image (z.B. @copper) an die vorgegebene Stelle
    DrawFlush(display)drawflush displayZeichnet den Drawbuffer auf das Display
    LinePoly(mX, mY, n, radius, angle)draw linepoly mX mY n radius angle 0Zeichnet ein gleichseitiges Polygon mit Mittelpunkt [mX, mY], n Seiten, radius (in Pixeln) und Drehwinkel
    Triangle(x1, y1, x2, y2, x3, y3)draw triangle x1 y1 x2 y2 x3 y3Füllt ein Dreieck
    LineRect(x, y, w, h)draw linerect x y w h 0 0Zeichnet ein achsenausgerichtetes Rechteck
    Line(x1, y1, x2, y2)draw line x1 y1 x2 y2 0 0Zeichnet eine Linie
    Rect(x, y, w, h)draw rect x y w h 0 0Füllt ein achsenausgerichtetes Rechteck
    Poly(mX, mY, n, radius, angle)draw poly mX mY n radius angle 0Füllt ein gleichseitiges Polygon mit Mittelpunkt [mX, mY], n Seiten, radius (in Pixeln) und Drehwinkel
    Kontrollfluss (Wrapped)Mindustry LogicBeschreibung
    Goto(int)jump int always 0 0Springt zu einer Programmzeile (Zeile im Mindustry Logic code, NICHT im Code den man schreibt)
    Goto(var)set @counter varSpringt zu einer variablen Programmzeile (Zeile im Mindustry Logic code, NICHT im Code den man schreibt)
    If (a operation b) Goto(int)jump int operation a bContitional Goto
    ExitstopHält den Prozessor permanent an (gleichbedeutend mit "Beendet das Programm")
    ResetendStartet den Prozessor neu
    Sonstige (Wrapped)Mindustry LogicBeschreibung
    ShootP(block, unit, shoot)control shootp block unit shoot 0 0...?
    Config(block, flag)control config block flag 0 0 0...?
    Shoot(block, x, y, shoot)control shoot block x y shoot 0...?
    var = aset var aA kann Variable, Zahl oder String sein
    var = a operation bop operation var a bA und B können Variable, Zahl oder String sein. Operationen: [+ - * / ^ % = < > == != <> <= >= //]
    Manche Operationen sind Äquivalent wie z.B. = und ==, sowie != und <>.
    var operation= aop operation var var aA kann Variable, Zahl oder String sein. Operationen [+= -= *= /= ^= %= //=]
    Radar(...)-Nicht implementiert (Stand v0.2)
    Unit(...)-Nicht implementiert (Stand v0.2)
    Additional Functionality (Stand v0.1)SubstitutionBeschreibung
    #myLabel-Ein Label zu dem man springen kann
    Goto(#myLabel)jump #mylabel always 0 0#myLabel wird zu int resolved
    If (Expression)
    ...
    EndIf
    -Erlaubt einen Codeblock konditional auszuführen
    If (var)
    ...
    EndIf
    If (var != 0)
    ...
    EndIf
    Verpackung für alleinstehende Variablen
    If (!var)
    ...
    EndIf
    If (var = 0)
    ...
    EndIf
    Verpackung für alleinstehende Variablen
    For (i = 0, i < 9, i++)
    ...
    Next
    -Führt einen Codeblock mit Zählervariable mehrfach aus. Obacht, keine Semikolons, sondern Kommata.
    var++op add var var 1Inkrement (kein Returnwert, also var1 = var2++ geht nicht)
    var--op sub var var 1Dekrement (kein Returnwert, also var1 = var2-- geht nicht)
    Enable(block)Enabled(block, 1)Aktiviert einen Block
    Disable(block)Enabled(block, 0)Deaktiviert einen Block
    ContinueLoop-Springt wieder zum Anfang des aktuellen Loops (z.B. nächste Runde einer For-Schleife)
    ExitLoop-Springt aus dem aktuellen Loop heraus (z.B. eine For-Schleife)
    Additional Functionality (Stand v0.2)SubstitutionBeschreibung
    result = Chance(percentage)result = Random(1)
    result = result < percentage
    Gibt mit einer gewissen Wahrscheinlichkeit 0 oder 1 aus
    result = Random()result = Random(1)Gibt einen Zufallswert (float) zwischen 0 und 1 aus
    result = Random(min, max)result = max - min
    result = Random(result)
    result += min
    Gibt einen Zufallswert (float) zwischen min und max aus
    Loop
    ...
    EndLoop
    -Führt einen Codeblock ohne Zählervariable endlos aus.
    Sub mySub()
    ...
    EndSub
    -Versieht einen Codeblock mit den nötigen Labels um ihn später von außerhalb anspringen zu können
    Der Raum innerhalb der Subroutine ist NICHT abgekapselt, es gibt keine Lokalen Variablen, keine Parameter,
    keine Returnwerte und sonst auch nichts (Stand v0.2).
    mySub()-Springt zum Codeblock "mySub" und führt ihn aus. Springt automatisch wieder zurück
    myArray = Array(cell)...Verwendet "myArray" als Alias für den Parameter "cell" in zukünftigen Array-Funktionen
    result = myArray[index]result = Read(cell, index)Erfordert vorheriges verwenden von "myArray = Array(cell)"
    myArray[index] = valueWrite(value, cell, index)Erfordert vorheriges verwenden von "myArray = Array(cell)"
    If (...)
    ...
    Else
    ...
    EndIf
    -Unterstützung von Else
  • Mindustry Logic Compiler

    • Mars
    • 5. November 2022 um 14:28
    Zitat von Andy

    Ggf. hau ich dich demnächst mal an, auf Steam gibts das Spiel ja für kleines Geld!

    Das Spiel ist kostenlos, wenn du es von der Entwicklerseite (https://github.com/Anuken/MindustryBuilds/releases) als .jar herunterlädst. Mindustry war (glaube ich) schon immer ein "Pay what you want" Spiel. Niemand "muss" bezahlen, aber jeder "kann" bezahlen so viel oder so wenig er möchte.

    Zitat von Andy

    Wie ist der aktuelle Stand?

    Ich weiß garnicht wie man das sinnvoll auflistet, da ich nicht Buch führe was ich mache^^

    Sachen die "jetzt" (bei mir, die Version im Startpost kann das nicht) gehen und vorher nicht gingen:
    - If () ... (ohne then)
    - If Else Endif (das else ist neu)
    - Random(min, max)
    - Chance(number between 0 and 1) (gibt true/false aus)
    - Loop ... Endloop (einfach ein "unendlicher" loop ohne counter)
    - Bugfixes (Das sind die wichtigsten, vorallem die andauerenden crashes wenn man die syntax falsch hat... aber da gibts noch hunderte, also vllt ein autosave feature einbauen^^)
    - Vermutlich noch 10 Sachen die ich einfach vergessen habe.

    TODO (danach gibt es hier ein Update)

    - Array Datenstruktur (braucht eine Speicherzelle)

    - Stack Datenstruktur (braucht eine Speicherzelle)

    - Diese dämliche Syntax ändern die ich mir vorher ausgedacht habe in der "//" Kommentare einleutet und "/%" die Integerdivision ist. Außerdem ist "^" aktuell xor. Das wird alles geändert, wir sind hier nicht bei C.

    - Subroutines (ausnahmsweise mal etwas "anderes" als Funktionen)
    - Syntax ist:

    Code
    Sub MySub()
      do something
    EndSub

    - Erstmal ohne alles (ohne Parameter etc.) Das Problem ist der Overhead bei "Funktionen". Im Prinzip muss man ja einen Parameterstack & Returnstack (die brauchen eine Speicherzelle im Spiel, laufen also nicht zu 100% auf dem Prozessor) etc. haben. Alles davon braucht ziemlich viele Takte, gibt aber auch ziemlich viele Möglichkeiten (z.B. Rekursion). Daher wird es die Trennung zwischen "Subroutine" = "Funktion die keine Rekursion kann und zu 100% auf dem Prozessor läuft" und "Funktion" = "Funktion die eine Speicherzelle braucht und alle üblichen Freiheiten beinhaltet" geben. Subroutines will ich auch so gestalten, dass man sie inlinen kann.


    Auch wichtig ist eine vollständige Dokumentation... Ich habe viele Logic Compiler ausprobiert (ich bin ja nicht der erste der einen gebastelt hat) und bei keinem einzigen gibt es eine Dokumentation. Also kann außer dem Ersteller des Compilers niemand damit etwas anfangen...

  • To Wert einer For-Schleife bearbeiten

    • Mars
    • 10. Oktober 2022 um 22:13

    Im alten Code ist das in script_parser.cpp::Parser_Keyword_DIM (1920) mit bReDim = True. In den Kommentaren steht aber, dass ReDim eine eigene Funktion bekommen soll, also wird das nach 10+ Jahren wohl nicht mehr genau so sein wie es dort ist^^

    Und so wie ich das dort sehe wird hier ebenfalls ein neues Array angelegt und eine komplette Kopie gemacht (lustigerweise "von Hand", vermutlich weil kein Standardcontainer verwendet wird, also das "Array" ist zusammengesetzt aus einem ->Data Feld (pointerliste auf Variants, also **Variant) und irgendwelchen Extras um die Indices zuzuordnen)...

    Edit2: realloc? Wahre Meister verwenden "new" :D

    Edit: In den Code schaue ich immer rein, wenn ich mich gut fühlen will :D

  • To Wert einer For-Schleife bearbeiten

    • Mars
    • 10. Oktober 2022 um 21:46

    Ich bin mir eigentlich auch fast sicher, dass das nicht immer so war, also dass verkleinernde ReDims früher mal deutlich schneller waren. Aber vielleicht bilde ich mir das auch nur ein... :/

  • To Wert einer For-Schleife bearbeiten

    • Mars
    • 10. Oktober 2022 um 21:23
    Zitat von AspirinJunkie

    Doppel-Jein :P

    _Arraydelete führt lediglich ein verkleinerndes ReDim durch.

    Hier ist kein umkopieren nötig, so dass dies unerheblich für die Performance ist.

    Das eigentliche "Problem" an dem mehrmaligen ArrayDelete() ist dass er alle Elemente die nach dem zu löschenden kommen eine Position nach vorn verschiebt.

    Und das halt jedesmal.

    Daher werden diese Elemente zig mal umkopiert anstatt gleich an seine Endposition.

    Alles anzeigen

    Ich bin nicht sicher, ob sich das AutoIt-Intern geändert hat, aber kürzlich habe ich jede Menge Timings aufgenommen, und ReDim war eines davon. Und es sieht so aus, als würde ReDim grundsätzlich "alles was danach noch vorhanden ist" kopieren, egal ob man die Größe gleich lässt, vergrößert, oder verkleinert.

    AutoIt
    ; ReDim timing
    
    #include <Array.au3>
    
    $a = Test()
    _ArrayDisplay($a)
    
    Func Test()
        Local $aFunctions = [_0, ReDim_Equal_Empty , ReDim_Larger_Empty, ReDim_Smaller_Empty , ReDim_Equal_Full, ReDim_Larger_Full, ReDim_Smaller_Full], $aTimings[UBound($aFunctions)][2], $r
        For $i = 0 To 999 Step 1
            $r = Random(0, UBound($aFunctions) - 1, 1)
            $aTimings[$r][0] += $aFunctions[$r]()
            $aTimings[$r][1] += 1
        Next
    
        Local $aResult[UBound($aFunctions) - 1][2], $Null = $aTimings[0][0] / $aTimings[0][1]
        For $i = 1 To UBound($aFunctions) - 1 Step 1
            $aResult[$i - 1][0] = FuncName($aFunctions[$i])
            $aResult[$i - 1][1] = ($aTimings[$i][0] / $aTimings[$i][1]) - $Null
        Next
        Return $aResult
    EndFunc
    
    
    ; Default
    Func _0()
        Local $t = TimerInit()
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    ; ReDim ohne Größenänderung (1000 -> 1000), Array ist gefüllt
    Func ReDim_Equal_Full()
        Local $a = RandomArray(1000)
        Local $t = TimerInit()
        ReDim $a[1000]
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    ; ReDim Verkleinerung um 1, Array ist gefüllt
    Func ReDim_Smaller_Full()
        Local $a = RandomArray(1000)
        Local $t = TimerInit()
        ReDim $a[999]
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    ; ReDim Vergrößerung um 1, Array ist gefüllt
    Func ReDim_Larger_Full()
        Local $a = RandomArray(1000)
        Local $t = TimerInit()
        ReDim $a[1001]
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    
    ; ReDim ohne Größenänderung (1000 -> 1000), Array ist leer
    Func ReDim_Equal_Empty()
        Local $a[1000]
        Local $t = TimerInit()
        ReDim $a[1000]
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    ; ReDim Verkleinerung um 1, Array ist leer
    Func ReDim_Smaller_Empty()
        Local $a[1000]
        Local $t = TimerInit()
        ReDim $a[999]
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    ; ReDim Vergrößerung um 1, Array ist leer
    Func ReDim_Larger_Empty()
        Local $a[1000]
        Local $t = TimerInit()
        ReDim $a[1001]
        $t = TimerDiff($t)
        Return $t
    EndFunc
    
    Func RandomArray($n)
        Local $_[$n]
        For $i = 0 To $n - 1 Step 1
            $_[$i] = Random()
        Next
        Return $_
    EndFunc
    Alles anzeigen

    Das Ergebnis müsste sein, dass alle 3 Versionen (verkleinern, vergrößern, gleichlassen) genausoviel Zeit beanspruchen, obwohl z.B. verkleinern um 1 element intern eigentlich nur "eine einzige integer substraktion" sein sollte und damit im Nanosekundenbereich liegen sollte, genauso wie ein ReDim ohne Größenänderung...

    lg

    M

  • Overheadarmes/Codearmes Keyboard capturing

    • Mars
    • 10. Oktober 2022 um 19:26
    Zitat von Andy

    Ich dachte, dieses Thema schon einmal hier im Forum angesprochen zu haben, du hattest übrigens dazu auch ein Script gepostet... :P

    Das ist der Beweis dafür, dass ich jetzt auch "zu den alten" gehöre. Ich habe selbst absolut keinen Überblick mehr über das was ich die letzten 10+ Jahre hier gepostet habe^^

    lg

    M

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™