rsnake

In meinem letzten Einträgen ist bereits angeklungen, dass ich Rust mag. Und wie die Erfahrung [1, 2, 3] zeigt, dauert es nie lange bis ich eine Snake-Abwandlung programmiere.

Dieses Mal verfolgt der Autopilot die Strategie des smart kinetic walk, (ein Model aus der statistischen Physik zur Simulation von Polymeren,) um sich nicht selbst zu beißen — leider setzt diese Strategie ein unendlich großes Spielfeld voraus.

Die grundlegende Idee ist, dass die Schlange immer wenn sie sich selbst begegnet prüft welcher nächste Schritt sie in einer Schlaufe fängt und welcher nach außen führt. Mit offenen Randbedingungen, also auf einem unendlich großen Feld lässt sich dass das in konstanter Zeit erledigen, wenn die Schlange an jedem Segment ihres Körpers die Anzahl der Rechts- und Linksdrehungen speichert. Bei periodischen Randbedingungen funktioniert das allerdings nicht mehr, sodass der Autopilot eine Best-First-Search durchführt. Auf offenen Randbedingungen würde es ausreichen einen Weg vom potentiell nächstem Schritt zu einem beliebigen Punkt außerhalb eines Rechtecks, das die Schlange einschließt, zu finden. Bei periodischen Randbedingungen ist es nicht so eindeutig. Ich habe mich entschlossen, dass die Schlange sich nur so bewegen soll, dass immer ein Pfad zu ihrem Schwanz existiert. Tatsächlich führt diese Strategie zu unterhaltsamen und nicht perfekten Spielverläufen.

Der Vollständigkeit halber sind noch ein nicht vorausplanender und ein perfekter, aber langweiliger, Autopilot dabei.

Da die Quellen auf GitHub liegen, ist es nur vier Zeilen entfernt — weniger, wenn der Rustcompiler bereits installiert ist.

    # curl https://sh.rustup.rs -sSf | sh  # never copy `| sh` in your terminal
    git clone https://github.com/surt91/rsnake
    cd rsnake
    cargo run --release

A Graph a Day

Vor einiger Zeit habe ich @randomGraphs geschrieben: Ein Twitterbot, der einen Zufallsgraphen pro Tag tweetet.

Die meisten Graphtypen, die er darstellen kann stammen aus der NetworkX Bibliothek oder sind reale Netzwerke. Ein paar Proximity Graphs habe ich selbst geschrieben. Die Darstellung und gegebenenfalls das Layout übernimmt Cytoscape oder graph-tool (dessen Autor diesem Bot folgt).

Bei diesem Projekt habe ich exzessiv Gebrauch von Pythons Decorator und Introspection gemacht, sodass man, um einen neuen Graphtyp einzuführen nur eine Methode schreiben muss, die eine Graph-Datenstruktur zurück gibt. Einstellungen, welche Darstellungen erlaubt sind, werden per decorator getätigt und alle Methoden werden per Introspection automatisch zum Pool hinzugefügt, aus dem der Zufallsgenerator zieht.

Eine typische Methode sieht etwa so aus.

@synonym("Barabasi Albert")
@synonym("preferential attachment")
@style(styles_all)
@layout(["kamada-kawai", "force-directed", "sfdp", "fruchterman_reingold", "arf", "radial_tree"])
def generateBarabasiAlbert(self, N=None, m=None, **kwargs):
    if N is None: N = random.randint(4, 400)
    if m is None: m = random.randint(1, 5)

    G = gen.barabasi_albert_graph(N, m)  # gen is networkx Generator
    details = dict(name="Barabási-Albert Graph", N=N, m=m, seed=self.seed,
                   template="{name}, N = {N}, m = {m}")

    return G, details

Und liefert für $N=226, m=1$ und das radial_tree Layout beispielsweise diesen Graph. Die Größe der Knoten wird hier von der Betweenness Centrality bestimmt.

Graph

Die @synonym Decorators ermöglichen die zweite Funktion des Bots, denn er tweetet nicht nur einmal am Tag einen zufälligen Graphen, sondern reagiert auch auf Mentions. Falls in der Mention der Name der Methode oder eines der per @synonym registrierten Worte auftaucht, antwortet er mit einem Bild des entsprechenden Graphen. Dank fuzzywuzzy ist es sogar resistent gegen Tippfehler.

Twitter unterstützt leider keine Vektorgrafiken und wandelt Bilder gerne in stark komprimierte .jpg, was gerade bei diesen Graphen zu störenden Artefakten führt. Dagegen hilft es, wenn ich einen Rand aus transparenten Pixeln dem Bild hinzufüge. Das führt dazu, dass Twitter .jpg nicht als geeignetes Format ansieht und die Bilder im verlustfreien .png ausliefert.

convert -alpha on -channel RGBA -bordercolor "rgba(0,0,0,0)" -border "1x1" input.png output.png

Graph

Der komplette Quellcode ist auf Github.

Labyrinthartiger Zellulärer Automat

Der wohl berühmteste zelluläre Automat ist vermutlich Conway’s Game of Life. Er und nahe Verwandte sind geradezu lächerlich gut untersucht. Das LifeWiki gibt einen ganz guten Überblick. Die Regeln sind einfach: Jede Zelle hat 8 Nachbarn, wenn genau 3 Nachbarn leben, erwacht sie auch zum Leben, bei weniger als 2 oder mehr als 3 stirbt sie (23/3). Wenn man die Regeln des Automaten ändert, kann man mit 12345/3 labyrinthartige Strukturen erzeugen.

Der Code ist als Gist auf GitHub verfügbar.