Code Bots 3: Parallele Programmierung von Antipattern

13

Willkommen zurück! Ich freue mich darauf, die 3. CodeBots-Herausforderung zu präsentieren. Dieser ist schon lange in Arbeit. Diese Herausforderung wird in drei Abschnitte unterteilt: die kurze Version, die lange Version und zusätzliche Details.

Die kurze Version

Jeder Teilnehmer schreibt ein Programm mit 24 Befehlen. Diese Bots bewegen sich auf der ganzen Welt und kopieren ihren Code in andere Bots, während sie versuchen, andere Bots daran zu hindern, dasselbe zu tun. Einer der möglichen Befehle ist das No-Op Flag. Wenn ein Bot mehr von dir hat Flagals jeder andere Flag, bekommst du einen Punkt. Sie gewinnen mit den meisten Punkten.

All dies traf auf die letzten beiden Herausforderungen zu. Diesmal können Bots mehrere Codezeilen gleichzeitig ausführen.

Die lange Version

Die API

Jeder Bot hat genau 24 Zeilen, wobei jede Zeile das folgende Format hat:

$label command parameters //comments

Beschriftungen und Kommentare sind optional, und jeder Befehl verfügt über eine andere Anzahl von Parametern. Alles ist unabhängig von Groß- und Kleinschreibung.

Parameter

Parameter sind typisiert und können in den folgenden Formaten vorliegen:

  1. Ein Wert von 0 bis 23.
  2. Eine Variable: A, B, C,D
  3. Ein Wert mit Zusatz: A+3oder2+C
  4. Eine Codezeile, die mit dem #Vorzeichen bezeichnet wird ( #4würde die 5. Zeile darstellen, während #C+2die durch berechnete Zeile darstellen würde C+2).
  5. Sie können eine $labelanstelle einer Codezeile verwenden.
  6. Die Variable oder Codezeile Ihres Gegners, bezeichnet mit *. Ihr Gegner ist der Bot auf dem Feld, dem Sie gegenüberstehen. ( *BStellt den BWert deines Gegners dar , während *#9die 10. Linie deines Gegners darstellt). Befindet sich niemand in diesem Feld, wird der Befehl nicht ausgeführt.

Befehle

Bewegen Sie V

Bewegt den Bot North+(V*90 degrees clockwise). Bewegung ändert nicht die Richtung.

Biegen Sie ab in die V

Dreht den Bot V*90 degreesim Uhrzeigersinn.

Kopieren Sie VW

Kopien , was in ist Vin W. Wenn Ves sich um eine Zeilennummer handelt, Wmuss es sich um eine Zeilennummer handeln. Wenn Ves sich um eine Variable oder einen Wert handelt, Wmuss es sich um eine Variable handeln.

Flagge

Tut nichts.

Stern Fernsehen

Startet einen neuen Thread, der an die Variable angehängt ist V. Der Thread führt den Befehl sofort und in jedem weiteren Zug online aus V.

Wenn Vbereits ein Thread angehängt ist, ist dieser Befehl ein No-Op. Wenn Ves sich um eine Variable eines Gegners handelt, startet der Gegner einen Thread, der an diese Variable angehängt ist.

Stoppen Sie V

Stoppt den an die Variable angehängten Thread am VEnde dieser Runde.

Schloss V

Verhindern Sie, dass die Zeile oder Variable Vauf irgendeine Weise verwendet wird, außer durch den aufgerufenen Thread Lock. Ein nachfolgender Aufruf von Lockdurch denselben Thread wird entsperrt V. Sperren können nicht für Variablen oder Zeilen des Gegners aufgerufen werden.

Wenn Cond VW

Dies wird getestet Cond. Wenn die Bedingung erfüllt ist, wird der Thread-Zeiger auf die Zeilennummer verschoben V, andernfalls auf die Zeilennummer W. Diese Zeile wird dann sofort ausgeführt.

Conditionals kann sein X=Y, X<Y, !X, oder ?X:

  1. X=Y testet, ob zwei Zeilen vom selben Typ und vom selben Bot sind, oder ob zwei Werte gleich groß sind.
  2. X<Ytestet, ob der Wert von Xkleiner als ist Y.
  3. !Xtestet, ob die Variable oder Zeile Xgesperrt ist (gibt true zurück, wenn gesperrt)
  4. ?X testet, ob an eine gegebene Variable ein Thread angehängt ist

Zusätzliche Details

Multithreading-Interaktionen

Aktionen des gleichen Typs werden zur gleichen Zeit ausgeführt. Aktionen werden in der folgenden Reihenfolge ausgeführt:

  1. Sperren. Wenn mehrere Threads versuchen, eine Variable zu sperren, schlagen alle fehl. Wenn ein Thread eine Variable entsperrt, während ein anderer versucht, sie zu sperren, bleibt die Variable entsperrt.

  2. Start. Wenn mehrere Threads versuchen, einen Thread für eine Variable zu starten, wird dies als ein einzelner Start gewertet.

  3. Kopieren. Wenn zwei Threads in dieselbe Variable kopiert werden, wird die Variable als zufälliger Wert ausgegeben. Wenn beide in dieselbe Zeile kopieren, funktioniert beides nicht. Wenn ein Thread in dieselbe Variable kopiert, aus der ein anderer Thread kopiert, kopiert der letztere Thread einen zufälligen Wert. Wenn zwei Threads von derselben Variablen kopiert werden, funktionieren beide einwandfrei.

  4. Wenn. Alle Bedingungen werden gleichzeitig getestet, und anschließend werden die Thread-Variablen aktualisiert. Das Ausführen von Ifkann dazu führen, dass eine Aktion mit einer höheren Priorität hinzugefügt wird. Aktionen mit höherer Priorität werden ausgeführt, bevor Sie an der vorbei gehen If, während Aktionen mit niedrigerer Priorität nach der ausgeführt werden If.

  5. Bewegung. Mehrere Züge auf demselben Bot bewegen den Bot um die Summe aller Züge. Wenn mehrere Bots am selben Ort landen, werden sie an ihren Startplatz zurückgebracht.

  6. Wende. Mehrere Runden auf dem gleichen Bot summieren sich.

  7. Halt. Mehrere Stoppbefehle für dieselbe Variable werden als ein Stopp gezählt.

Andere Details

Ihr erster Thread beginnt mit dem Anhängen an die DVariable

Die Wiederholung eines If(mit einer Ifauf sich selbst gerichteten Aussage) bewirkt, dass Ihr Bot nichts unternimmt

Wenn ein Thread nach dem Sperren gestoppt wird, werden diese Sperren entsperrt

Aktionen, die eine gesperrte Variable oder Zeile verwenden, bewirken nichts.

Wenn ein Bot kürzer als 24 Zeilen ist, werden die verbleibenden Zeilen mit gefüllt Flag

Wenn Sie einen Schreibvorgang für eine Variable ausführen, die auch an einen Startthread angehängt ist, beginnt der Thread seine Ausführung mit dem neuen Wert, wenn der Thread die folgende Runde beginnt.

Bots werden nach folgendem Muster in eine toroidale Welt gestellt:

B...B...B...
..B...B...B.
B...B...B...

Ich habe einige Beispiel- Bots hinzugefügt , die als Sprachreferenz kommentiert sind.

Die Steuerung befindet sich hier . Ich habe lange daran gearbeitet, aber es hat wahrscheinlich immer noch Fehler. Wenn die Spezifikation und der Controller widersprechen, ist die Spezifikation korrekt.

Anzeigetafel

1. 771  LockedScannerBot
2. 297  CopyAndSelfFlag
3. 289  DoubleTapBot
4. 197  ThreadCutterBot
5. 191  TripleThread
6. 180  ThickShelled
7. 155  Attacker
8. 99   RandomMover
9. 90   BananaBot
10. 56  LockedStationaryDoubleTap
Nathan Merrill
quelle
Wow, zumindest scheint DoubleTap viel besser zu sein als Samples!
Katenkyo
Was soll passieren, wenn ich versuche, eine gesperrte Variable aus einem anderen Thread zu lesen? Angenommen, ich mache LOCK A, dann gibt es in einem anderen Thread einen MOVE A. Wird A mit 0 oder einem zufälligen Wert bewertet, oder schlägt der Move fehl oder ...?
Sparr
Das Gleiche gilt für das, was passiert, wenn ein Thread eine von einem anderen Thread gesperrte Zeile erreicht. Ist es ein Noop? Wird es übersprungen?
Sparr
Sollte "Copy $ label A" funktionieren? Es wird als "Copy # 11 A" interpretiert, was nicht gültig ist und den Interpreter zum Absturz bringt, anstelle von "Copy 11 A", wie ich es mir erhofft habe.
Sparr
Möglicher Fehler ... Ich scheine in der Lage zu sein, meine eigenen Flaggenzeilen zu lesen, um sie zu kopieren, selbst wenn sie von einem anderen Thread gesperrt sind.
Sparr

Antworten:

3

Gesperrter Scanner-Bot

Scannt den Feind so schnell wie möglich und ersetzt die Linien durch Flaggen.

    Lock D
    Copy $a A
    Start A
    Copy $b B
    Start B

$d  Lock $d0
    Lock $d1    
$d0 Copy $flag *#C+1
$d1 If 1=1 $d0 $d0

$a  Lock A
    Lock $a0
    Lock $a1
    Lock $a2
$a0 Copy $flag *#C
$a1 Copy C+2 C
$a2 If !*#C $a1 $a0

$b  Lock B
    Lock $b0
    Lock $b1
    Lock $b2
$b0 Move C
$b1 Turn 1
$b2 If 1=1 $b0 $b0

$flag Flag
Die Nummer eins
quelle
Ich bin gespannt auf die Bedingung in deinem A-Thread. ! * # C prüft, ob die Leitung #C (Ihr C) Ihres Ziels gesperrt ist, oder? Wie ist das hilfreich?
Sparr
@Sparr Der A-Thread verschwendet keine Zeit damit, eine Zeile des Feind-Codes durch ein Flag zu ersetzen, wenn es gesperrt ist.
TheNumberOne
Vielen Dank. Ich habe die Spezifikation ursprünglich in Bezug auf die Geschwindigkeit von If-Anweisungen falsch gelesen.
Sparr
3

DoubleTapBot

Dieser Bot hat 3 Fäden: Einer zum Bewegen (A), die beiden anderen zum Markieren (B und D). B Fahne 1/2 Umdrehung, D Fahne 1/3 Umdrehung. Irgendwann wird er den Gegner doppelt markieren :).

Ich gehe davon aus, dass C auf 0 zurückgeht, wenn es 23 überschreitet.

Es sollte ziemlich sicher sein, wenn es einige Runden hat, um sich vorzubereiten (8 Runden), da er immer mindestens 2 Threads (A & B) normal laufen lässt.

Ich kann es im Moment nicht ausprobieren, also mache ich den Test, wenn ich wieder zu Hause bin :)

Lock D          //Thread D locks itself
Copy 6 A        //Thread A will start line 6
Start A     
Copy 13 B       //Thread B will start line 13
Start B        
Copy 20 D       //Moving Thread D to an other part of the program
Lock A          //Thread A locks itself and the line it will be using
Lock #10
Lock #11
Lock #12
Move C          //Move in a pseudo random direction
Turn 1      //always turn to the right
If 1=1 #10 #10  //return to Move C
Lock B          //Thread B locks itself and the line it will be using
Lock #13
Lock #14
Copy #18 *#C    //Copy a flag to the Cth line of the opponent
If 1=1 #16 #16  //jump back to the copy
Flag   
Flag   
Copy C+1 C      //Increment C
Copy #19 *#C+1  //Copy a flag to the Cth+1 line of the opponent
If 1=1 #20 #20  //jump back to the increment
Flag 
Katenkyo
quelle
Die Sperrnummer ist kein gültiger Befehl. Ich setze vor jede Zahl ein # -Zeichen. Außerdem lautet der Befehl "Drehen" und nicht "Drehen"
Nathan Merrill
@ NathanMerrill Wie, das ist ein Tippfehler, vergessen Sie das #, danke, dass Sie darauf hingewiesen haben. Ändern Sie für den Turn Ihren Post so, dass Sie Turn V geschrieben haben. Dreht den Bot V * um 90 Grad im Uhrzeigersinn. :)
Katenkyo
Oh, das habe ich getan. Turn ist eigentlich korrekt, dann gehe ich zurück und aktualisiere den Code
Nathan Merrill
Sie sperren 11,12,13, wenn Sie 10,11,12 sperren wollen?
Sparr
Wow, danke, dass du darauf hingewiesen hast!
Katenkyo
2

Gesperrte stationäre Doppelklick

Inspiriert von @ Katenkyos DoubleTapBot, gibt dieser ein paar Flaggen und jede Hoffnung auf Bewegung auf, als Gegenleistung dafür, dass er seine eigenen Threads vollständig gesperrt hat, damit er niemals neu programmiert werden kann. Es ist jedoch immer noch möglich, feindliche Flags in nicht schleifenförmige Codebereiche schreiben zu lassen.

Lock $flag              // lock the only flag line, super important!
Lock D                  // lock thread D
Copy 10 A
Start A                 // start thread A at $Astart
Copy 17 B
Start B                 // start thread B at $Bstart
Lock $D1                // lock thread D lines
Lock $D2                // thread D should be safe on turn 8
$D1 Turn C              // Spin in place, once every 2 turns
$D2 If 0=0 $D1 $D1      // thread D loop
$Astart Lock A          // thread A starts here, locks itself
Lock $A1                // lock thread A lines
Lock $A2
Lock $A3                // thread A should be safe on turn 7
$A1 Copy $flag *#C      // ATTACK! once every 3 turns
$A2 Copy C+1 C          // increment C, used for attacks and turning
$A3 If 0=0 $A1 $A1      // thread A loop
$Bstart Lock B          // thread B starts here, locks itself
Lock $B1                // lock thread B lines
Lock $B2                // thread B should be safe on turn 8
$B1 Copy $flag *#C+12   // ATTACK! once every 2 turns
$B2 If 0=0 $B1 $B1      // thread B loop
$flag Flag
Sparr
quelle
Haha, die Flagge zu sperren ist eine ziemlich gute Idee, ich hätte darüber nachdenken sollen! Wie auch immer, ich bin froh, dass mein Bot jemanden inspiriert hat!
Katenkyo
@Katenkyo es ist eine gute Idee, wenn es funktioniert, aber ich denke nicht, dass es funktionieren sollte. Die beschriebenen Regeln legen nahe, dass A / B, wenn D die Flag-Zeile sperrt, nicht in der Lage ist, davon zu kopieren. Dies scheint jedoch nicht der Fall zu sein. Fehlerbericht in den Kommentaren zur Frage.
Sparr
1

Zufälliger Urheber

Bewegt sich in eine pseudozufällige Richtung

Copy 5 C
Copy 8 B
Start C
Move A // If you can't catch me, you can't modify me
If 1=1 #3 #3 //Continue to execute the above line
Start B
Copy 4 A
If 1=1 #6 #6 //Continue to execute the above line
Flag
Copy 5 A
If 1=1 #9 #9 //Continue to execute the above line
Nathan Merrill
quelle
1

Dick geschält

Sperrt seine Sachen so gut er kann

Copy 5 B //Designating that the B thread will start on line 5
Start B //Starting the B thread
Lock C //Preventing C from being used
Copy A+1 A //The two threads are offset, meaning that the two threads shouldn't access this at the same time
Lock #A
Copy 2 B
Nathan Merrill
quelle
1

Angreifer Bot

Kopiert Flags an verschiedene Stellen

Copy A+1 A // Increment A
Move A //Move in the Ath direction
Turn A //Rotate A times
Copy #8 *#A //Copy my flag over
Copy 23 D //Loop back to the beginning.  (I use 23 here as threads auto-increment)
Nathan Merrill
quelle
0

Dreifacher Faden

Dieser einfache Bot führt drei Threads mit demselben Code aus. Jeder Faden greift 1/3 Umdrehungen an, bewegt sich 1/6, dreht sich 1/6 und führt 1/3 Buchhaltung durch.

Move 0
Start A
Start B
$loop Copy #A+9 *#C
Move C
Copy #A+9 *#C
Turn C
Copy C+1 C
If 0=0 $loop $loop
Sparr
quelle
0

Bananenbot

Versuche, Bananen in das gegnerische Rad zu werfen, bevor der Feind etwas tun kann. Neigt dazu, zerquetscht zu werden.

$d     If !*D $d1 $d0
$d0    Copy 24 *D
$d1    If !D $d2 $start
$d2    If !*B $d5 $d3
$d3    Copy 24 *B
$d4    Copy $d D

$start Lock D             //Banana's like to split.
       Copy $a A
       Start A
       Copy $b B
       Start B
       Lock $flag

$d5    Copy $start *C     //It's okay if enemy messes up our start.
       Copy $d d

$a     Lock A
$a1    Move C
       Turn 1
       Copy $a1 A

$b     Lock B
$b0    Copy C+1 C
       If !*#C $b0 $b1    //Banana's are good at slipping.
$b1    Copy $flag *#C
$b2    Copy $b0 B

$flag  Flag
Die Nummer eins
quelle
0

Fadenabschneider Bot

   Lock D
   Lock $f
   Copy 16 C
$S If ?*D $1 $2
   Move 1
   Copy $S D
$f Flag
$1 Stop *D
$2 If ?*A $3 $4
$3 Stop *A
$4 If ?*B $5 $6
$5 Stop *B
$6 Copy $f *#C
   Copy C+1 C
   If *#C=#C $E $6
   Copy 2 D
$E Start *D

Stoppen Sie alle feindlichen Threads, bevor Sie Ihren Code eingeben.

MegaTom
quelle
0

Kopieren und selbst kennzeichnen

Dieser Bot führt drei Threads aus. Der D-Faden bewegt sich, bis er auf einen Feind trifft, versucht dann, eine Flagge in ihn zu kopieren, und bewegt sich dann in eine zufällige Richtung. Der A-Thread kopiert sein eigenes Flag über nicht wesentliche Zeilen des Bot-Codes. Der B-Thread ist nur ein Zähler. Die von jedem Thread verwendeten Variablen, Flags und Codezeilen sind in den ersten 15 Runden vollständig gesperrt, und der Bot überschreibt fast den gesamten Startcode mit seinen eigenen Flags. Ich denke nicht, dass es möglich ist, diesen Bot nach Runde 15 in das Banner eines anderen Teams zu konvertieren, ohne dass ein dedizierter Angriffsbot nichts anderes tut, als ihm Flaggen zu schreiben.

    Lock D              // Lock D thread
    Copy $AS A
    Start A             // Start A thread at $AS
    Start B             // B is just a counter
    Copy $DL D          // Jump to D thread startup code
$DC Start B             // Don't let B thread get stopped
$D0 If !*#B $D1 $D2
$D1 Copy $DF *#B
$D2 If !*#B+6 $D3 $DM
$D3 Copy $DF *#B
$DM Move B              // Move some direction after attacking
$DA Move 0              // Move north ...
    If ?*D $DC $DA      // until we hit a live target
$DF Flag                // Flag to copy
$DL Lock #B+3           // Lock the D thread's lines
    If B<12 $DL $DA     // jump to `Move 0` when D thread is safe
$AS Lock A
$AL Lock #B+20
    If B<4 $AL $AD
    Copy 23 B           // reset B so A doesn't overwrite its own code
$AF Flag
    Flag
$AD Copy $AF #B+1       // Copy a safe flag over every unused line of code
    If B<18 $AD $AF
Sparr
quelle
Move 0ist nach Norden zu bewegen, nicht vorwärts.
MegaTom
@ MegaTom aha, danke. Das habe ich vermisst.
Sparr