コードボット3:並列プログラミングのアンチパターン


13

お帰りなさい!3つ目のCodeBotsチャレンジを紹介できることを嬉しく思います。これは、作成に長い時間がかかりました。この課題は、ショートバージョン、ロングバージョン、および追加の詳細の3つのセクションに分割されます。

ショートバージョン

各競技者は24コマンドプログラムを作成します。これらのボットは世界中を移動し、コードを他のボットにコピーしますが、他のボットが同じことを実行できないようにします。可能なコマンドの1つはno-op Flagです。ボットがFlag他のボットよりも多くのボットを持っている場合、Flagポイントを獲得します。最も多くのポイントを獲得して勝ちます。

上記のすべては、過去2つの課題に当てはまりました。今回は、ボットは複数行のコードを同時に実行できます。

ロングバージョン

API

すべてのボットには24行あります。各行の形式は次のとおりです。

$label command parameters //comments

ラベルとコメントはオプションであり、各コマンドには異なる数のパラメーターがあります。すべて大文字と小文字は区別されません。

パラメーター

パラメーターは入力され、次の形式にすることができます。

  1. 0〜23の値。
  2. 変数:ABCD
  3. 加算を使用した値:A+3または2+C
  4. 符号を使用して指定されたコード行##45行目#C+2を表し、で計算された行を表しますC+2)。
  5. $labelコード行を指定する代わりにを使用できます。
  6. で指定された相手の変数またはコード行*。対戦相手は、あなたが直面している広場のボットです。(*B対戦相手のB価値を*#9表し、敵の10行目を表します)。その正方形に誰もいない場合、コマンドは実行されません。

コマンド

Vを移動

ボットを移動しNorth+(V*90 degrees clockwise)ます。動きは方向を変えません。

Vを回す

ボットをV*90 degrees時計回りに回転させます。

VWをコピー

にあるものをにコピーVWます。Vが行番号の場合、行番号であるW必要があります。Vが変数または値の場合、変数でWなければなりません。

国旗

何もしません。

Vを開始

変数にアタッチされた新しいスレッドを開始しますV。すぐに、そして将来の各ターンで、スレッドはlineでコマンドを実行しますV

Vが既にスレッドに接続されている場合、このコマンドはノーオペレーションです。場合はV、相手の変数であり、その後、相手はその変数に添付スレッドを開始します。

停止V

Vこのターンの終わりに変数に接続されたスレッドを停止します。

ロックV

を呼び出したスレッド以外の方法で、行または変数Vが使用されないようにしますLockLock同じスレッドによるの後続の呼び出しでロックが解除されVます。ロックは、相手の変数またはラインで呼び出すことはできません。

Cond VWの場合

これはテストしCondます。条件が真の場合、スレッドポインターを行番号Vに移動しますW。それ以外の場合は、行番号に移動します。その行はすぐに実行されます。

条件文をすることができX=YX<Y!X、または?X

  1. X=Y 2つのラインが同じタイプで同じボットのものであるかどうかをテストするか、2つの値が同じ量に等しいかどうかをテストします。
  2. X<Yの値Xが未満かどうかをテストしますY
  3. !X変数または行Xがロックされているかどうかをテストします(ロックされている場合はtrueを返します)
  4. ?X 指定された変数にスレッドが接続されているかどうかをテストします

追加の詳細

マルチスレッドの相互作用

同じタイプのアクションが同時に実行されます。アクションは次の順序で実行されます。

  1. ロック。複数のスレッドが変数をロックしようとすると、それらはすべて失敗します。スレッドが変数をロック解除しているときに、別のスレッドがそれをロックしようとすると、変数はロック解除されたままになります。

  2. 開始。複数のスレッドが変数でスレッドを開始しようとすると、単一の開始としてカウントされます。

  3. コピー。2つのスレッドが両方とも同じ変数にコピーする場合、変数はランダムな値になります。両方が同じ行にコピーされる場合、どちらも機能しません。スレッドが別のスレッドがコピーしている同じ変数にコピーする場合、後者のスレッドはランダムな値をコピーします。2つのスレッドが両方とも同じ変数からコピーしている場合、両方とも正常に機能します。

  4. もしそうなら。すべての条件が同時にテストされ、その後スレッド変数が更新されます。を実行するIfと、より高い優先度のアクションが追加される場合があります。優先度の高いアクションはを通過する前に実行されIf、優先度の低いアクションはの後に実行されますIf

  5. 移動します。同じボットでの複数の動きは、すべての動きの合計でボットを動かします。複数のボットが同じ場所に到着する場合、それらは開始地点に戻ります。

  6. 順番。同じボットを複数回ターンすると合計されます。

  7. やめる。同じ変数に対する複数の停止コマンドは、単一の停止としてカウントされます。

その他の詳細

最初のスレッドはD変数に添付され始めます

IfIf自分自身を指すステートメントを持つ)で再帰すると、ボットは何もしません

ロック後にスレッドが停止した場合、それらのロックはロック解除されます

ロックされた変数または行を使用するアクションは何もしません。

ボットが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をコピー」は機能しますか?これは、「Copy#11 A」として解釈されますが、これは有効ではなく、「Copy 11 A」ではなくインタープリターをクラッシュさせます。
スパー

可能性のあるバグ...別のスレッドによってロックされている場合でも、自分のフラグ行を読み取ってそこからコピーできるようです。
スパー

回答:


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

Aスレッドの条件に興味があります。!*#Cは、ターゲットの行#C(C)がロックされているかどうかをチェックしますか?それはどのように役立ちますか?
スパー

@Sparr Aスレッドは、ロックされている場合、敵のコードの行をフラグで置き換える時間を無駄にしません。
TheNumberOne

ありがとう。Ifステートメントの速度に関する仕様を最初は読み間違えました。
スパー

3

DoubleTapBot

このボットには3つのスレッドがあります。1つは移動用(A)、もう2つはフラグ付け用(BおよびD)です。Bフラグ1/2回転、Dフラグ1/3回転。だから、いくつかのターン、彼は対戦相手に二重フラグを立てます:)

Cが23を超えると0に戻ると仮定します。

少なくとも2つのスレッド(AおよびB)を常に正常に実行し続けるため、自分で準備するためのターン(8ターン)がある場合、かなり安全です。

現時点では試せないので、ホームに戻ったらテストを行います:)

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 

ロック番号は有効なコマンドではありません。各番号の前に#記号を付けます。また、コマンドは「回転」ではなく「回転」です
ネイサンメリル

@NathanMerrillどのように、それはタイプミスです、#を忘れて、それを指摘してくれてありがとう。そして、順番に、あなたの投稿を修正して、あなたが書いたように、Vを回しますボットを時計回りにV * 90度回転させます。:)
かてんきょう

ああ、やった。ターンは実際に正しいので、戻ってコードを更新します
ネイサンメリル

10,11,12をロックするつもりなら、11,12,13をロックしていますか?
スパー

うわー、それを指摘してくれてありがとう!
かてんきょう

2

ロックされた固定ダブルタップ

@KatenkyoのDoubleTapBotに触発され、これは2、3のフラグを放棄し、それ自体のスレッドを完全にロックダウンして再プログラムできないようにする代わりに、動きの希望を放棄します。ただし、非ループコード領域に敵のフラグを書き込むことは依然として可能です。

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

ハハ、旗をロックするのはかなり良いアイデアです、私はそれを考えるべきでした!とにかく、ボットが誰かにインスピレーションを与えてくれてうれしいです!
かてんきょう

@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

トリプルスレッド

この単純なボットは、すべて同じコードで3つのスレッドを実行します。各スレッドは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

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

コードを入力する前に、すべての敵スレッドを停止してください。


0

コピーと自己フラグ

このボットは3つのスレッドを実行します。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

Move 0前方ではなく北に移動します。
メガトム

@MegaTomあは、ありがとう。私は逃しました。
スパー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.