Code Bots 3: Parallel Programming Antipatterns


13

Ben tornato! Sono entusiasta di presentare la terza sfida di CodeBot. Questo è da molto tempo in preparazione. Questa sfida sarà suddivisa in 3 sezioni: la versione corta, la versione lunga e ulteriori dettagli.

La versione breve

Ogni concorrente scriverà un programma a 24 comandi. Questi robot si sposteranno in tutto il mondo e copieranno il loro codice in altri robot, mentre cercano di impedire ad altri robot di fare lo stesso. Uno dei possibili comandi è il no-op Flag. Se un bot ha più del tuo Flagdi qualsiasi altro bot Flag, ottieni un punto. Vinci vincendo il maggior numero di punti.

Tutto quanto sopra era vero per le due precedenti sfide. Questa volta, i robot saranno in grado di eseguire più righe di codice contemporaneamente.

La versione lunga

L'API

Ogni bot avrà esattamente 24 righe, dove ogni riga è nel seguente formato:

$label command parameters //comments

Etichette e commenti sono opzionali e ogni comando ha un numero diverso di parametri. Tutto non distingue tra maiuscole e minuscole.

parametri

I parametri vengono digitati e possono essere nei seguenti formati:

  1. Un valore compreso tra 0 e 23.
  2. Una variabile: A, B, C,D
  3. Un valore usando l'addizione: A+3o2+C
  4. Una riga di codice, che viene designata utilizzando il #segno ( #4rappresenterebbe la quinta riga, mentre #C+2rappresenterebbe la riga calcolata da C+2).
  5. È possibile utilizzare un $labelinvece di designare una riga di codice.
  6. La variabile o la riga di codice del tuo avversario, designata da *. Il tuo avversario è il robot nel quadrato che stai affrontando. ( *Brappresenta il Bvalore del tuo avversario , mentre *#9rappresenta la decima linea del tuo avversario). Se non c'è nessuno in quel quadrato, il comando non viene eseguito.

comandi

Sposta V

Sposta il bot North+(V*90 degrees clockwise). Il movimento non cambia direzione.

Girare V

Ruota il robot in V*90 degreessenso orario.

Copia VW

Copia tutto ciò che è Vdentro W. Se Vè un numero di riga, Wdeve essere un numero di riga. Se Vè una variabile o un valore, allora Wdeve essere una variabile.

Bandiera

Non fa nulla.

Stella della tv

Avvia un nuovo thread associato alla variabile V. Immediatamente e in ogni turno futuro, il thread eseguirà il comando on line V.

Se Vè già collegato a un thread, questo comando è no-op. Se Vè una variabile di un avversario, allora l'avversario inizierà un thread attaccato a quella variabile.

Stop V

Ferma il thread attaccato alla variabile Valla fine di questo turno.

Lock V

Impedisci che la linea o la variabile Vvengano utilizzate in alcun modo tranne che dal thread che ha chiamato Lock. Viene Locksbloccata una chiamata successiva a dallo stesso thread V. I blocchi non possono essere chiamati su variabili o linee dell'avversario.

Se Cond VW

Questo metterà alla prova Cond. Se la condizione è vera, sposta il puntatore del thread sul numero di riga V, altrimenti sul numero di riga W. Quella riga verrà quindi immediatamente eseguita.

Condizionali possono essere X=Y, X<Y, !X, o ?X:

  1. X=Y verifica se due righe sono dello stesso tipo e dello stesso bot oppure verifica se due valori equivalgono allo stesso importo.
  2. X<Yverifica se il valore di Xè inferiore a Y.
  3. !Xverifica se la variabile o la riga Xè bloccata (restituisce true se bloccata)
  4. ?X verifica se a una determinata variabile è associato un thread

dettagli aggiuntivi

Interazioni multi-thread

Le azioni dello stesso tipo vengono eseguite contemporaneamente. Le azioni vengono eseguite nel seguente ordine:

  1. Serratura. Se diversi thread tentano di bloccare una variabile, falliranno tutti. Se un thread sblocca una variabile mentre un altro sta tentando di bloccarla, la variabile rimarrà sbloccata.

  2. Inizio. Se più thread tentano di avviare un thread su una variabile, verrà conteggiato come un singolo avvio.

  3. Copia. Se due thread vengono entrambi copiati nella stessa variabile, la variabile finirà come valore casuale. Se entrambi copiano sulla stessa riga, nessuno dei due funzionerà. Se un thread copia nella stessa variabile da cui un altro thread sta copiando, quest'ultimo thread copia un valore casuale. Se due thread copiano entrambi dalla stessa variabile, funzioneranno entrambi correttamente.

  4. Se. Tutti i condizionali verranno testati simultaneamente e successivamente le variabili del thread verranno aggiornate. L'esecuzione di un Ifpuò causare un'azione con una priorità più alta da aggiungere. Le azioni con priorità più alta verranno eseguite prima di passare oltre il If, mentre le azioni con una priorità inferiore verranno eseguite dopo il If.

  5. Mossa. Mosse multiple sullo stesso bot sposteranno il bot della somma di tutte le mosse. Se più robot finissero nello stesso punto, verranno riportati al punto di partenza.

  6. Girare. Si sommano più turni sullo stesso bot.

  7. Fermare. I comandi di arresto multipli sulla stessa variabile verranno conteggiati come arresto singolo.

Altri dettagli

Il thread iniziale inizia in allegato alla Dvariabile

Ricorrere con un If(avendo Ifun'affermazione puntata su se stesso) non farà nulla al tuo bot

Se un thread viene interrotto dopo il blocco, tali blocchi verranno sbloccati

Le azioni per usare una variabile o una linea bloccate non faranno nulla.

Se un bot è più corto di 24 righe, le righe rimanenti verranno riempite Flag

Eseguendo una scrittura su una variabile che è anche collegata a un thread iniziale, il thread inizierà effettivamente la sua esecuzione sul nuovo valore mentre il thread inizia il turno successivo.

I robot sono collocati in un mondo toroidale nel seguente schema:

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

Ho aggiunto diversi bot di esempio che vengono commentati come riferimento di lingua.

Il controller si trova qui . Ci ho lavorato a lungo, ma probabilmente ha ancora dei bug. Quando le specifiche e il controller sono in contraddizione, le specifiche sono corrette.

tabellone segnapunti

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

Wow, almeno, DoubleTap sembra molto meglio dei campioni!
Katenkyo,

Cosa dovrebbe accadere se provo a leggere una variabile bloccata da un altro thread? Di 'che faccio BLOCCO A, poi in un altro thread c'è un MOVE A. A valuta come 0 o un valore casuale o lo spostamento fallisce o ...?
Sparr,

Idem su cosa succede quando un thread raggiunge una linea bloccata da un altro thread. È un noop? Viene saltato?
Sparr,

"Copia $ etichetta A" dovrebbe funzionare? Interpreta come "Copia # 11 A" che non è valido e blocca l'interprete, invece di "Copia 11 A" come spererei.
Sparr,

possibile bug ... Mi sembra di poter leggere le mie linee di bandiera per copiarle, anche quando sono bloccate da un altro thread.
Sparr,

Risposte:


3

Bot scanner bloccato

Scansiona il nemico il più velocemente possibile e sostituisce le linee con le bandiere.

    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

Sono curioso del condizionale nel tuo thread A. ! * # C controlla se la linea del bersaglio #C (la tua C) è bloccata, giusto? Come è utile?
Sparr,

@Sparr Il thread A non perde tempo a sostituire una riga del codice nemico con una bandiera se è bloccata.
TheNumberOne

Grazie. Ho letto male le specifiche originariamente riguardanti la velocità delle istruzioni If.
Sparr

3

DoubleTapBot

Questo bot ha 3 thread: uno per lo spostamento (A), gli altri due per la segnalazione (B e D). B flag 1/2 giro, D flag 1/3 giro. Quindi in qualche turno, farà doppio flag l'avversario :).

Presumo che C tornerà a 0 se supera 23.

Dovrebbe essere abbastanza sicuro se ha qualche turno per prepararsi (8 turni), poiché manterrà sempre almeno 2 fili (A e B) in esecuzione normalmente.

Al momento non posso provarlo, quindi farò il test quando torno 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 

Il numero di blocco non è un comando valido. Metto # segni prima di ciascuno dei numeri. Inoltre, il comando è "Ruota", non "Ruota"
Nathan Merrill il

@NathanMerrill Come, è un refuso, dimentica il #, grazie per averlo sottolineato. E per girare, modifica il tuo post in modo che tu abbia scritto Gira V Ruota il bot V * di 90 gradi in senso orario. :)
Katenkyo,

Oh, l'ho fatto. Il turno è in realtà corretto, quindi, torno indietro e aggiorno il codice
Nathan Merrill

Stai bloccando 11,12,13 quando intendi bloccare 10,11,12?
Sparr,

Wow, grazie per averlo sottolineato!
Katenkyo,

2

Doppio tocco fisso bloccato

Ispirato al DoubleTapBot di @ Katenkyo, questo abbandona un paio di bandiere e ogni speranza di movimento in cambio del blocco completo dei propri thread in modo che non possa mai essere riprogrammato. Tuttavia, è ancora possibile avere bandiere nemiche scritte in aree di codice senza loop.

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

Haha, Bloccare la bandiera è un'idea abbastanza buona, avrei dovuto pensarci! Ad ogni modo, sono contento che il mio bot abbia ispirato qualcuno!
Katenkyo,

@Katenkyo è una buona idea se funziona, ma non penso che dovrebbe funzionare. Le regole scritte suggeriscono che se D blocca la linea di bandiera, A / B non sarà in grado di copiarla. Tuttavia, ciò non sembra essere il caso. Segnalazione di bug nei commenti alla domanda.
Sparr,

1

Mover casuale

Si sposta in una direzione 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

1

Spessore sgusciato

Blocca le sue cose il più possibile

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

1

Bot dell'attaccante

Copia le bandiere in varie posizioni

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)

0

Triple Thread

Questo semplice bot esegue tre thread tutti con lo stesso codice. Ogni thread attacca 1/3 di turni, si sposta di 1/6, si trasforma di 1/6 e fa la contabilità di 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

0

Banana Bot

Tenta di lanciare banane nella ruota dei nemici prima che il nemico possa fare qualsiasi cosa. Incline ad essere schiacciato.

$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

0

Bot tagliafilo

   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

Ferma tutti i thread nemici prima di riempire con il tuo codice.


0

Copia e bandiera autonoma

Questo bot esegue tre thread. Il thread D si sposta fino a quando non si imbatte in un nemico, quindi cerca di copiare una bandiera al suo interno, quindi si sposta in una direzione casuale. Il thread A copia il proprio flag su righe non essenziali del codice del bot. Il thread B è solo un contatore. La variabile, il flag e le righe di codice utilizzate da ciascun thread sono completamente bloccate nei primi 15 turni e il bot sovrascrive quasi tutto il suo codice di avvio con i propri flag. Non penso che sia possibile convertire questo bot in uno striscione di un'altra squadra dopo il turno 15 senza un bot di attacco dedicato che non fa altro che scrivere bandiere su di esso.

    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

Move 0 si sposta verso nord, non in avanti.
MegaTom,

@MegaTom aha, grazie. Ho perso questo.
Sparr,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.