Code Bots 3: Antipatterns de programación paralela

13

¡Dar una buena acogida! Estoy emocionado de presentar el 3er desafío de CodeBots. Este ha pasado mucho tiempo en la fabricación. Este desafío se dividirá en 3 secciones: la versión corta, la versión larga y detalles adicionales.

La versión corta

Cada competidor escribirá un programa de 24 comandos. Estos bots se moverán alrededor del mundo y copiarán su código en otros bots, mientras tratan de evitar que otros bots hagan lo mismo. Uno de los comandos posibles es el no-op Flag. Si un bot tiene más de tu Flagque cualquier otro bot Flag, obtienes un punto. Ganas al tener la mayor cantidad de puntos.

Todo lo anterior fue cierto para los últimos dos desafíos. Esta vez, los bots podrán ejecutar múltiples líneas de código al mismo tiempo.

La versión larga

La API

Cada bot tendrá exactamente 24 líneas, donde cada línea tiene el siguiente formato:

$label command parameters //comments

Las etiquetas y los comentarios son opcionales, y cada comando tiene un número diferente de parámetros. Todo distingue entre mayúsculas y minúsculas.

Parámetros

Los parámetros están escritos y pueden estar en los siguientes formatos:

  1. Un valor de 0 a 23.
  2. Una variable: A, B, C,D
  3. Un valor usando la suma: A+3o2+C
  4. Una línea de código, que se designa con el #signo ( #4representaría la quinta línea, mientras #C+2que representaría la línea calculada por C+2).
  5. Puede usar una en $labellugar de designar una línea de código.
  6. La variable o línea de código de su oponente, designada por *. Tu oponente es el bot en la casilla que estás enfrentando. ( *Brepresenta el Bvalor de tu oponente , mientras que *#9representa la décima línea de tu oponente). Si no hay nadie en ese cuadrado, el comando no se ejecuta.

Comandos

Mover V

Mueve el bot North+(V*90 degrees clockwise). El movimiento no cambia de dirección.

Vuelta V

Gira el bot en V*90 degreessentido horario.

Copia VW

Copia lo que sea que esté Vadentro W. Si Ves un número de línea, Wdebe ser un número de línea. Si Ves una variable o un valor, Wdebe ser una variable.

Bandera

No hace nada.

Estrella de la TV

Inicia un nuevo hilo adjunto a la variable V. Inmediatamente, y en cada turno futuro, el hilo ejecutará el comando en línea V.

Si Vya está conectado a un hilo, entonces este comando es no operativo. Si Ves la variable de un oponente, entonces el oponente comenzará un hilo adjunto a esa variable.

Parada V

Detiene el hilo adjunto a la variable Val final de este turno.

Bloqueo V

Evite que la línea o variable Vse use de cualquier manera, excepto por el hilo que llamó Lock. Una llamada posterior a Lockpor el mismo hilo se desbloquea V. No se pueden invocar bloqueos en las variables o líneas del oponente.

If Cond VW

Esto lo probará Cond. Si la condición es verdadera, moverá el puntero del hilo al número de línea V, de lo contrario al número de línea W. Esa línea se ejecutará inmediatamente.

Condicionales pueden ser X=Y, X<Y, !Xo ?X:

  1. X=Y prueba si dos líneas son del mismo tipo y del mismo bot, o prueba si dos valores equivalen a la misma cantidad.
  2. X<Yprueba si el valor de Xes menor que Y.
  3. !Xprueba si la variable o la línea Xestá bloqueada (devuelve verdadero si está bloqueado)
  4. ?X prueba si una variable dada tiene un hilo adjunto

Detalles adicionales

Interacciones multihilo

Las acciones del mismo tipo se ejecutan al mismo tiempo. Las acciones se ejecutan en el siguiente orden:

  1. Bloquear. Si varios hilos intentan bloquear una variable, todos fallarán. Si un subproceso está desbloqueando una variable mientras otro intenta bloquearlo, la variable permanecerá desbloqueada.

  2. Comienzo. Si varios hilos intentan iniciar un hilo en una variable, contará como un solo inicio.

  3. Copiar. Si dos hilos se copian en la misma variable, la variable terminará como un valor aleatorio. Si ambos copian en la misma línea, ninguno funcionará. Si un hilo se copia a la misma variable desde la que se está copiando otro hilo, el último hilo copiará un valor aleatorio. Si dos hilos se copian de la misma variable, ambos funcionarán bien.

  4. Si. Todos los condicionales se probarán simultáneamente, y luego las variables del hilo se actualizarán después. La ejecución de un Ifpuede provocar que se agregue una acción con mayor prioridad. Las acciones con mayor prioridad se ejecutarán antes de pasar al pasado If, mientras que las acciones con menor prioridad se ejecutarán después del If.

  5. Moverse. Múltiples movimientos en el mismo bot moverán al bot la suma de todos los movimientos. Si varios bots terminarían en el mismo lugar, volverán a su punto de partida.

  6. Giro. Sumas múltiples en el mismo bot sumarán.

  7. Detener. Múltiples comandos de parada en la misma variable contarán como una sola parada.

Otros detalles

Su hilo inicial comienza adjunto a la Dvariable

Recurrir con un If(que tiene una Ifdeclaración apuntando a sí mismo) hará que su bot no haga nada

Si se detiene un hilo después del bloqueo, esos bloqueos se desbloquearán

Las acciones para usar una variable o línea bloqueada no harán nada.

Si un bot tiene menos de 24 líneas, las líneas restantes se llenarán con Flag

Al realizar una escritura en una variable que también se adjunta a un subproceso inicial, el subproceso comenzará su ejecución en el nuevo valor a medida que el subproceso comience el siguiente turno.

Los bots se colocan en un mundo toroidal con el siguiente patrón:

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

He agregado varios bots de muestra que se comentan como referencia de idioma.

El controlador se encuentra aquí . He trabajado mucho tiempo en ello, pero probablemente todavía tiene errores. Cuando la especificación y el controlador se contradicen, la especificación es correcta.

Marcador

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
fuente
¡Guau, al menos, DoubleTap parece mucho mejor que las muestras!
Katenkyo
¿Qué debería suceder si intento leer una variable bloqueada de otro hilo? Digamos que BLOQUEO A y luego en otro hilo hay un MOVIMIENTO A. ¿A evalúa a 0 o un valor aleatorio o el movimiento falla o ...?
Sparr
Lo mismo ocurre con lo que sucede cuando un hilo llega a una línea bloqueada por otro hilo. ¿Es un noop? ¿Se salta?
Sparr
¿Debería funcionar "Copiar $ etiqueta A"? Se interpreta como "Copiar # 11 A", que no es válido y bloquea el intérprete, en lugar de "Copiar 11 A" como esperaba.
Sparr
posible error ... Parece que puedo leer mis propias líneas de bandera para copiarlas, incluso cuando están bloqueadas por otro hilo.
Sparr

Respuestas:

3

Escáner bloqueado Bot

Escanea al enemigo lo más rápido posible y reemplaza las líneas con banderas.

    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
El numero uno
fuente
Tengo curiosidad sobre el condicional en su hilo A. ! * # C comprueba si la línea #C de su objetivo (su C) está bloqueada, ¿verdad? ¿Cómo es eso útil?
Sparr
@Sparr El hilo A no pierde tiempo reemplazando una línea del código de los enemigos con una bandera si está bloqueada.
TheNumberOne
Gracias. Leí mal la especificación originalmente con respecto a la velocidad de las declaraciones If.
Sparr
3

DoubleTapBot

Este bot tiene 3 hilos: uno para mover (A), los otros dos para marcar (B y D). B bandera 1/2 vuelta, D bandera 1/3 vuelta. Entonces, un turno, él hará doble bandera al oponente :).

Supongo que C volverá a 0 si excede 23.

Debería ser bastante seguro si tiene algún turno para prepararse (8 turnos), ya que siempre mantendrá al menos 2 hilos (A y B) funcionando normalmente.

No puedo probarlo en este momento, así que haré la prueba cuando regrese a casa :)

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
fuente
El número de bloqueo no es un comando válido. Pongo # signos antes de cada uno de los números. Además, el comando es "Girar", no "Girar"
Nathan Merrill
@NathanMerrill Cómo, eso es un error tipográfico, olvida el #, gracias por señalarlo. Y para su turno, modifique su publicación, así que escribió Turno V Gira el bot V * 90 grados en el sentido de las agujas del reloj. :)
Katenkyo
Oh, lo hice El giro es correcto, entonces, volveré y actualizaré el código
Nathan Merrill
¿Estás bloqueando 11,12,13 cuando quieres bloquear 10,11,12?
Sparr
¡Guau, gracias por señalar eso!
Katenkyo
2

Doble golpe estacionario bloqueado

Inspirado en DoubleTapBot de @Katenkyo, este deja un par de banderas y cualquier esperanza de movimiento a cambio de bloquear completamente sus propios hilos para que nunca se pueda reprogramar. Sin embargo, todavía es susceptible de tener banderas enemigas escritas en áreas de código sin bucle.

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
fuente
Jaja, bloquear la bandera es una idea bastante buena, ¡debería haberlo pensado! De todos modos, ¡me alegra que mi bot haya inspirado a alguien!
Katenkyo
@Katenkyo es una buena idea si funciona, pero no creo que debería funcionar. Las reglas tal como están escritas sugieren que si D bloquea la línea de bandera, entonces A / B no podrá copiarla. Sin embargo, ese no parece ser el caso. Informe de error en los comentarios a la pregunta.
Sparr
1

Mover al azar

Se mueve en dirección psuedorandom

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
fuente
1

De cáscara gruesa

Bloquea sus cosas tanto como puede

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
fuente
1

Atacante bot

Copia banderas en varios lugares

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
fuente
0

Hilo triple

Este simple bot ejecuta tres hilos, todos con el mismo código. Cada hilo ataca 1/3 de turno, se mueve 1/6, gira 1/6 y hace la contabilidad 1/3.

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
fuente
0

Banana Bot

Intenta tirar plátanos en la rueda del enemigo antes de que el enemigo pueda hacer algo. Propenso a ser aplastado.

$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
El numero uno
fuente
0

Cortador de hilo 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

Detenga todos los hilos enemigos antes de llenar con su código.

MegaTom
fuente
0

Copiar y auto-marcar

Este bot ejecuta tres hilos. El hilo D se mueve hasta que se topa con un enemigo, luego intenta copiar una bandera en ellos, luego se mueve en una dirección aleatoria. El hilo A copia su propia bandera sobre líneas no esenciales del código del bot. El hilo B es solo un contador. La variable, la bandera y las líneas de código utilizadas por cada subproceso están completamente bloqueadas en los primeros 15 turnos, y el bot sobrescribe casi todo su código de inicio con sus propias banderas. No creo que sea posible convertir este bot en el banner de otro equipo después del turno 15 sin que un bot de ataque dedicado no haga nada más que escribir banderas en él.

    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
fuente
Move 0es moverse hacia el norte, no hacia adelante.
MegaTom
@MegaTom aha, gracias. Me lo perdí.
Sparr