Code Bots 3: Parallel Programming Antipatterns

13

Welcome back! I'm excited to present the 3rd CodeBots challenge. This one has been a long time in the making. This challenge will be split up in 3 sections: the short version, the long version, and additional details.

The Short Version

Each competitor will write a 24-command program. These bots will move around the world and copy their code into other bots, while trying to prevent other bots to do the same. One of the possible commands is the no-op Flag. If a bot has more of your Flag than any other bot's Flag, you get a point. You win by having the most points.

All of the above was true for the past two challenges. This time around, bots will be able to run multiple lines of code at the same time.

The Long Version

The API

Every bot will have exactly 24 lines, where each line is in the following format:

$label command parameters //comments

Labels and comments are optional, and each command has a different number of parameters. Everything is case-insensitive.

Parameters

Parameters are typed, and can be in the following formats:

  1. A value from 0 to 23.
  2. A variable: A, B, C, D
  3. A value using addition: A+3 or 2+C
  4. A line of code, which is designated using the # sign (#4 would represent the 5th line, while #C+2 would represent the line calculated by C+2).
  5. You can use a $label instead of designating a line of code.
  6. Your opponent's variable or line of code, designated by *. Your opponent is the bot in the square that you are facing. (*B represents your opponent's B value, while *#9 represents your opponent's 10th line). If there is nobody in that square, the command is not executed.

Commands

Move V

Moves the bot North+(V*90 degrees clockwise). Movement does not change direction.

Turn V

Turns the bot V*90 degrees clockwise.

Copy V W

Copies whatever is in V into W. If V is a line number, then W has to be a line number. If V is a variable or value, then W must be a variable.

Flag

Does nothing.

Start V

Starts a new thread attached to the variable V. Immediately, and on each future turn, the thread will execute the command on line V.

If V is already attached to a thread, then this command is a no-op. If V is an opponent's variable, then the opponent will start a thread attached to that variable.

Stop V

Stops the thread attached to the variable V at the end of this turn.

Lock V

Prevent the line or variable V from being used in any way except by the thread that called Lock. A subsequent call to Lock by the same thread unlocks V. Locks cannot be called on opponent's variables or lines.

If Cond V W

This will test Cond. If the condition is true, then it will move the thread pointer to the line number V, otherwise to the line number W. That line will then be immediately executed.

Conditionals can be X=Y, X<Y, !X, or ?X:

  1. X=Y tests whether two lines are of the same type and from the same bot, or you test whether two values equal the same amount.
  2. X<Y tests whether the value of X is less than Y.
  3. !X tests whether the variable or line X is locked (returns true if locked)
  4. ?X tests whether a given variable has a thread attached to it

Additional Details

Multi-threaded interactions

Actions of the same type are executed at the same time. Actions are executed in the following order:

  1. Lock. If several threads attempt to lock a variable, they will all fail. If a thread is unlocking a variable while another is attempting to lock it, the variable will remain unlocked.

  2. Start. If several threads attempt to start a thread on a variable, it will count as a single start.

  3. Copy. If two threads both copy to the same variable, the variable will end up as a random value. If they both copy to the same line, neither will work. If a thread copies to the same variable another thread is copying from, then the latter thread will copy a random value. If two threads are both copying from the same variable, they will both work fine.

  4. If. All conditionals will be tested simultaneously, and then the thread variables will be updated after. Executing an If can cause an action with a higher priority to be added. Actions with higher priority will be executed before moving on past the If, while actions with a lower priority will execute after the If.

  5. Move. Multiple moves on the same bot will move the bot the sum of all of the moves. If multiple bots would end up in the same spot, they will be returned to their starting spot.

  6. Turn. Multiple turns on the same bot will sum.

  7. Stop. Multiple stop commands on the same variable will count as a single stop.

Other details

Your initial thread starts attached to the D variable

Recursing with an If (having an If statement pointed to itself) will cause your bot to do nothing

If a thread is stopped after locking, those locks will be unlocked

Actions to use a locked variable or line will do nothing.

If a bot is shorter than 24 lines, remaining lines will be filled with Flag

Performing a write on a variable that is also attached to a starting thread will actually have the thread start its execution on the new value as the thread starts the following turn.

Bots are placed in a toroidal world in the following pattern:

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

I have added several sample bots that are commented as a language reference.

The controller is located here. I've worked a long time on it, but it probably still has bugs. When the spec and the controller contradict, the spec is correct.

Scoreboard

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

Posted 2015-06-12T02:45:09.947

Reputation: 13 591

Wow, at least, DoubleTap seems much better than samples ! – Katenkyo – 2015-06-12T14:37:39.153

What should happen if I try to read a locked variable from another thread? Say I do LOCK A then in another thread there's a MOVE A. Does A evaluate to 0 or a random value or does the move fail or...? – Sparr – 2015-06-12T16:08:08.073

Ditto on what happens when a thread reaches a line locked by another thread. Is it a noop? Does it get skipped? – Sparr – 2015-06-12T16:23:26.557

Should "Copy $label A" work? It interprets as "Copy #11 A" which isn't valid and crashes the interpreter, instead of "Copy 11 A" as I'd hope for. – Sparr – 2015-06-12T17:26:22.253

possible bug... I seem to be able to read my own flag lines to copy from them, even when they are locked by another thread. – Sparr – 2015-06-12T17:49:38.937

Both reading the variable (as in Move A), and executing the line is a no-op. – Nathan Merrill – 2015-06-13T13:49:34.477

@sparr concerning your $label, I'll have to see what I can do, but right now, I'm doing a super dumb find/replace. – Nathan Merrill – 2015-06-13T13:50:48.170

What happens if you use * and no bot is in front of you? for example If ?*A, Copy 1 *A – MegaTom – 2015-06-15T18:36:24.040

@MegaTom it is a no-op. – Nathan Merrill – 2015-06-15T18:37:03.133

Answers

3

Locked Scanner Bot

Scans the enemy as fast as possible and replaces the lines with flags.

    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

TheNumberOne

Posted 2015-06-12T02:45:09.947

Reputation: 10 855

I'm curious about the conditional in your A thread. !*#C checks if your target's line #C (your C) is locked, right? How is that helpful? – Sparr – 2015-06-14T02:49:15.227

@Sparr The A thread doesn't waste time replacing a line of the enemies code with a flag if it's locked. – TheNumberOne – 2015-06-14T14:52:59.530

Thanks. I misread the spec originally regarding the speed of If statements. – Sparr – 2015-06-14T18:18:07.183

3

DoubleTapBot

This bot has 3 threads : One for moving (A), The two others for flagging (B and D). B flag 1/2 turn, D flag 1/3 turn. So some turn, he will double flag the opponent :).

I assume that C will return to 0 if it exceed 23.

It shoudl be pretty safe if it have some turn to prepare itself (8 turn), as he will always keep at least 2 threads (A & B) running normally.

I can't try it at the moment, so I'll do the test when I'll be back Home :)

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

Posted 2015-06-12T02:45:09.947

Reputation: 2 857

Lock number is not a valid command. I put # signs before each of the numbers. Also, the command is "Rotate", not "Turn" – Nathan Merrill – 2015-06-12T13:48:04.163

@NathanMerrill How, that's a typo, forget the #, thanks for pointing it out. And for turn, modify your post so, you wrote Turn V

Turns the bot V*90 degrees clockwise. :) – Katenkyo – 2015-06-12T14:10:02.190

Oh, I did. Turn is actually correct, then, I'll go back and update the code – Nathan Merrill – 2015-06-12T15:23:58.343

You're locking 11,12,13 when you mean to be locking 10,11,12? – Sparr – 2015-06-12T16:06:32.733

Wow, thanks for pointing that out ! – Katenkyo – 2015-06-12T16:33:44.853

2

Locked Stationary Double Tap

Inspired by @Katenkyo's DoubleTapBot, this one gives up a couple of flags and any hope of movement in return for completely locking down its own threads so it can't ever be reprogrammed. It is, however, still succeptible to having enemy flags written to non-looping code areas.

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

Posted 2015-06-12T02:45:09.947

Reputation: 5 758

Haha, Locking the flag is a pretty good Idea, I should have thought of it ! Anyway, I'm glad that my bot gave some inspiration to someone ! – Katenkyo – 2015-06-12T18:34:17.650

@Katenkyo it's a good idea if it works, but I don't think it should work. The rules-as-written suggest that if D locks the flag line then A/B won't be able to copy from it. However, that doesn't seem to be the case. Bug report in the comments to the question. – Sparr – 2015-06-14T00:22:46.990

1

Attacker Bot

Copies flags into various locations

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

Posted 2015-06-12T02:45:09.947

Reputation: 13 591

1

Random Mover

Moves in a psuedorandom direction

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

Posted 2015-06-12T02:45:09.947

Reputation: 13 591

1

Thick Shelled

Locks his stuff as much as he can

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

Posted 2015-06-12T02:45:09.947

Reputation: 13 591

0

Triple Thread

This simple bot runs three threads all with the same code. Each thread attacks 1/3 turns, moves 1/6, turns 1/6, and does bookkeeping 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

Posted 2015-06-12T02:45:09.947

Reputation: 5 758

0

Banana Bot

Attempts to throw bananas in the enemies wheel before the enemy can do anything. Prone to being squished.

$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

TheNumberOne

Posted 2015-06-12T02:45:09.947

Reputation: 10 855

0

Copy and Self Flag

This bot runs three threads. The D thread moves until it runs into an enemy, then tries to copy a flag into them, then moves a random direction. The A thread copies its own flag over non-essential lines of the bot's code. The B thread is just a counter. The variable, flag, and lines of code used by each thread are fully locked in the first 15 turns, and the bot overwrites almost all of its startup code with its own flags. I don't think it's possible to convert this bot to another team's banner after turn 15 without a dedicated attack bot doing nothing but writing flags to it.

    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

Posted 2015-06-12T02:45:09.947

Reputation: 5 758

Move 0 is move north, not forward. – MegaTom – 2015-06-17T16:53:36.000

@MegaTom aha, thanks. I missed that. – Sparr – 2015-06-17T17:14:48.100

0

Thread Cutter 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

Stop all enemy threads before filling with your code.

MegaTom

Posted 2015-06-12T02:45:09.947

Reputation: 3 787