Code Bots 3: Параллельное программирование Antipatterns

13

Добро пожаловать! Я рад представить 3-й вызов CodeBots. Этот был в разработке долгое время. Эта задача будет разделена на 3 раздела: короткая версия, длинная версия и дополнительные подробности.

Короткая версия

Каждый участник напишет программу из 24 команд. Эти боты будут перемещаться по миру и копировать свой код в других ботов, пытаясь помешать другим ботам делать то же самое. Одной из возможных команд является no-op Flag. Если бот имеет больше, Flagчем любой другой бот Flag, вы получаете очко. Вы выиграли, набрав наибольшее количество очков.

Все вышесказанное относится к двум последним задачам. На этот раз боты смогут запускать несколько строк кода одновременно.

Длинная версия

API

Каждый бот будет иметь ровно 24 строки, где каждая строка имеет следующий формат:

$label command parameters //comments

Метки и комментарии являются необязательными, и каждая команда имеет разное количество параметров. Все без учета регистра.

параметры

Параметры набираются и могут быть в следующих форматах:

  1. Значение от 0 до 23.
  2. Переменная: A, B, C,D
  3. Значение с использованием сложения: A+3или2+C
  4. Строка кода, которая обозначается с помощью #знака ( #4будет представлять 5-ю строку, а #C+2будет представлять строку, рассчитанную с помощью C+2).
  5. Вы можете использовать $labelвместо обозначения строки кода.
  6. Переменная вашего противника или строка кода, обозначенная *. Ваш оппонент - бот в квадрате, с которым вы сталкиваетесь. ( *Bпредставляет Bценность вашего оппонента , в то время как *#9представляет 10-ую линию оппонента). Если в этом квадрате никого нет, команда не выполняется.

команды

Ход V

Перемещает бота North+(V*90 degrees clockwise). Движение не меняет направление.

Поворот V

Поворачивает бота по V*90 degreesчасовой стрелке.

Копировать VW

Копирует все, что Vв W. Если Vэто номер строки, то Wдолжен быть номер строки. Если Vэто переменная или значение, то Wдолжна быть переменная.

Флаг

Ничего не делает.

Star TV

Запускает новый поток, присоединенный к переменной V. Сразу же и при каждом следующем повороте поток выполнит команду в режиме онлайн V.

Если Vон уже подключен к потоку, то эта команда не используется. Если Vпеременная противника, то противник запустит поток, присоединенный к этой переменной.

Стоп V

Останавливает поток, присоединенный к переменной Vв конце этого хода.

Блокировка V

Предотвратить линию или переменный Vот использования в любом случае , кроме как по нити , которая называется Lock. Последующий вызов Lockтого же потока разблокирует V. Блокировки не могут быть вызваны на переменных или строках противника.

Если Конд VW

Это будет проверка Cond. Если условие истинно, оно будет перемещать указатель потока на номер строки V, в противном случае - на номер строки W. Эта строка будет немедленно выполнена.

Conditionals может быть X=Y, X<Y, !Xили ?X:

  1. X=Y проверяет, являются ли две строки одного типа и от одного и того же бота, или вы проверяете, равны ли два значения одному и тому же количеству.
  2. X<Yпроверяет, Xменьше ли значение Y.
  3. !Xпроверяет, Xзаблокирована ли переменная или строка (возвращает true, если заблокирована)
  4. ?X проверяет, имеет ли данная переменная присоединенный поток

дополнительные детали

Многопоточные взаимодействия

Действия одного типа выполняются одновременно. Действия выполняются в следующем порядке:

  1. Замок. Если несколько потоков попытаются заблокировать переменную, все они потерпят неудачу. Если поток разблокирует переменную, а другой пытается ее заблокировать, переменная останется разблокированной.

  2. Начало. Если несколько потоков пытаются запустить поток в переменной, он считается за один запуск.

  3. Копировать. Если два потока копируют в одну и ту же переменную, переменная в итоге получит случайное значение. Если они оба копируют в одну строку, ни один из них не будет работать. Если поток копирует в ту же переменную, из которой копирует другой поток, то последний поток скопирует случайное значение. Если два потока копируют из одной и той же переменной, они оба будут работать нормально.

  4. Если. Все условные выражения будут проверены одновременно, а затем переменные потока будут обновлены после. Выполнение Ifможет привести к добавлению действия с более высоким приоритетом. Действия с более высоким приоритетом будут выполнены перед тем, как перейти за If, в то время как действия с более низким приоритетом будут выполнены после If.

  5. Переехать. Несколько ходов на одном и том же боте приведут к сумме всех ходов бота. Если несколько ботов окажутся в одном месте, они будут возвращены в исходное место.

  6. Перемена. Несколько ходов на одном боте будут суммироваться.

  7. Стоп. Несколько команд останова для одной и той же переменной будут учитываться как один останов.

Другие детали

Ваш начальный поток начинает присоединяться к Dпеременной

Повторение с If( указав на себя Ifутверждение) заставит вашего бота ничего не делать

Если поток заблокирован после блокировки, эти блокировки будут разблокированы

Действия по использованию заблокированной переменной или строки ничего не сделают.

Если бот меньше 24 строк, оставшиеся строки будут заполнены Flag

Выполнение записи в переменную, которая также присоединена к начальному потоку, фактически заставит поток начать свое выполнение с новым значением, поскольку поток начинает следующий ход.

Боты размещаются в тороидальном мире по следующей схеме:

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

Я добавил несколько примеров ботов , которые комментируются как справочник по языку.

Контроллер находится здесь . Я долго работал над этим, но, вероятно, все еще есть ошибки. Когда спецификация и контроллер противоречат, спецификация верна.

Табло

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
Натан Меррилл
источник
Вау, по крайней мере, DoubleTap кажется намного лучше, чем образцы!
Катенкё
Что должно произойти, если я попытаюсь прочитать заблокированную переменную из другого потока? Скажем, я делаю LOCK A, тогда в другом потоке есть MOVE A. Оценивает ли A значение 0 или случайное значение, или перемещение не удается или ...?
Спарр
То же самое происходит, когда поток достигает линии, заблокированной другим потоком. Это шумиха? Это пропускается?
Спарр
Должен ли "Копировать $ label A" работать? Он интерпретируется как «Копия № 11 А», которая недопустима, и вызывает сбой интерпретатора, а не «Копировать 11 А», как я надеюсь.
Спарр
возможная ошибка ... Кажется, я могу читать свои собственные строки флагов, чтобы копировать их, даже когда они заблокированы другим потоком.
Спарр

Ответы:

3

Заблокированный сканер бот

Сканирует противника как можно быстрее и заменяет линии флагами.

    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
Номер один
источник
Мне любопытно об условном в вашей теме. ! * # C проверяет, заблокирована ли строка вашей цели #C (ваша C), верно? Как это полезно?
Спарр
@Sparr Поток A не тратит время, заменяя строку кода врага флагом, если он заблокирован.
TheNumberOne
Благодарю. Первоначально я неправильно понял спецификацию, касающуюся скорости операторов If.
Спарр
3

DoubleTapBot

Этот бот имеет 3 потока: один для перемещения (A), два других для пометки (B и D). Флаг B на 1/2 оборота, флаг D на 1/3 оборота. Так что на каком-то ходу он удвоит флаг противника :).

Я предполагаю, что C вернется к 0, если он превысит 23.

Будет довольно безопасно, если у него будет какой-то ход, чтобы подготовиться (8 ходов), так как он всегда будет поддерживать как минимум 2 потока (A & B) в нормальном режиме.

Я не могу попробовать это в данный момент, поэтому я сделаю тест, когда вернусь домой :)

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
источник
Номер блокировки не является допустимой командой. Я ставлю знаки # перед каждым из чисел. Кроме того, команда «Поворот», а не «Поворот»
Натан Меррилл
@NathanMerrill Как, это опечатка, забудьте #, спасибо за указание на это. А для поворота измените свой пост так, что вы написали Turn V Поворот бота V * на 90 градусов по часовой стрелке. :)
Катенкё
О, я сделал. Поворот на самом деле правильный, тогда я вернусь и обновлю код
Натан Меррилл
Вы блокируете 11,12,13, когда хотите заблокировать 10,11,12?
Спарр
Вау, спасибо за указание на это!
Катенькио,
2

Заблокированный стационарный двойной кран

Вдохновленный DoubleTapBot @ Katenkyo, он оставляет пару флагов и любую надежду на движение в обмен на полную блокировку своих собственных потоков, так что его невозможно перепрограммировать. Тем не менее, все еще возможно, чтобы вражеские флаги были записаны в области зацикливания кода.

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
источник
Ха-ха, Блокировка флага - довольно хорошая идея, я должен был подумать об этом! В любом случае, я рад, что мой бот кого-то вдохновил!
Катенкё
@ Katenkyo это хорошая идея, если это работает, но я не думаю, что это должно работать. Как написано в правилах, если D блокирует строку флага, то A / B не сможет скопировать ее. Тем не менее, это не так. Сообщение об ошибке в комментариях к вопросу.
Спарр
1

Случайный Двигатель

Перемещается в псевдослучайном направлении

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

Толстый

Запирает его вещи столько, сколько он может

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

Атакующий бот

Копирует флаги в разные места

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

Тройная нить

Этот простой бот запускает три потока с одинаковым кодом. Каждая нить атакует 1/3 хода, перемещается на 1/6, поворачивается на 1/6 и ведет бухгалтерский учет на 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
источник
0

Банановый бот

Попытки бросить бананы в колесо врага, прежде чем противник сможет что-либо сделать. Склонен к давлению.

$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

Резак бот

   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

Остановите все потоки противника, прежде чем наполнять его кодом.

MegaTom
источник
0

Копировать и Self Flag

Этот бот запускает три потока. Нить D движется, пока не натолкнется на врага, затем попытается скопировать в него флаг, а затем в произвольном направлении. Поток A копирует свой собственный флаг над несущественными строками кода бота. B поток - это просто счетчик. Переменная, флаг и строки кода, используемые каждым потоком, полностью блокируются в первые 15 ходов, и бот перезаписывает почти весь свой код запуска своими собственными флагами. Я не думаю, что можно превратить этого бота в баннер другой команды после 15-го хода без специального атакующего бота, который просто делает для него флаги.

    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
источник
Move 0это двигаться на север, а не вперед.
MegaTom
@ MegaTom ага, спасибо. Я пропустил это.
Спарр